diff --git a/.ci/AppImageBuilder.yml b/.ci/AppImageBuilder.yml index 7f312baae..08d7be1ae 100644 --- a/.ci/AppImageBuilder.yml +++ b/.ci/AppImageBuilder.yml @@ -96,3 +96,4 @@ AppDir: AppImage: arch: !ENV '${arch_appimage}' file_name: !ENV '${appimage_path}' + comp: gzip diff --git a/.ci/build.sh b/.ci/build.sh index 0af94132a..e26bbe8bf 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -603,7 +603,7 @@ else 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 qttranslations5-l10n" + pkgs="cmake ninja-build pkg-config git wget p7zip-full extra-cmake-modules wayland-protocols tar gzip file appstream qttranslations5-l10n python3-pip python3-venv squashfs-tools" if [ "$(dpkg --print-architecture)" = "$arch_deb" ] then pkgs="$pkgs build-essential" @@ -1141,55 +1141,32 @@ EOF # Copy line. echo "$line" >> AppImageBuilder-generated.yml - - # Workaround for appimage-builder issues 272 and 283 (i686 and armhf are also missing) - if [ "$arch_appimage" != "x86_64" -a "$line" = " files:" ] - then - # Some mild arbitrary code execution with a dummy package... - [ ! -d /runtime ] && sudo apt-get -y -o 'DPkg::Post-Invoke::=mkdir -p /runtime; chmod 777 /runtime' install libsixel1 > /dev/null 2>&1 - - echo " include:" >> AppImageBuilder-generated.yml - for loader in "/lib/$libdir/ld-linux"*.so.* - do - for loader_copy in "$loader" "/lib/$(basename "$loader")" - do - if [ ! -e "/runtime/compat$loader_copy" ] - then - mkdir -p "/runtime/compat$(dirname "$loader_copy")" - ln -s "$loader" "/runtime/compat$loader_copy" - fi - echo " - /runtime/compat$loader_copy" >> AppImageBuilder-generated.yml - done - done - fi done < .ci/AppImageBuilder.yml # Download appimage-builder if necessary. - appimage_builder_url="https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-$(uname -m).AppImage" - appimage_builder_binary="$cache_dir/$(basename "$appimage_builder_url")" - if [ ! -e "$appimage_builder_binary" ] + appimage_builder_commit=22fefa298f9cee922a651a6f65a46fe0ccbfa34e # from issue 376 + appimage_builder_dir="$cache_dir/appimage-builder-$appimage_builder_commit" + if [ ! -x "$appimage_builder_dir/bin/appimage-builder" ] then - rm -rf "$cache_dir/"*".AppImage" # remove old versions - wget -qO "$appimage_builder_binary" "$appimage_builder_url" + rm -rf "$cache_dir/appimage-builder-"* # remove old versions + python3 -m venv "$appimage_builder_dir" # venv to solve some Debian setuptools headaches + "$appimage_builder_dir/bin/pip" install -U "git+https://github.com/AppImageCrafters/appimage-builder.git@$appimage_builder_commit" fi - # Symlink appimage-builder binary and global cache directory. + # Symlink appimage-builder global cache directory. rm -rf appimage-builder.AppImage appimage-builder-cache "$project-"*".AppImage" # also remove any dangling AppImages which may interfere with the renaming process - ln -s "$appimage_builder_binary" appimage-builder.AppImage - chmod u+x appimage-builder.AppImage mkdir -p "$cache_dir/appimage-builder-cache" ln -s "$cache_dir/appimage-builder-cache" appimage-builder-cache - # Run appimage-builder in extract-and-run mode for Docker compatibility. + # Run appimage-builder from the virtual environment created above. # --appdir is a workaround for appimage-builder issue 270 reported by us. for retry in 1 2 3 4 5 do project="$project" project_id="$project_id" project_version="$project_version" project_icon="$project_icon" arch_deb="$arch_deb" \ - arch_appimage="$arch_appimage" appimage_path="$cwd/$package_name.AppImage" APPIMAGE_EXTRACT_AND_RUN=1 ./appimage-builder.AppImage \ + arch_appimage="$arch_appimage" appimage_path="$cwd/$package_name.AppImage" "$appimage_builder_dir/bin/appimage-builder" \ --recipe AppImageBuilder-generated.yml --appdir "$(grep -oP '^\s+path: \K(.+)' AppImageBuilder-generated.yml)" status=$? [ $status -eq 0 ] && break - [ $status -eq 127 ] && rm -rf /tmp/appimage_extracted_* done # Remove appimage-builder binary on failure, just in case it's corrupted. diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml index 83672974f..012db79b7 100644 --- a/.github/workflows/cmake_linux.yml +++ b/.github/workflows/cmake_linux.yml @@ -8,6 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" + - "!.github/workflows/**" - .github/workflows/cmake_linux.yml - vcpkg.json - "!**/Makefile*" @@ -18,7 +19,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/** + - "!.github/workflows/**" - .github/workflows/cmake_linux.yml - vcpkg.json - "!**/Makefile*" @@ -26,12 +27,10 @@ on: jobs: linux: - name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64" - runs-on: ubuntu-22.04 + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.arch }}" - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + runs-on: ${{ matrix.environment.runner }} strategy: fail-fast: true @@ -66,6 +65,20 @@ jobs: qttranslations5-l10n libevdev-dev libxkbcommon-x11-dev + environment: + - arch: x86_64 + toolchain: ./cmake/flags-gcc-x86_64.cmake + slug: "-x86_64" + runner: ubuntu-22.04 + - arch: arm64 + toolchain: ./cmake/flags-gcc-aarch64.cmake + slug: -arm64 + runner: ubuntu-22.04-arm + exclude: + - dynarec: + new: off + environment: + arch: arm64 steps: - name: Install dependencies @@ -90,28 +103,17 @@ jobs: 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@v3 - - name: Configure CMake run: >- cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ./cmake/flags-gcc-x86_64.cmake + --toolchain ${{ matrix.environment.toolchain }} -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 }}" + cmake --build build - name: Generate package run: | @@ -120,5 +122,5 @@ jobs: - name: Upload artifact uses: actions/upload-artifact@v4 with: - name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}' + name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy${{ matrix.environment.slug }}-gha${{ github.run_number }}' path: build/artifacts/** diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index 2ae417e13..c917932fe 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -8,6 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" + - "!.github/workflows/**" - .github/workflows/cmake_macos.yml - vcpkg.json - "!**/Makefile*" @@ -18,7 +19,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/** + - "!.github/workflows/**" - .github/workflows/cmake_macos.yml - vcpkg.json - "!**/Makefile*" @@ -26,13 +27,11 @@ on: jobs: macos13-x86_64: + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64" runs-on: macos-13 - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - strategy: fail-fast: true matrix: @@ -66,7 +65,6 @@ jobs: - name: Install dependencies run: >- brew install - ninja sdl2 rtmidi openal-soft @@ -81,9 +79,6 @@ jobs: 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@v3 - - name: Configure CMake run: >- cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} @@ -97,20 +92,10 @@ jobs: -D LIBSERIALPORT_ROOT=$(brew --prefix libserialport) - 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 }}" + run: cmake --build build - name: Generate package - run: | - cmake --install build + run: cmake --install build - name: Upload artifact uses: actions/upload-artifact@v4 @@ -119,13 +104,11 @@ jobs: path: build/artifacts/** macos14-arm64: + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, arm64" runs-on: macos-14 -# env: -# BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - strategy: fail-fast: true matrix: @@ -159,12 +142,12 @@ jobs: - name: Install dependencies run: >- brew install - ninja sdl2 rtmidi openal-soft fluidsynth libslirp + vde libserialport ${{ matrix.ui.packages }} @@ -173,9 +156,6 @@ jobs: 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@v3 - - name: Configure CMake run: >- cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} @@ -189,20 +169,10 @@ jobs: -D LIBSERIALPORT_ROOT=$(brew --prefix libserialport) - 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 }}" + run: cmake --build build - name: Generate package - run: | - cmake --install build + run: cmake --install build - name: Upload artifact uses: actions/upload-artifact@v4 diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index ca48599a0..eb83d4674 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -8,6 +8,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" + - "!.github/workflows/**" - .github/workflows/cmake_windows_msys2.yml - vcpkg.json - "!**/Makefile*" @@ -18,6 +19,7 @@ on: - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" + - "!.github/workflows/**" - .github/workflows/cmake_windows_msys2.yml - vcpkg.json - "!**/Makefile*" @@ -25,13 +27,11 @@ on: jobs: msys2: + name: "${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" runs-on: ${{ matrix.environment.runner }} - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - defaults: run: shell: msys2 {0} @@ -40,23 +40,47 @@ jobs: fail-fast: true matrix: build: - - name: Dev Debug +# - name: Regular +# preset: regular + - name: Debug preset: dev_debug - slug: -Dev-Debug + slug: -Debug - name: Dev preset: development slug: -Dev dynarec: - name: ODR new: off + slug: -ODR - name: NDR new: on slug: -NDR + ui: + - name: Qt GUI + qt: on + static: on + slug: -Qt + packages: >- + qt5-base:p + qt5-tools:p + vulkan-headers:p environment: +# - msystem: MSYS +# toolchain: ./cmake/flags-gcc-x86_64.cmake +# slug: "-MSYS64" - msystem: MINGW64 + prefix: mingw-w64-x86_64 toolchain: ./cmake/flags-gcc-x86_64.cmake slug: "-64" runner: windows-2022 +# - msystem: CLANG64 +# prefix: mingw-w64-clang-x86_64 +# toolchain: ./cmake/llvm-win32-x86_64.cmake +# slug: "CLANG64" +# - msystem: UCRT64 +# prefix: mingw-w64-ucrt-x86_64 +# toolchain: ./cmake/flags-gcc-x86_64.cmake +# slug: "UCRT64" - msystem: CLANGARM64 toolchain: ./cmake/flags-gcc-aarch64.cmake slug: -arm64 @@ -97,9 +121,6 @@ jobs: 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@v3 - - name: Configure CMake run: >- cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} @@ -107,20 +128,9 @@ jobs: -D NEW_DYNAREC=${{ matrix.dynarec.new }} -D CMAKE_INSTALL_PREFIX=./build/artifacts - # - 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: Build run: cmake --build build - # - name: Run sonar-scanner - # 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 diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml index fc0397703..b8fb93ef6 100644 --- a/.github/workflows/codeql_linux.yml +++ b/.github/workflows/codeql_linux.yml @@ -3,34 +3,43 @@ name: CodeQL Analysis (Linux) on: push: + branches: [ "master" ] paths: - src/** - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" + - "!.github/workflows/**" - .github/workflows/codeql_linux.yml - vcpkg.json - "!**/Makefile*" pull_request: + branches: [ "master" ] paths: - src/** - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/** + - "!.github/workflows/**" - .github/workflows/codeql_linux.yml - vcpkg.json - "!**/Makefile*" + schedule: + - cron: '22 11 * * 0' + jobs: analyze-linux: - name: "Analyze Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" + name: "Analyze (${{ 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 + permissions: actions: read contents: read @@ -43,12 +52,12 @@ jobs: build: # - name: Regular # preset: regular -# - name: Debug -# preset: debug -# slug: -Debug - - name: Dev + - name: Debug preset: dev_debug - slug: -Dev + slug: -Debug +# - name: Dev +# preset: development +# slug: -Dev dynarec: - name: ODR new: off @@ -59,6 +68,7 @@ jobs: ui: - name: SDL GUI qt: off + static: on - name: Qt GUI qt: on slug: -Qt @@ -90,6 +100,11 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Install Build Wrapper + uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v5 - name: Initialize CodeQL uses: github/codeql-action/init@v3 @@ -106,9 +121,23 @@ jobs: -D QT=${{ matrix.ui.qt }} - name: Build - run: cmake --build build + run: | + build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" + + - name: SonarQube Scan + if: matrix.build.preset == 'dev_debug' && matrix.dynarec.new == 'on' && matrix.ui.qt == 'on' && env.SONAR_TOKEN != '' +# if: 0 + uses: SonarSource/sonarqube-scan-action@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} +# SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }} + with: + # Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options + args: > + --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml index 841ca98f5..203f385ff 100644 --- a/.github/workflows/codeql_macos.yml +++ b/.github/workflows/codeql_macos.yml @@ -3,34 +3,43 @@ name: CodeQL Analysis (macos) on: push: + branches: [ "master" ] paths: - src/** - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" + - "!.github/workflows/**" - .github/workflows/codeql_macos.yml - vcpkg.json - "!**/Makefile*" pull_request: + branches: [ "master" ] paths: - src/** - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/** + - "!.github/workflows/**" - .github/workflows/codeql_macos.yml - vcpkg.json - "!**/Makefile*" + schedule: + - cron: '22 11 * * 0' + jobs: analyze-macos13-x86_64: - name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64" + name: "Analyze (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)" runs-on: macos-13 + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + permissions: actions: read contents: read @@ -43,12 +52,12 @@ jobs: build: # - name: Regular # preset: regular -# - name: Debug -# preset: debug -# slug: -Debug - - name: Dev + - name: Debug preset: dev_debug - slug: -Dev + slug: -Debug +# - name: Dev +# preset: development +# slug: -Dev dynarec: - name: ODR new: off @@ -69,7 +78,6 @@ jobs: - name: Install dependencies run: >- brew install - ninja sdl2 rtmidi openal-soft @@ -81,6 +89,11 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Install Build Wrapper + uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v5 - name: Initialize CodeQL uses: github/codeql-action/init@v3 @@ -101,9 +114,23 @@ jobs: -D LIBSERIALPORT_ROOT=$(brew --prefix libserialport) - name: Build - run: cmake --build build + run: | + build-wrapper-macosx-x86 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" + + - name: SonarQube Scan +# if: matrix.build.preset == 'dev_debug' && matrix.dynarec.new == 'on' && matrix.ui.qt == 'on' && env.SONAR_TOKEN != '' + if: 0 + uses: SonarSource/sonarqube-scan-action@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} +# SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }} + with: + # Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options + args: > + --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index 7a0055910..c7edae77f 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -3,33 +3,42 @@ name: CodeQL Analysis (Windows, msys2) on: push: + branches: [ "master" ] paths: - src/** - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" + - "!.github/workflows/**" - .github/workflows/codeql_windows_msys2.yml - vcpkg.json - "!**/Makefile*" pull_request: + branches: [ "master" ] paths: - src/** - cmake/** - "**/CMakeLists.txt" - "CMakePresets.json" - - .github/workflows/** + - "!.github/workflows/**" - .github/workflows/codeql_windows_msys2.yml - vcpkg.json - "!**/Makefile*" + schedule: + - cron: '22 11 * * 0' + jobs: analyze-msys2: - name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" + name: "Analyze (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})" - runs-on: windows-2022 + runs-on: ${{ matrix.environment.runner }} + + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed permissions: actions: read @@ -47,12 +56,12 @@ jobs: build: # - name: Regular # preset: regular -# - name: Debug -# preset: debug -# slug: -Debug - - name: Dev + - name: Debug preset: dev_debug - slug: -Dev + slug: -Debug +# - name: Dev +# preset: development +# slug: -Dev dynarec: - name: ODR new: off @@ -72,21 +81,37 @@ jobs: environment: # - msystem: MSYS # toolchain: ./cmake/flags-gcc-x86_64.cmake +# slug: "-MSYS64" - msystem: MINGW64 prefix: mingw-w64-x86_64 toolchain: ./cmake/flags-gcc-x86_64.cmake + slug: "-64" + runner: windows-2022 # - 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 +# slug: "CLANG64" +# runner: windows-2022 +# - msystem: UCRT64 +# prefix: mingw-w64-ucrt-x86_64 +# toolchain: ./cmake/flags-gcc-x86_64.cmake +# slug: "UCRT64" +# runner: windows-2022 +# - msystem: CLANGARM64 +# toolchain: ./cmake/flags-gcc-aarch64.cmake +# slug: -arm64 +# runner: windows-11-arm + exclude: + - dynarec: + new: off + environment: + msystem: CLANGARM64 steps: - name: Prepare MSYS2 environment uses: msys2/setup-msys2@v2 with: - release: false + release: true update: true msystem: ${{ matrix.environment.msystem }} pacboy: >- @@ -104,9 +129,15 @@ jobs: fluidsynth:p libserialport:p ${{ matrix.ui.packages }} + openmp:p - name: Checkout repository uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + +# - name: Install Build Wrapper +# uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v5 - name: Initialize CodeQL uses: github/codeql-action/init@v3 @@ -123,11 +154,27 @@ jobs: -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: Build run: cmake --build build - - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" + + - name: SonarQube Scan +# if: matrix.build.preset == 'dev_debug' && matrix.dynarec.new == 'on' && matrix.ui.qt == 'on' && env.SONAR_TOKEN != '' + if: 0 + uses: SonarSource/sonarqube-scan-action@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} +# SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }} + with: + # Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options + args: > + --define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json" diff --git a/CMakeLists.txt b/CMakeLists.txt index 007c1ffd8..989649b58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,6 +137,7 @@ option(GDBSTUB "Enable GDB stub server for debugging" option(DEV_BRANCH "Development branch" OFF) option(DISCORD "Discord Rich Presence support" ON) option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF) +option(LIBASAN "Enable compilation with the addresss sanitizer" OFF) if((ARCH STREQUAL "arm64") OR (ARCH STREQUAL "arm")) set(NEW_DYNAREC ON) @@ -173,21 +174,17 @@ endif() # Option Description Def. Condition Otherwise # ------ ----------- ---- ------------ --------- cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF) -cmake_dependent_option(AN430TX "Intel AN430TX" ON "DEV_BRANCH" OFF) cmake_dependent_option(CDROM_MITSUMI "Mitsumi CDROM" ON "DEV_BRANCH" OFF) cmake_dependent_option(G100 "Matrox Productiva G100" ON "DEV_BRANCH" OFF) -cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF) 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(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) -cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) cmake_dependent_option(PCL "Generic PCL5e Printer" ON "DEV_BRANCH" OFF) cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) cmake_dependent_option(WACOM "Wacom Input Devices" ON "DEV_BRANCH" OFF) cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) +cmake_dependent_option(NETSWITCH "Network Switch Support" ON "DEV_BRANCH" OFF) # Ditto but for Qt if(QT) @@ -225,7 +222,15 @@ if(NOT EMU_BUILD_NUM) set(EMU_BUILD_NUM 0) endif() if(NOT EMU_COPYRIGHT_YEAR) - set(EMU_COPYRIGHT_YEAR 2024) + set(EMU_COPYRIGHT_YEAR 2025) endif() +# Libasan +if(LIBASAN) + add_compile_options(-fsanitize=address) + add_link_options(-fsanitize=address) +endif() + +set(CMAKE_TOP_LEVEL_PROCESSED TRUE) + add_subdirectory(src) diff --git a/README.md b/README.md index ee0e1e7f1..506eba794 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,9 @@ Minimum system requirements and recommendations * macOS version: macOS High Sierra 10.13 or newer * 4 GB of RAM or higher -Performance may vary depending on both host and guest configuration. Most emulation logic is executed in a single thread; therefore, systems with better IPC (instructions per clock) generally should be able to emulate higher clock speeds. +Performance may vary depending on host and guest configuration. Most emulation logic is executed in a single thread. Therefore, systems with greater IPC (instructions per clock) capacity should be able to emulate higher clock speeds. -It is also recommended to use a manager application with 86Box for easier handling of multiple virtual machines. +For easier handling of multiple virtual machines, use a manager application: * [Avalonia 86](https://github.com/notBald/Avalonia86) by [notBald](https://github.com/notBald) (Windows and Linux) * [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only) @@ -37,7 +37,7 @@ It is also recommended to use a manager application with 86Box for easier handli * [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by [Dungeonseeker](https://github.com/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) -It is also possible to use 86Box on its own with the `--vmpath`/`-P` command line option. +To use 86Box on its own, use the `--vmpath`/`-P` command line option. Getting started --------------- @@ -47,7 +47,7 @@ See [our documentation](https://86box.readthedocs.io/en/latest/index.html) for a Community --------- -We operate an IRC channel and a Discord server for discussing 86Box, its development and anything related to retro computing. We look forward to hearing from you! +We operate an IRC channel and a Discord server for discussing 86Box, its development, and anything related to retro computing. We look forward to hearing from you! [![Visit our IRC channel](https://kiwiirc.com/buttons/irc.ringoflightning.net/86Box.png)](https://kiwiirc.com/client/irc.ringoflightning.net/?nick=86box|?#86Box) diff --git a/src/86box.c b/src/86box.c index 4131e7ecc..2f8c77c9f 100644 --- a/src/86box.c +++ b/src/86box.c @@ -70,6 +70,7 @@ #include <86box/unittester.h> #include <86box/novell_cardkey.h> #include <86box/isamem.h> +#include <86box/isarom.h> #include <86box/isartc.h> #include <86box/lpt.h> #include <86box/serial.h> @@ -87,7 +88,7 @@ #include <86box/scsi_device.h> #include <86box/cdrom.h> #include <86box/cdrom_interface.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/mo.h> #include <86box/scsi_disk.h> #include <86box/cdrom_image.h> @@ -168,7 +169,6 @@ int vid_api = 0; /* (C) video r int vid_cga_contrast = 0; /* (C) video */ int video_fullscreen = 0; /* (C) video */ int video_fullscreen_scale = 0; /* (C) video */ -int video_fullscreen_first = 0; /* (G) video */ int enable_overscan = 0; /* (C) video */ int force_43 = 0; /* (C) video */ int video_filter_method = 1; /* (C) video */ @@ -182,12 +182,12 @@ int postcard_enabled = 0; /* (C) enable int unittester_enabled = 0; /* (C) enable unit tester device */ int gameport_type[GAMEPORT_MAX] = { 0, 0 }; /* (C) enable gameports */ int isamem_type[ISAMEM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA mem cards */ +int isarom_type[ISAROM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA ROM cards */ int isartc_type = 0; /* (C) enable ISA RTC card */ int gfxcard[GFXCARD_MAX] = { 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 lba_enhancer_enabled = 0; /* (C) enable Vision Systems LBA Enhancer */ int ibm8514_standalone_enabled = 0; /* (C) video option */ int xga_standalone_enabled = 0; /* (C) video option */ int da2_standalone_enabled = 0; /* (C) video option */ @@ -216,12 +216,15 @@ int test_mode = 0; /* (C) Test mo char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */ int sound_muted = 0; /* (C) Is sound muted? */ int inhibit_multimedia_keys; /* (G) Inhibit multimedia keys on Windows. */ +int force_10ms; /* (C) Force 10ms CPU frame intervals. */ int other_ide_present = 0; /* IDE controllers from non-IDE cards are present */ int other_scsi_present = 0; /* SCSI controllers from non-SCSI cards are present */ +int is_pcjr = 0; /* The current machine is PCjr. */ + // Accelerator key array struct accelKey acc_keys[NUM_ACCELS]; @@ -252,6 +255,8 @@ struct accelKey def_acc_keys[NUM_ACCELS] = { .seq="Ctrl+Alt+M" } }; +char vmm_path[1024] = { '\0'}; /* TEMPORARY - VM manager path to scan for VMs */ +int vmm_enabled = 0; /* Statistics. */ extern int mmuflush; @@ -600,8 +605,8 @@ pc_show_usage(char *s) #ifdef _WIN32 "-D or --debug\t\t\t- force debug output logging\n" #endif -#if 0 - "-E or --nographic\t\t- forces the old behavior\n" +#if 1 + "-E or --vmmpath\t\t- vm manager path\n" #endif "-F or --fullscreen\t\t- start in fullscreen mode\n" "-G or --lang langid\t\t- start with specified language\n" @@ -638,7 +643,7 @@ pc_show_usage(char *s) ui_msgbox(MBX_ANSI | ((s == NULL) ? MBX_INFO : MBX_WARNING), p); #else if (s == NULL) - pclog(p); + pclog("%s", p); else ui_msgbox(MBX_ANSI | MBX_WARNING, p); #endif @@ -736,13 +741,18 @@ usage: } else if (!strcasecmp(argv[c], "--debug") || !strcasecmp(argv[c], "-D")) { force_debug = 1; #endif -#ifdef ENABLE_NG - } else if (!strcasecmp(argv[c], "--nographic") || !strcasecmp(argv[c], "-E")) { - /* Currently does nothing, but if/when we implement a built-in manager, - it's going to force the manager not to run, allowing the old usage - without parameter. */ - ng = 1; -#endif +//#ifdef ENABLE_NG + } else if (!strcasecmp(argv[c], "--vmmpath") || + !strcasecmp(argv[c], "-E")) { + /* Using this variable for vm manager path + Temporary solution!*/ + if ((c+1) == argc) goto usage; + char *vp = argv[++c]; + if ((strlen(vp) + 1) >= sizeof(vmm_path)) + memcpy(vmm_path, vp, sizeof(vmm_path)); + else + memcpy(vmm_path, vp, strlen(vp) + 1); + //#endif } else if (!strcasecmp(argv[c], "--fullscreen") || !strcasecmp(argv[c], "-F")) { start_in_fullscreen = 1; } else if (!strcasecmp(argv[c], "--logfile") || !strcasecmp(argv[c], "-L")) { @@ -782,7 +792,11 @@ usage: goto usage; temp2 = (char *) calloc(2048, 1); - sscanf(argv[++c], "%c:%s", &drive, temp2); + if (sscanf(argv[++c], "%c:%2047s", &drive, temp2) != 2) { + fprintf(stderr, "Invalid input format for --image option.\n"); + free(temp2); + goto usage; + } if (drive > 0x40) drive = (drive & 0x1f) - 1; else @@ -1029,9 +1043,21 @@ usage: * This is where we start outputting to the log file, * if there is one. Create a little info header first. */ + struct tm time_buf; + (void) time(&now); - info = localtime(&now); - strftime(temp, sizeof(temp), "%Y/%m/%d %H:%M:%S", info); +#ifdef _WIN32 + if (localtime_s(&time_buf, &now) == 0) + info = &time_buf; +#else + info = localtime_r(&now, &time_buf); +#endif + + if (info) + strftime(temp, sizeof(temp), "%Y/%m/%d %H:%M:%S", info); + else + strcpy(temp, "unknown"); + pclog("#\n# %ls v%ls logfile, created %s\n#\n", EMU_NAME_W, EMU_VERSION_FULL_W, temp); pclog("# VM: %s\n#\n", vm_name); @@ -1042,48 +1068,55 @@ usage: } pclog("# Global configuration file: %s\n", global_cfg_path); - pclog("# VM configuration file: %s\n#\n\n", cfg_path); - /* - * We are about to read the configuration file, which MAY - * put data into global variables (the hard- and floppy - * disks are an example) so we have to initialize those - * modules before we load the config.. - */ - hdd_init(); - network_init(); - mouse_init(); - cdrom_global_init(); - zip_global_init(); - mo_global_init(); - - /* Initialize the keyboard accelerator list with default values */ - for (int x = 0; x < NUM_ACCELS; x++) { - strcpy(acc_keys[x].name, def_acc_keys[x].name); - strcpy(acc_keys[x].desc, def_acc_keys[x].desc); - strcpy(acc_keys[x].seq, def_acc_keys[x].seq); + pclog("# Configuration file: %s\n#\n\n", cfg_path); + if (strlen(vmm_path) != 0) { + vmm_enabled = 1; + pclog("# VM Manager enabled. Path: %s\n", vmm_path); } - /* Load the configuration file. */ - config_load(); + if (!vmm_enabled) { + /* + * We are about to read the configuration file, which MAY + * put data into global variables (the hard- and floppy + * disks are an example) so we have to initialize those + * modules before we load the config.. + */ + hdd_init(); + network_init(); + mouse_init(); + cdrom_global_init(); + rdisk_global_init(); + mo_global_init(); - /* 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; - } + /* Initialize the keyboard accelerator list with default values */ + for (int x = 0; x < NUM_ACCELS; x++) { + strcpy(acc_keys[x].name, def_acc_keys[x].name); + strcpy(acc_keys[x].desc, def_acc_keys[x].desc); + strcpy(acc_keys[x].seq, def_acc_keys[x].seq); + } - if (clear_flash) { - delete_nvr_file(1); - clear_flash = 0; - } + /* Load the configuration file. */ + config_load(); - for (uint8_t i = 0; i < FDD_NUM; i++) { - if (fn[i] != NULL) { - if (strlen(fn[i]) <= 511) - strncpy(floppyfns[i], fn[i], 511); - free(fn[i]); - fn[i] = NULL; + /* Clear the CMOS and/or BIOS flash file, if we were started with + the relevant parameter(s). */ + if (clear_cmos) { + delete_nvr_file(0); + clear_cmos = 0; + } + + if (clear_flash) { + delete_nvr_file(1); + clear_flash = 0; + } + + for (uint8_t i = 0; i < FDD_NUM; i++) { + if (fn[i] != NULL) { + if (strlen(fn[i]) <= 511) + strncpy(floppyfns[i], fn[i], 511); + free(fn[i]); + fn[i] = NULL; + } } } @@ -1249,6 +1282,11 @@ pc_init_modules(void) machine_status_init(); + serial_set_next_inst(0); + + lpt_set_3bc_used(0); + lpt_set_next_inst(0); + for (c = 0; c <= 0x7ff; c++) { int64_t exp = c - 1023; /* 1023 = BIAS64 */ exp_pow_table[c] = pow(2.0, (double) exp); @@ -1268,20 +1306,48 @@ pc_send_ca(uint16_t sc) if (keyboard_mode >= 0x81) { /* Use R-Alt because PS/55 DOS and OS/2 assign L-Alt Kanji */ keyboard_input(1, 0x1D); /* Ctrl key pressed */ + if (keyboard_get_in_reset()) + return; keyboard_input(1, 0x138); /* R-Alt key pressed */ + if (keyboard_get_in_reset()) + return; keyboard_input(1, sc); + if (keyboard_get_in_reset()) + return; usleep(50000); + if (keyboard_get_in_reset()) + return; keyboard_input(0, sc); + if (keyboard_get_in_reset()) + return; keyboard_input(0, 0x138); /* R-Alt key released */ + if (keyboard_get_in_reset()) + return; keyboard_input(0, 0x1D); /* Ctrl key released */ + if (keyboard_get_in_reset()) + return; } else { keyboard_input(1, 0x1D); /* Ctrl key pressed */ + if (keyboard_get_in_reset()) + return; keyboard_input(1, 0x38); /* Alt key pressed */ + if (keyboard_get_in_reset()) + return; keyboard_input(1, sc); + if (keyboard_get_in_reset()) + return; usleep(50000); + if (keyboard_get_in_reset()) + return; keyboard_input(0, sc); + if (keyboard_get_in_reset()) + return; keyboard_input(0, 0x38); /* Alt key released */ + if (keyboard_get_in_reset()) + return; keyboard_input(0, 0x1D); /* Ctrl key released */ + if (keyboard_get_in_reset()) + return; } } @@ -1335,10 +1401,6 @@ pc_reset_hard_close(void) lpt_devices_close(); -#ifdef UNCOMMENT_LATER - lpt_close(); -#endif - nvr_save(); nvr_close(); @@ -1354,7 +1416,7 @@ pc_reset_hard_close(void) cdrom_close(); - zip_close(); + rdisk_close(); mo_close(); @@ -1367,6 +1429,9 @@ pc_reset_hard_close(void) cpu_close(); serial_set_next_inst(0); + + lpt_set_3bc_used(0); + lpt_set_next_inst(0); } /* @@ -1405,6 +1470,8 @@ pc_reset_hard_init(void) scsi_reset(); scsi_device_init(); + ide_hard_reset(); + /* Initialize the actual machine and its basic modules. */ machine_init(); @@ -1426,6 +1493,7 @@ pc_reset_hard_init(void) /* Initialize parallel devices. */ /* note: PLIP LPT side has to be initialized before the network side */ + lpt_standalone_init(); lpt_devices_init(); /* Reset and reconfigure the serial ports. */ @@ -1448,9 +1516,6 @@ pc_reset_hard_init(void) fdd_reset(); - /* Reset the CD-ROM Controller module. */ - cdrom_interface_reset(); - /* Reset and reconfigure the SCSI layer. */ scsi_card_init(); @@ -1458,9 +1523,16 @@ pc_reset_hard_init(void) cdrom_hard_reset(); + /* Reset the CD-ROM Controller module. */ + cdrom_interface_reset(); + mo_hard_reset(); - zip_hard_reset(); + rdisk_hard_reset(); + + + /* Reset any ISA ROM cards. */ + isarom_reset(); /* Reset any ISA RTC cards. */ isartc_reset(); @@ -1489,9 +1561,6 @@ pc_reset_hard_init(void) if (unittester_enabled) device_add(&unittester_device); - if (lba_enhancer_enabled) - device_add(&lba_enhancer_device); - if (novell_keycard_enabled) device_add(&novell_keycard_device); @@ -1549,19 +1618,19 @@ update_mouse_msg(void) *(wcp - 1) = L'\0'; mbstowcs(wcpu, cpu_s->name, strlen(cpu_s->name) + 1); #ifdef _WIN32 - swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i%%%% - %ls", + swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i.%%i%%%% - %ls", plat_get_string(STRING_MOUSE_CAPTURE)); - swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i%%%% - %ls", + swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i.%%i%%%% - %ls", (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); - wcsncpy(mouse_msg[2], L"%i%%", sizeof_w(mouse_msg[2])); + wcsncpy(mouse_msg[2], L"%i.%i%%", sizeof_w(mouse_msg[2])); #else - swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", + swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, plat_get_string(STRING_MOUSE_CAPTURE)); - swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", + swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); - swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls", + swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu); #endif } @@ -1622,13 +1691,17 @@ pc_close(UNUSED(thread_t *ptr)) cdrom_close(); - zip_close(); + rdisk_close(); mo_close(); scsi_disk_close(); gdbstub_close(); + +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) + mem_free(); +#endif } #ifdef __APPLE__ @@ -1667,7 +1740,7 @@ pc_run(void) /* Run a block of code. */ startblit(); - cpu_exec((int32_t) cpu_s->rspeed / 100); + cpu_exec((int32_t) cpu_s->rspeed / (force_10ms ? 100 : 1000)); ack_pause(); #ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ if (gdbstub_step == GDBSTUB_EXEC) { @@ -1682,14 +1755,14 @@ pc_run(void) /* Done with this frame, update statistics. */ framecount++; - if (++framecountx >= 100) { + if (++framecountx >= (force_10ms ? 100 : 1000)) { framecountx = 0; frames = 0; } if (title_update) { 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); + swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps / (force_10ms ? 1 : 10), force_10ms ? 0 : (fps % 10)); #ifdef __APPLE__ /* Needed due to modifying the UI on the non-main thread is a big no-no. */ dispatch_async_f(dispatch_get_main_queue(), wcsdup((const wchar_t *) temp), _ui_window_title); @@ -1891,4 +1964,4 @@ int FindAccelerator(const char *name) { } // No key was found return -1; -} \ No newline at end of file +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8cf67043f..724e1fda6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,10 @@ # Copyright 2024 Jasmine Iwanek. # +if(NOT CMAKE_TOP_LEVEL_PROCESSED) + message(FATAL_ERROR "Incorrect source directory specified. Delete your build directory and retry with the top-level directory instead") +endif() + if(APPLE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) endif() @@ -99,7 +103,7 @@ if(INSTRUMENT) add_compile_definitions(USE_INSTRUMENT) endif() -target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom zip mo hdd +target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom rdisk mo hdd net print scsi sio snd utils vid voodoo plat ui) if(HAIKU) @@ -149,16 +153,6 @@ if(APPLE) target_link_libraries(86Box Freetype::Freetype) endif() -find_package(SDL2 REQUIRED) -include_directories(${SDL2_INCLUDE_DIRS}) -if(STATIC_BUILD AND TARGET SDL2::SDL2-static) - target_link_libraries(86Box SDL2::SDL2-static) -elseif(TARGET SDL2::SDL2) - target_link_libraries(86Box SDL2::SDL2) -else() - target_link_libraries(86Box ${SDL2_LIBRARIES}) -endif() - find_package(PNG REQUIRED) include_directories(${PNG_INCLUDE_DIRS}) target_link_libraries(86Box PNG::PNG) diff --git a/src/acpi.c b/src/acpi.c index ccd51ebca..e7a0de53d 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -36,6 +36,7 @@ #include <86box/pit.h> #include <86box/apm.h> #include <86box/acpi.h> +#include <86box/dma.h> #include <86box/machine.h> #include <86box/i2c.h> #include <86box/video.h> @@ -1025,8 +1026,13 @@ acpi_reg_write_common_regs(UNUSED(int size), uint16_t addr, uint8_t val, void *p nvr_reg_write(0x000f, 0xff, dev->nvr); } - if (sus_typ & SUS_RESET_PCI) + if (sus_typ & SUS_RESET_PCI) { + /* DMA is part of the southbridge so it responds to PCI reset. */ + dma_reset(); + dma_set_at(1); + device_reset_all(DEVICE_PCI); + } if (sus_typ & SUS_RESET_CPU) cpu_alt_reset = 0; @@ -2387,6 +2393,14 @@ acpi_reset(void *priv) dev->regs.gpi_val = 0xfff57fc1; if (!strcmp(machine_get_internal_name(), "ficva503a") || !strcmp(machine_get_internal_name(), "6via90ap")) dev->regs.gpi_val |= 0x00000004; + /* + TriGem Delhi-III second GPI word: + - Bit 7 = Save CMOS (must be set); + - Bit 6 = Password jumper (must be set); + - Bit 5 = Enable Setup (must be set). + */ + else if (!strcmp(machine_get_internal_name(), "delhi3")) + dev->regs.gpi_val |= 0x00008000; } if (acpi_power_on) { diff --git a/src/cdrom/CMakeLists.txt b/src/cdrom/CMakeLists.txt index 621b069b0..7e18a72a0 100644 --- a/src/cdrom/CMakeLists.txt +++ b/src/cdrom/CMakeLists.txt @@ -23,6 +23,7 @@ add_library(cdrom OBJECT cdrom.c cdrom_image.c cdrom_image_viso.c + cdrom_mke.c ) target_link_libraries(86Box PkgConfig::SNDFILE) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 44bf2811c..ffccbdcb4 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -32,6 +32,7 @@ #ifdef USE_CDROM_MITSUMI #include <86box/cdrom_mitsumi.h> #endif +#include <86box/cdrom_mke.h> #include <86box/log.h> #include <86box/plat.h> #include <86box/plat_cdrom_ioctl.h> @@ -121,8 +122,10 @@ static const struct { // clang-format off { &cdrom_interface_none_device }, #ifdef USE_CDROM_MITSUMI - { &mitsumi_cdrom_device }, + { &mitsumi_cdrom_device }, #endif + { &mke_cdrom_noncreative_device }, + { &mke_cdrom_device }, { NULL } // clang-format on }; @@ -292,10 +295,80 @@ msf_to_bcd(int *m, int *s, int *f) *f = bin2bcd(*f); } -static int -read_data(cdrom_t *dev, const uint32_t lba) +void +cdrom_compute_ecc_block(cdrom_t *dev, uint8_t *parity, const uint8_t *data, + uint32_t major_count, uint32_t minor_count, + uint32_t major_mult, uint32_t minor_inc, int m2f1) { - int ret = 1; + uint32_t size = major_count * minor_count; + + for (uint32_t major = 0; major < major_count; ++major) { + uint32_t index = (major >> 1) * major_mult + (major & 1); + + uint8_t ecc_a = 0; + uint8_t ecc_b = 0; + + for (uint32_t minor = 0; minor < minor_count; ++minor) { + uint8_t temp = data[index]; + + if (m2f1 && (index < 4)) + temp = 0x00; + + index += minor_inc; + + if (index >= size) + index -= size; + + ecc_a ^= temp; + ecc_b ^= temp; + ecc_a = dev->_F_LUT[ecc_a]; + } + + parity[major] = dev->_B_LUT[dev->_F_LUT[ecc_a] ^ ecc_b]; + parity[major + major_count] = parity[major] ^ ecc_b; + } +} + +static void +cdrom_generate_ecc_data(cdrom_t *dev, const uint8_t *data, int m2f1) +{ + /* Compute ECC P code. */ + cdrom_compute_ecc_block(dev, dev->p_parity, data, 86, 24, 2, 86, m2f1); + + /* Compute ECC Q code. */ + cdrom_compute_ecc_block(dev, dev->q_parity, data, 52, 43, 86, 88, m2f1); +} + +static int +cdrom_is_sector_good(cdrom_t *dev, const uint8_t *b, const uint8_t mode2, const uint8_t form) +{ + int ret = 1; + + if (!mode2 || (form != 1)) { + if (mode2 && (form == 1)) { + const uint32_t crc = cdrom_crc32(0xffffffff, &(b[16]), 2056) ^ 0xffffffff; + + ret = ret && (crc == (*(uint32_t *) &(b[2072]))); + } else if (!mode2) { + const uint32_t crc = cdrom_crc32(0xffffffff, b, 2064) ^ 0xffffffff; + + ret = ret && (crc == (*(uint32_t *) &(b[2064]))); + } + + cdrom_generate_ecc_data(dev, &(b[12]), mode2 && (form == 1)); + + ret = ret && !memcmp(dev->p_parity, &(b[2076]), 172); + ret = ret && !memcmp(dev->q_parity, &(b[2248]), 104); + } + + return ret; +} + +static int +read_data(cdrom_t *dev, const uint32_t lba, int check) +{ + int ret = 1; + int form = 0; if (dev->cached_sector != lba) { dev->cached_sector = lba; @@ -303,6 +376,25 @@ read_data(cdrom_t *dev, const uint32_t lba) ret = dev->ops->read_sector(dev->local, dev->raw_buffer[dev->cur_buf ^ 1], lba); + if ((ret > 0) && check) { + if (dev->mode2) { + if (dev->raw_buffer[dev->cur_buf ^ 1][0x000f] == 0x01) + /* + Use Mode 1, since evidently specification-violating + discs exist. + */ + dev->mode2 = 0; + else if (dev->raw_buffer[dev->cur_buf ^ 1][0x0012] == + dev->raw_buffer[dev->cur_buf ^ 1][0x0016]) + form = ((dev->raw_buffer[dev->cur_buf ^ 1][0x0012] & + 0x20) >> 5) + 1; + } else if (dev->raw_buffer[dev->cur_buf ^ 1][0x000f] == 0x02) + dev->mode2 = 1; + + if (!cdrom_is_sector_good(dev, dev->raw_buffer[dev->cur_buf ^ 1], dev->mode2, form)) + ret = -1; + } + if (ret <= 0) { memset(dev->raw_buffer[dev->cur_buf ^ 1], 0x00, 2448); dev->cached_sector = -1; @@ -322,7 +414,7 @@ cdrom_get_subchannel(cdrom_t *dev, const uint32_t lba, if (lba != dev->cached_sector) dev->cached_sector = -1; - (void) read_data(dev, lba); + (void) read_data(dev, lba, 0); for (int i = 0; i < 12; i++) for (int j = 0; j < 8; j++) @@ -679,7 +771,7 @@ track_type_is_valid(UNUSED(const cdrom_t *dev), const int type, const int flags, static int read_audio(cdrom_t *dev, const uint32_t lba, uint8_t *b) { - const int ret = read_data(dev, lba); + const int ret = read_data(dev, lba, 0); memcpy(b, dev->raw_buffer[dev->cur_buf], 2352); @@ -979,28 +1071,28 @@ cdrom_toc_dump(cdrom_t *dev) uint8_t b[65536] = { 0 }; int len = cdrom_read_toc(dev, b, CD_TOC_RAW, 0, 0, 65536); const char *fn2 = "d:\\86boxnew\\toc_cue.dmp"; - FILE * f = fopen(fn2, "wb"); - fwrite(b, 1, len, f); - fflush(f); - fclose(f); + FILE * fp = fopen(fn2, "wb"); + fwrite(b, 1, len, fp); + fflush(fp); + fclose(fp); cdrom_log(dev->log, "Written TOC of %i bytes to %s\n", len, fn2); memset(b, 0x00, 65536); len = cdrom_read_toc(dev, b, CD_TOC_NORMAL, 0, 0, 65536); fn2 = "d:\\86boxnew\\toc_cue_cooked.dmp"; - f = fopen(fn2, "wb"); - fwrite(b, 1, len, f); - fflush(f); - fclose(f); + fp = fopen(fn2, "wb"); + fwrite(b, 1, len, fp); + fflush(fp); + fclose(fp); cdrom_log(dev->log, "Written cooked TOC of %i bytes to %s\n", len, fn2); memset(b, 0x00, 65536); len = cdrom_read_toc(dev, b, CD_TOC_SESSION, 0, 0, 65536); fn2 = "d:\\86boxnew\\toc_cue_session.dmp"; - f = fopen(fn2, "wb"); - fwrite(b, 1, len, f); - fflush(f); - fclose(f); + fp = fopen(fn2, "wb"); + fwrite(b, 1, len, fp); + fflush(fp); + fclose(fp); cdrom_log(dev->log, "Written session TOC of %i bytes to %s\n", len, fn2); } #endif @@ -1100,6 +1192,12 @@ cdrom_is_early(const int type) return (cdrom_drive_types[type].scsi_std == 1); } +int +cdrom_is_dvd(const int type) +{ + return (cdrom_drive_types[type].is_dvd == 1); +} + int cdrom_is_generic(const int type) { @@ -1151,6 +1249,26 @@ cdrom_get_type_count(void) return count; } +void +cdrom_generate_name_mke(const int type, char *name) +{ + char elements[2][512] = { 0 }; + + memcpy(elements[0], cdrom_drive_types[type].model, + strlen(cdrom_drive_types[type].model) + 1); + char *s = strstr(elements[0], " "); + if (s != NULL) + s[0] = 0x00; + + memcpy(elements[1], cdrom_drive_types[type].revision, + strlen(cdrom_drive_types[type].revision) + 1); + s = strstr(elements[1], " "); + if (s != NULL) + s[0] = 0x00; + + sprintf(name, "%s%s", elements[0], elements[1]); +} + void cdrom_get_identify_model(const int type, char *name, const int id) { @@ -1589,7 +1707,7 @@ cdrom_audio_track_search(cdrom_t *dev, const uint32_t pos, dev->seek_pos = MSFtoLBA(ti.m, ti.s, ti.f) - 150; else { cdrom_log(dev->log, "Unable to get the starting position for " - "track %08X\n", ismsf & 0xff); + "track %08X\n", pos2 & 0xff); cdrom_stop(dev); } break; @@ -1707,7 +1825,7 @@ cdrom_audio_play_toshiba(cdrom_t *dev, const uint32_t pos, const int type) dev->cd_end = MSFtoLBA(ti.m, ti.s, ti.f) - 150; else { cdrom_log(dev->log, "Unable to get the starting position for " - "track %08X\n", ismsf & 0xff); + "track %08X\n", pos2 & 0xff); cdrom_stop(dev); } break; @@ -1740,7 +1858,7 @@ cdrom_audio_scan(cdrom_t *dev, const uint32_t pos) uint8_t ret = 0; if (dev->cd_status & CD_STATUS_HAS_AUDIO) { - cdrom_log(dev->log, "Audio Scan: MSF = %06x, type = %02x\n", pos, type); + cdrom_log(dev->log, "Audio Scan: MSF = %06x\n", pos); if (pos == 0xffffffff) { cdrom_log(dev->log, "(Type 0) Search from current position\n"); @@ -2009,9 +2127,10 @@ cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b) cdrom_get_current_subcodeq(dev, b); switch (dev->cd_status) { - default: case CD_STATUS_EMPTY: - case CD_STATUS_DATA_ONLY: case CD_STATUS_DVD: - case CD_STATUS_STOPPED: case CD_STATUS_PLAYING_COMPLETED: + default: case CD_STATUS_EMPTY: + case CD_STATUS_DATA_ONLY: case CD_STATUS_DVD: + case CD_STATUS_STOPPED: case CD_STATUS_PLAYING_COMPLETED: + case CD_STATUS_DVD_REJECTED: ret = 0x03; break; case CD_STATUS_HOLD: @@ -2360,7 +2479,7 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, const int sector, const int ecc_diff = 0; } - if (dev->cd_status != CD_STATUS_EMPTY) { + if ((dev->cd_status != CD_STATUS_EMPTY) && (dev->cd_status != CD_STATUS_DVD_REJECTED)) { uint8_t *temp_b; uint8_t *b = temp_b = buffer; int audio = 0; @@ -2379,6 +2498,8 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, const int sector, const int if (dm != CD_TRACK_NORMAL) mode2 = 1; + dev->mode2 = mode2; + memset(dev->extra_buffer, 0, 296); if ((cdrom_sector_flags & 0xf8) == 0x08) { @@ -2405,7 +2526,7 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, const int sector, const int else ret = read_audio(dev, lba, temp_b); } else { - ret = read_data(dev, lba); + ret = read_data(dev, lba, 1); /* Return with error if we had one. */ if (ret > 0) { @@ -2655,7 +2776,7 @@ cdrom_read_disc_information(const cdrom_t *dev, uint8_t *buffer) buffer[ 3] = first; /* Number of First Track on Disc */ buffer[ 4] = sessions; /* Number of Sessions (LSB) */ buffer[ 5] = ls_first; /* First Track Number in Last Session (LSB) */ - buffer[ 5] = ls_last; /* Last Track Number in Last Session (LSB) */ + buffer[ 6] = ls_last; /* Last Track Number in Last Session (LSB) */ buffer[ 7] = 0x20; /* Unrestricted use */ buffer[ 8] = t[0].ps; /* Disc Type */ buffer[ 9] = 0x00; /* Number Of Sessions (MSB) */ @@ -2800,7 +2921,7 @@ cdrom_read_track_information(cdrom_t *dev, const uint8_t *cdb, uint8_t *buffer) } if (track->adr_ctl & 0x04) { - ret = read_data(dev, start); + ret = read_data(dev, start, 0); mode = dev->raw_buffer[dev->cur_buf][3]; } } else if (track->point != 0xa2) @@ -2829,9 +2950,9 @@ uint8_t cdrom_get_current_mode(cdrom_t *dev) { if (dev->cached_sector == -1) - (void) read_data(dev, dev->seek_pos); + (void) read_data(dev, dev->seek_pos, 0); else - (void) read_data(dev, dev->cached_sector); + (void) read_data(dev, dev->cached_sector, 0); return dev->raw_buffer[dev->cur_buf][3]; } @@ -2864,7 +2985,7 @@ cdrom_update_status(cdrom_t *dev) dev->cached_sector = -1; dev->cdrom_capacity = dev->ops->get_last_block(dev->local); - if (dev->cd_status != CD_STATUS_EMPTY) { + if ((dev->cd_status != CD_STATUS_EMPTY) && (dev->cd_status != CD_STATUS_DVD_REJECTED)) { /* Signal media change to the emulated machine. */ cdrom_insert(dev->id); @@ -2906,9 +3027,14 @@ cdrom_load(cdrom_t *dev, const char *fn, const int skip_insert) if ((dev->ops->is_empty != NULL) && dev->ops->is_empty(dev->local)) dev->cd_status = CD_STATUS_EMPTY; - else if (dev->ops->is_dvd(dev->local)) - dev->cd_status = CD_STATUS_DVD; - else + else if (dev->ops->is_dvd(dev->local)) { + if (cdrom_is_dvd(dev->type)) + dev->cd_status = CD_STATUS_DVD; + else { + warning("DVD image \"%s\" in a CD-only drive, reporting as empty\n", fn); + dev->cd_status = CD_STATUS_DVD_REJECTED; + } + } else dev->cd_status = dev->ops->has_audio(dev->local) ? CD_STATUS_STOPPED : CD_STATUS_DATA_ONLY; @@ -2922,7 +3048,7 @@ cdrom_load(cdrom_t *dev, const char *fn, const int skip_insert) cdrom_toc_dump(dev); #endif - if (!skip_insert && (dev->cd_status != CD_STATUS_EMPTY)) { + if (!skip_insert && (dev->cd_status != CD_STATUS_EMPTY) && (dev->cd_status != CD_STATUS_DVD_REJECTED)) { /* Signal media change to the emulated machine. */ cdrom_insert(dev->id); @@ -3011,6 +3137,11 @@ cdrom_hard_reset(void) cdrom_load(dev, dev->image_path, 0); } + + for (uint32_t j = 0; j < _LUT_SIZE; ++j) { + dev->_F_LUT[j] = (j << 1) ^ (j & 0x80 ? 0x11d : 0); + dev->_B_LUT[j ^ dev->_F_LUT[j]] = j; + } } } diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 519afaa4c..81fadb272 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #ifndef _WIN32 # include @@ -84,17 +85,148 @@ typedef struct track_t { track_index_t idx[3]; } track_t; +/* + MDS for DVD has the disc structure table - 4 byte pointer to BCA, + followed by the copyright, DMI, and layer pages. +*/ +#pragma pack(push, 1) +typedef struct +{ + uint8_t f1[4]; + uint8_t f4[2048]; + uint8_t f0[2048]; +} layer_t; + +typedef struct +{ + layer_t layers[2]; +} mds_disc_struct_t; +#pragma pack(pop) + +#define dstruct_t mds_disc_struct_t + typedef struct cd_image_t { cdrom_t *dev; void *log; int is_dvd; int has_audio; + int has_dstruct; int32_t tracks_num; uint32_t bad_sectors_num; track_t *tracks; uint32_t *bad_sectors; + dstruct_t dstruct; } cd_image_t; +typedef enum +{ + CD = 0x00, /* CD-ROM */ + CD_R = 0x01, /* CD-R */ + CD_RW = 0x02, /* CD-RW */ + DVD = 0x10, /* DVD-ROM */ + DVD_MINUS_R = 0x12 /* DVD-R */ +} mds_medium_type_t; + +typedef enum +{ + UNKNOWN = 0x00, + AUDIO = 0xa9, /* sector size = 2352 */ + MODE1 = 0xaa, /* sector size = 2048 */ + MODE2 = 0xab, /* sector size = 2336 */ + MODE2_FORM1 = 0xac, /* sector size = 2048 */ + MODE2_FORM2 = 0xad /* sector size = 2324 (+4) */ +} mds_trk_mode_t; + +typedef enum +{ + NONE = 0x00, /* no subchannel */ + PW_INTERLEAVED = 0x08 /* 96-byte PW subchannel, interleaved */ +} mds_subch_mode_t; + +#pragma pack(push, 1) +typedef struct +{ + uint8_t file_sig[16]; + uint8_t file_ver[2]; + uint16_t medium_type; + uint16_t sess_num; + uint16_t pad[2]; + uint16_t bca_data_len; + uint32_t pad0[2]; + uint32_t bca_data_offs_offs; + uint32_t pad1[6]; + uint32_t disc_struct_offs; + uint32_t pad2[3]; + uint32_t sess_blocks_offs; + uint32_t dpm_blocks_offs; +} mds_hdr_t; /* 88 bytes */ + +typedef struct +{ + int32_t sess_start; + int32_t sess_end; + uint16_t sess_id; + uint8_t all_blocks_num; + uint8_t non_track_blocks_num; + uint16_t first_trk; + uint16_t last_trk; + uint32_t pad; + uint32_t trk_blocks_offs; +} mds_sess_block_t; /* 24 bytes */ + +typedef struct +{ + uint8_t trk_mode; + /* DiscImageCreator says this is the number of subchannels. */ + uint8_t subch_mode; + uint8_t adr_ctl; + uint8_t track_id; + uint8_t point; + uint8_t m; + uint8_t s; + uint8_t f; + uint8_t zero; + uint8_t pm; + uint8_t ps; + uint8_t pf; + /* DiscImageCreator calls this the index offset. */ + uint32_t ex_offs; + uint16_t sector_len; + /* DiscImageCreator says unknown1 followed by 17x zero. */ + uint8_t pad0[18]; + uint32_t start_sect; + uint64_t start_offs; + uint32_t files_num; + uint32_t footer_offs; + uint8_t pad1[24]; +} mds_trk_block_t; /* 80 bytes */ + +/* + DiscImageCreator's interpretation here makes sense and essentially + matches libmirage's - Index 0 sectors followed by Index 1 sectors. + */ +typedef struct +{ + uint32_t pregap; + uint32_t trk_sectors; +} mds_trk_ex_block_t; /* 8 bytes */ + +typedef struct +{ + uint32_t fn_offs; + uint32_t fn_is_wide; + uint32_t pad; + uint32_t pad0; +} mds_footer_t; /* 16 bytes */ + +typedef struct +{ + uint32_t type; + uint32_t pad[2]; + uint32_t entries; +} mds_dpm_block_t; +#pragma pack(pop) + #ifdef ENABLE_IMAGE_LOG int image_do_log = ENABLE_IMAGE_LOG; @@ -284,6 +416,9 @@ bin_close(void *priv) memset(tf->fn, 0x00, sizeof(tf->fn)); + log_close(tf->log); + tf->log = NULL; + free(priv); } @@ -298,6 +433,11 @@ bin_init(const uint8_t id, const char *filename, int *error) return NULL; } + char n[1024] = { 0 }; + + sprintf(n, "CD-ROM %i Bin ", id + 1); + tf->log = log_open(n); + memset(tf->fn, 0x00, sizeof(tf->fn)); strncpy(tf->fn, filename, sizeof(tf->fn) - 1); tf->fp = plat_fopen64(tf->fn, "rb"); @@ -314,11 +454,6 @@ bin_init(const uint8_t id, const char *filename, int *error) tf->read = bin_read; tf->get_length = bin_get_length; tf->close = bin_close; - - char n[1024] = { 0 }; - - sprintf(n, "CD-ROM %i Bin ", id + 1); - tf->log = log_open(n); } else { /* 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. @@ -326,8 +461,12 @@ bin_init(const uint8_t id, const char *filename, int *error) if ((tf->fp != NULL) && ((stats.st_mode & S_IFMT) == S_IFDIR)) { /* tf is freed by bin_close */ bin_close(tf); - } else + } else { + log_close(tf->log); + tf->log = NULL; + free(tf); + } tf = NULL; } @@ -1183,7 +1322,7 @@ image_process(cd_image_t *img) ct->point, j, cit[ci->type + 2], ci->file_start * ct->sector_size); image_log(img->log, " TOC data: %02X %02X %02X " - "%%02X %02X %02X %02X 02X %02X %02X %02X\n", + "%02X %02X %02X %02X %02X %02X %02X %02X\n", ct->session, ct->attr, ct->tno, ct->point, ct->extra[0], ct->extra[1], ct->extra[2], ct->extra[3], (uint32_t) ((ci->start / 75) / 60), @@ -1208,12 +1347,12 @@ image_set_track_subch_type(track_t *ct) static int image_load_iso(cd_image_t *img, const char *filename) { - track_t *ct = NULL; - track_index_t *ci = NULL; - track_file_t *tf = NULL; - int success = 1; - int error = 1; - int is_viso = 0; + track_t *ct = NULL; + track_index_t *ci = NULL; + track_file_t *tf = NULL; + int success = 1; + int error = 1; + int is_viso = 0; int sector_sizes[8] = { 2448, 2368, RAW_SECTOR_SIZE, 2336, 2332, 2328, 2324, COOKED_SECTOR_SIZE }; @@ -1308,8 +1447,12 @@ image_load_iso(cd_image_t *img, const char *filename) if (success) image_process(img); else { - image_log(img->log, " [ISO ] Unable to open image or folder \"%s\"\n", - filename); +#ifdef ENABLE_IMAGE_LOG + log_warning(img->log, "Unable to open image or folder \"%s\"\n", + filename); +#else + warning("Unable to open image or folder \"%s\"\n", filename); +#endif return 0; } @@ -1446,9 +1589,9 @@ image_load_cue(cd_image_t *img, const char *cuefile) if (last_t != -1) { /* Important: This has to be done like this because pointers - change due to realloc. + change due to realloc. */ - ct = &(img->tracks[t]); + ct = &(img->tracks[img->tracks_num - 1]); for (int i = 2; i >= 0; i--) { if (ct->idx[i].file == NULL) @@ -1654,11 +1797,436 @@ image_load_cue(cd_image_t *img, const char *cuefile) if (success) image_process(img); - else { - image_log(img->log, " [CUE ] Unable to open Cue sheet \"%s\"\n", cuefile); + else +#ifdef ENABLE_IMAGE_LOG + log_warning(img->log, " [CUE ] Unable to open Cue sheet \"%s\"\n", cuefile); +#else + warning("Unable to open Cue sheet \"%s\"\n", cuefile); +#endif + + return success; +} + +// Converts UTF-16 string into UTF-8 string. +// If destination string is NULL returns total number of symbols that would've +// been written (without null terminator). However, when actually writing into +// destination string, it does include it. So, be sure to allocate extra byte +// for destination string. +// Params: +// u16_str - source UTF-16 string +// u16_str_len - length of source UTF-16 string +// u8_str - destination UTF-8 string +// u8_str_size - size of destination UTF-8 string in bytes +// Return value: +// 0 on success, -1 if encountered invalid surrogate pair, -2 if +// encountered buffer overflow or length of destination UTF-8 string in bytes +// (without including the null terminator). +long int utf16_to_utf8(const uint16_t *u16_str, size_t u16_str_len, + uint8_t *u8_str, size_t u8_str_size) +{ + size_t i = 0, j = 0; + + if (!u8_str) { + u8_str_size = u16_str_len * 4; + } + + while (i < u16_str_len) { + uint32_t codepoint = u16_str[i++]; + + // check for surrogate pair + if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { + uint16_t high_surr = codepoint; + uint16_t low_surr = u16_str[i++]; + + if (low_surr < 0xDC00 || low_surr > 0xDFFF) + return -1; + + codepoint = ((high_surr - 0xD800) << 10) + + (low_surr - 0xDC00) + 0x10000; + } + + if (codepoint < 0x80) { + if (j + 1 > u8_str_size) return -2; + + if (u8_str) u8_str[j] = (char)codepoint; + + j++; + } else if (codepoint < 0x800) { + if (j + 2 > u8_str_size) return -2; + + if (u8_str) { + u8_str[j + 0] = 0xC0 | (codepoint >> 6); + u8_str[j + 1] = 0x80 | (codepoint & 0x3F); + } + + j += 2; + } else if (codepoint < 0x10000) { + if (j + 3 > u8_str_size) return -2; + + if (u8_str) { + u8_str[j + 0] = 0xE0 | (codepoint >> 12); + u8_str[j + 1] = 0x80 | ((codepoint >> 6) & 0x3F); + u8_str[j + 2] = 0x80 | (codepoint & 0x3F); + } + + j += 3; + } else { + if (j + 4 > u8_str_size) return -2; + + if (u8_str) { + u8_str[j + 0] = 0xF0 | (codepoint >> 18); + u8_str[j + 1] = 0x80 | ((codepoint >> 12) & 0x3F); + u8_str[j + 2] = 0x80 | ((codepoint >> 6) & 0x3F); + u8_str[j + 3] = 0x80 | (codepoint & 0x3F); + } + + j += 4; + } + } + + if (u8_str) { + if (j >= u8_str_size) return -2; + u8_str[j] = '\0'; + } + + return (long int)j; +} + +static int +image_load_mds(cd_image_t *img, const char *mdsfile) +{ + track_t *ct = NULL; + track_index_t *ci = NULL; + track_file_t *tf = NULL; + int is_viso = 0; + int last_t = -1; + int error; + char pathname[MAX_FILENAME_LENGTH]; + char ofn[2048] = { 0 }; + + mds_hdr_t mds_hdr = { 0 }; + mds_sess_block_t mds_sess_block = { 0 }; + mds_trk_block_t mds_trk_block = { 0 }; + mds_trk_ex_block_t mds_trk_ex_block = { 0 }; + mds_footer_t mds_footer = { 0 }; + mds_dpm_block_t mds_dpm_block = { 0 }; + uint32_t mds_dpm_blocks_num = 0x00000000; + uint32_t mds_dpm_block_offs = 0x00000000; + + img->tracks = NULL; + img->tracks_num = 0; + + /* Get a copy of the filename into pathname, we need it later. */ + memset(pathname, 0, MAX_FILENAME_LENGTH * sizeof(char)); + path_get_dirname(pathname, mdsfile); + + /* Open the file. */ + FILE *fp = plat_fopen(mdsfile, "rb"); + if (fp == NULL) + return 0; + + int success = 0; + + /* + Pass 1 - loading the MDS sheet. + */ + image_log(img->log, "Pass 1 (loading the Media Descriptor Sheet)...\n"); + img->tracks_num = 0; + success = 2; + + fseek(fp, 0, SEEK_SET); + fread(&mds_hdr, 1, sizeof(mds_hdr_t), fp); + + if (memcmp(mds_hdr.file_sig, "MEDIA DESCRIPTOR", 16)) { +#ifdef ENABLE_IMAGE_LOG + log_warning(img->log, " [MDS ] \"%s\"\n is not an actual MDF file", + mdsfile); +#else + warning("\"%s\"\n is not an actual MDF file", mdsfile); +#endif + fclose(fp); return 0; } + if (mds_hdr.file_ver[0] == 0x02) { +#ifdef ENABLE_IMAGE_LOG + log_warning(img->log, " [MDS ] \"%s\" is a Daemon Tools encrypted MDS which is not supported\n", + mdsfile); +#else + warning("\"%s\" is a Daemon Tools encrypted MDS which is not supported\n", mdsfile); +#endif + fclose(fp); + return 0; + } + + img->is_dvd = (mds_hdr.medium_type >= 0x10); + + if (img->is_dvd) { + if (mds_hdr.disc_struct_offs != 0x00) { + fseek(fp, mds_hdr.disc_struct_offs, SEEK_SET); + fread(&(img->dstruct.layers[0]), 1, sizeof(layer_t), fp); + img->has_dstruct = 1; + + if (((img->dstruct.layers[0].f0[2] & 0x60) >> 4) == 0x01) { + fseek(fp, mds_hdr.disc_struct_offs, SEEK_SET); + fread(&(img->dstruct.layers[1]), 1, sizeof(layer_t), fp); + img->has_dstruct++; + } + } + + for (int t = 0; t < 3; t++) { + ct = image_insert_track(img, 1, 0xa0 + t); + + ct->attr = DATA_TRACK; + ct->mode = 0; + ct->form = 0; + ct->tno = 0; + ct->subch_type = 0; + memset(ct->extra, 0x00, 4); + + for (int i = 0; i < 3; i++) { + ci = &(ct->idx[i]); + ci->type = INDEX_NONE; + ci->start = 0; + ci->length = 0; + ci->file_start = 0; + ci->file_length = 0; + ci->file = NULL; + } + + ci = &(ct->idx[1]); + + if (t < 2) + ci->start = (0x01 * 60 * 75) + (0 * 75) + 0; + } + } + + if (mds_hdr.dpm_blocks_offs != 0x00) { + fseek(fp, mds_hdr.dpm_blocks_offs, SEEK_SET); + fread(&mds_dpm_blocks_num, 1, sizeof(uint32_t), fp); + + if (mds_dpm_blocks_num > 0) for (int b = 0; b < mds_dpm_blocks_num; b++) { + fseek(fp, mds_hdr.dpm_blocks_offs + 4 + (b * 4), SEEK_SET); + fread(&mds_dpm_block_offs, 1, sizeof(uint32_t), fp); + + fseek(fp, mds_dpm_block_offs, SEEK_SET); + fread(&mds_dpm_block, 1, sizeof(mds_dpm_block_t), fp); + + /* We currently only support the bad sectors block and not (yet) actual DPM. */ + if (mds_dpm_block.type == 0x00000002) { + /* Bad sectors. */ + img->bad_sectors_num = mds_dpm_block.entries; + img->bad_sectors = (uint32_t *) malloc(img->bad_sectors_num * sizeof(uint32_t)); + fseek(fp, mds_dpm_block_offs + sizeof(mds_dpm_block_t), SEEK_SET); + fread(img->bad_sectors, 1, img->bad_sectors_num * sizeof(uint32_t), fp); + break; + } + } + } + + for (int s = 0; s < mds_hdr.sess_num; s++) { + fseek(fp, mds_hdr.sess_blocks_offs + (s * sizeof(mds_sess_block_t)), SEEK_SET); + fread(&mds_sess_block, 1, sizeof(mds_sess_block_t), fp); + + for (int t = 0; t < mds_sess_block.all_blocks_num; t++) { + fseek(fp, mds_sess_block.trk_blocks_offs + (t * sizeof(mds_trk_block_t)), SEEK_SET); + fread(&mds_trk_block, 1, sizeof(mds_trk_block_t), fp); + + if (last_t != -1) { + /* + Important: This has to be done like this because pointers + change due to realloc. + */ + ct = &(img->tracks[img->tracks_num - 1]); + + for (int i = 2; i >= 0; i--) { + if (ct->idx[i].file == NULL) + ct->idx[i].file = tf; + else + break; + } + } + + last_t = mds_trk_block.point; + ct = image_insert_track(img, mds_sess_block.sess_id, mds_trk_block.point); + + if (img->is_dvd) { + /* DVD images have no extra block - the extra block offset is the track length. */ + memset(&mds_trk_ex_block, 0x00, sizeof(mds_trk_ex_block_t)); + mds_trk_ex_block.pregap = 0x00000000; + mds_trk_ex_block.trk_sectors = mds_trk_block.ex_offs; + } else if (mds_trk_block.ex_offs != 0ULL) { + fseek(fp, mds_trk_block.ex_offs, SEEK_SET); + fread(&mds_trk_ex_block, 1, sizeof(mds_trk_ex_block), fp); + } + + uint32_t astart = mds_trk_block.start_sect - mds_trk_ex_block.pregap; + uint32_t aend = astart + mds_trk_ex_block.pregap; + uint32_t aend2 = aend + mds_trk_ex_block.trk_sectors; + uint32_t astart2 = mds_trk_block.start_sect + mds_trk_ex_block.trk_sectors; + + if (mds_trk_block.footer_offs != 0ULL) for (uint32_t ff = 0; ff < mds_trk_block.files_num; ff++) { + fseek(fp, mds_trk_block.footer_offs + (ff * sizeof(mds_footer_t)), SEEK_SET); + fread(&mds_footer, 1, sizeof(mds_footer_t), fp); + + uint16_t wfn[2048] = { 0 }; + char fn[2048] = { 0 }; + fseek(fp, mds_footer.fn_offs, SEEK_SET); + if (mds_footer.fn_is_wide) { + int len = 0; + for (int i = 0; i < 256; i++) { + fread(&(wfn[i]), 1, 2, fp); + len++; + if (wfn[i] == 0x0000) + break; + } + (void) utf16_to_utf8(wfn, 2048, (uint8_t *) fn, 2048); + } else for (int i = 0; i < 512; i++) { + fread(&fn[i], 1, 1, fp); + if (fn[i] == 0x00) + break; + } + + if (!stricmp(fn, "*.mdf")) { + strcpy(fn, mdsfile); + fn[strlen(mdsfile) - 3] = 'm'; + fn[strlen(mdsfile) - 2] = 'd'; + fn[strlen(mdsfile) - 1] = 'f'; + } + + char filename[2048] = { 0 }; + if (!path_abs(fn)) + path_append_filename(filename, pathname, fn); + else + strcpy(filename, fn); + + if (strcmp(ofn, filename) != 0) { + tf = index_file_init(img->dev->id, filename, &error, &is_viso); + strcpy(ofn, filename); + } + } + + ct->sector_size = mds_trk_block.sector_len; + ct->form = 0; + ct->tno = mds_trk_block.track_id; + ct->subch_type = mds_trk_block.subch_mode; + ct->extra[0] = mds_trk_block.m; + ct->extra[1] = mds_trk_block.s; + ct->extra[2] = mds_trk_block.f; + ct->extra[3] = mds_trk_block.zero; + /* + Note from DiscImageCreator: + + I hexedited the track mode field with various values and fed it to Alchohol; + it seemed that high part of byte had no effect at all; only the lower one + affected the mode, in the following manner: + 00: Mode 2, 01: Audio, 02: Mode 1, 03: Mode 2, 04: Mode 2 Form 1, + 05: Mode 2 Form 2, 06: UKNONOWN, 07: Mode 2 + 08: Mode 2, 09: Audio, 0A: Mode 1, 0B: Mode 2, 0C: Mode 2 Form 1, + 0D: Mode 2 Form 2, 0E: UKNONOWN, 0F: Mode 2 + */ + ct->attr = ((mds_trk_block.trk_mode & 0x07) == 0x01) ? + AUDIO_TRACK : DATA_TRACK; + ct->mode = 0; + ct->form = 0; + if (((mds_trk_block.trk_mode & 0x07) != 0x01) && + ((mds_trk_block.trk_mode & 0x07) != 0x06)) + ct->mode = ((mds_trk_block.trk_mode & 0x07) != 0x02) + 1; + if ((mds_trk_block.trk_mode & 0x06) == 0x04) + ct->form = (mds_trk_block.trk_mode & 0x07) - 0x03; + if (ct->attr == AUDIO_TRACK) + success = 1; + + if (((ct->sector_size == 2336) || (ct->sector_size == 2332)) && (ct->mode == 2) && (ct->form == 1)) + ct->skip = 8; + + ci = &(ct->idx[0]); + if (ct->point < 0xa0) { + ci->start = astart + 150; + ci->length = mds_trk_ex_block.pregap; + } + ci->type = (ci->length > 0) ? INDEX_ZERO : INDEX_NONE; + ci->file_start = 0; + ci->file_length = 0; + ci->file = NULL; + + ci = &(ct->idx[1]); + if ((mds_trk_block.point >= 1) && (mds_trk_block.point <= 99)) { + ci->start = aend + 150; + ci->length = mds_trk_ex_block.trk_sectors; + ci->type = INDEX_NORMAL; + ci->file_start = mds_trk_block.start_offs / ct->sector_size; + ci->file_length = ci->length; + ci->file = tf; + } else { + ci->start = (mds_trk_block.pm * 60 * 75) + (mds_trk_block.ps * 75) + mds_trk_block.pf; + ci->type = INDEX_NONE; + ci->file_start = 0; + ci->file_length = 0; + ci->file = NULL; + } + + ci = &(ct->idx[2]); + if (ct->point < 0xa0) { + ci->start = aend2 + 150; + ci->length = astart2 - aend2; + } + ci->type = (ci->length > 0) ? INDEX_ZERO : INDEX_NONE; + ci->file_start = 0; + ci->file_length = 0; + ci->file = NULL; + + if (img->is_dvd) { + ci = &(ct->idx[1]); + uint32_t total = ci->start + ci->length; + + ci = &(img->tracks[2].idx[1]); + ci->start = total; + } + } + + for (int i = 2; i >= 0; i--) { + if (ct->point >= 0xa0) + ci->type = INDEX_SPECIAL; + + if (ct->idx[i].file == NULL) + ct->idx[i].file = tf; + else + break; + } + } + + tf = NULL; + + fclose(fp); + + if (success) { +#ifdef ENABLE_IMAGE_LOG + image_log(img->log, "Final tracks list:\n"); + for (int i = 0; i < img->tracks_num; i++) { + ct = &(img->tracks[i]); + for (int j = 0; j < 3; j++) { + ci = &(ct->idx[j]); + image_log(img->log, " [TRACK ] %02X INDEX %02X: [%8s, %016" PRIX64 "]\n", + ct->point, j, + cit[ci->type + 2], ci->file_start * ct->sector_size); + image_log(img->log, " TOC data: %02X %02X %02X " + "%02X %02X %02X %02X %02X %02X %02X %02X\n", + ct->session, ct->attr, ct->tno, ct->point, + ct->extra[0], ct->extra[1], ct->extra[2], ct->extra[3], + (uint32_t) ((ci->start / 75) / 60), + (uint32_t) ((ci->start / 75) % 60), + (uint32_t) (ci->start % 75)); + } + } +#endif + } else +#ifdef ENABLE_IMAGE_LOG + log_warning(img->log, " [MDS ] Unable to open MDS sheet \"%s\"\n", mdsfile); +#else + warning("Unable to open MDS sheet \"%s\"\n", mdsfile); +#endif + return success; } @@ -1713,8 +2281,8 @@ image_get_track_info(const void *local, const uint32_t track, } if (ct != NULL) { - const uint32_t pos = end ? ct->idx[1].start : - (ct->idx[1].start + ct->idx[1].length); + const uint32_t pos = end ? (ct->idx[1].start + ct->idx[1].length) : + ct->idx[1].start; ti->number = ct->point; ti->attr = ct->attr; @@ -1784,6 +2352,7 @@ image_read_sector(const void *local, uint8_t *buffer, const uint32_t sector) { const cd_image_t *img = (const cd_image_t *) local; + cdrom_t *dev = (cdrom_t *) img->dev; int m = 0; int s = 0; int f = 0; @@ -1792,6 +2361,7 @@ image_read_sector(const void *local, uint8_t *buffer, int track; int index; uint8_t q[16] = { 0x00 }; + uint8_t *buf = buffer; if (sector == 0xffffffff) lba = img->dev->seek_pos; @@ -1851,6 +2421,26 @@ image_read_sector(const void *local, uint8_t *buffer, /* Index is not in the file, no read to fail here. */ ret = 1; + if ((ret > 0) && (trk->attr & 0x04) && ((idx->type < INDEX_NORMAL) || !track_is_raw)) { + uint32_t crc; + + if ((trk->mode == 2) && (trk->form == 1)) { + crc = cdrom_crc32(0xffffffff, &(buf[16]), 2056) ^ 0xffffffff; + memcpy(&(buf[2072]), &crc, 4); + } else { + crc = cdrom_crc32(0xffffffff, buf, 2064) ^ 0xffffffff; + memcpy(&(buf[2064]), &crc, 4); + } + + int m2f1 = (trk->mode == 2) && (trk->form == 1); + + /* Compute ECC P code. */ + cdrom_compute_ecc_block(dev, &(buf[2076]), &(buf[12]), 86, 24, 2, 86, m2f1); + + /* Compute ECC Q code. */ + cdrom_compute_ecc_block(dev, &(buf[2248]), &(buf[12]), 52, 43, 86, 88, m2f1); + } + if ((ret > 0) && ((idx->type < INDEX_NORMAL) || (trk->subch_type != 0x08))) { buffer -= offset; @@ -1945,7 +2535,27 @@ static int image_read_dvd_structure(const void *local, const uint8_t layer, const uint8_t format, uint8_t *buffer, uint32_t *info) { - return 0; + const cd_image_t *img = (const cd_image_t *) local; + int ret = 0; + + if ((img->has_dstruct > 0) && ((layer + 1) > img->has_dstruct)) { + switch (format) { + case 0x00: + memcpy(buffer + 4, img->dstruct.layers[layer].f0, 2048); + ret = 2048 + 2; + break; + case 0x01: + memcpy(buffer + 4, img->dstruct.layers[layer].f1, 4); + ret = 4 + 2; + break; + case 0x04: + memcpy(buffer + 4, img->dstruct.layers[layer].f4, 2048); + ret = 2048 + 2; + break; + } + } + + return ret; } static int @@ -1977,6 +2587,9 @@ image_close(void *local) log_close(img->log); img->log = NULL; + if (img->bad_sectors != NULL) + free(img->bad_sectors); + free(img); } } @@ -2005,34 +2618,53 @@ image_open(cdrom_t *dev, const char *path) if (img != NULL) { int ret; - const int is_cue = ((ext == 4) && !stricmp(path + strlen(path) - ext + 1, "CUE")); + const int is_cue = ((ext == 4) && !stricmp(path + strlen(path) - ext + 1, "CUE")); + const int is_mds = ((ext == 4) && !stricmp(path + strlen(path) - ext + 1, "MDS")); + char n[1024] = { 0 }; - img->dev = dev; + sprintf(n, "CD-ROM %i Image", dev->id + 1); + img->log = log_open(n); - if (is_cue) { + img->dev = dev; + + if (is_mds) { + ret = image_load_mds(img, path); + + if (ret >= 2) + img->has_audio = 0; + else if (ret) + img->has_audio = 1; + } else if (is_cue) { ret = image_load_cue(img, path); if (ret >= 2) img->has_audio = 0; else if (ret) img->has_audio = 1; + + if (ret >= 1) + img->is_dvd = 2; } else { ret = image_load_iso(img, path); - if (!ret) { - image_close(img); - img = NULL; - } else + if (ret) { img->has_audio = 0; + img->is_dvd = 2; + } } - if (ret) { - char n[1024] = { 0 }; - - sprintf(n, "CD-ROM %i Image", dev->id + 1); - img->log = log_open(n); + if (ret > 0) { + if (img->is_dvd == 2) { + uint32_t lb = image_get_last_block(img); /* Should be safer than previous way of doing it? */ + img->is_dvd = (lb >= 524287); /* Minimum 1 GB total capacity as threshold for DVD. */ + } dev->ops = &image_ops; + } else { + log_warning(img->log, "Unable to load CD-ROM image: %s\n", path); + + image_close(img); + img = NULL; } } diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index 4bf976794..3eec6d5a1 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -446,24 +446,36 @@ static int viso_fill_time(uint8_t *data, time_t time, int format, int longform) { uint8_t *p = data; - struct tm *time_s = localtime(&time); - if (!time_s) { - /* localtime will return NULL if the time_t is negative (Windows) - or way too far into 64-bit space (Linux). Fall back to epoch. */ - time_t epoch = 0; - time_s = localtime(&epoch); - if (UNLIKELY(!time_s)) - fatal("VISO: localtime(0) = NULL\n"); + struct tm time_s_buf; + struct tm *time_s = NULL; + time_t epoch = 0; - /* Force year clamping if the timestamp is known to be outside the supported ranges. */ +#ifdef _WIN32 + if (localtime_s(&time_s_buf, &time) == 0) + time_s = &time_s_buf; +#else + time_s = localtime_r(&time, &time_s_buf); +#endif + + if (!time_s) { + /* localtime may return NULL if time is negative or out of range */ +#ifdef _WIN32 + if (localtime_s(&time_s_buf, &epoch) == 0) + time_s = &time_s_buf; +#else + time_s = localtime_r(&epoch, &time_s_buf); +#endif + if (!time_s) + fatal("VISO: localtime fallback to epoch failed\n"); + + /* Force year clamping for out-of-range times */ if (time < (longform ? -62135596800LL : -2208988800LL)) /* 0001-01-01 00:00:00 : 1900-01-01 00:00:00 */ time_s->tm_year = -1901; else if (time > (longform ? 253402300799LL : 5869583999LL)) /* 9999-12-31 23:59:59 : 2155-12-31 23:59:59 */ time_s->tm_year = 8100; } - /* Clamp year to the supported ranges, and assume the - OS returns valid numbers in the other struct fields. */ + /* Clamp year within supported ranges */ if (time_s->tm_year < (longform ? -1900 : 0)) { time_s->tm_year = longform ? -1900 : 0; time_s->tm_mon = time_s->tm_hour = time_s->tm_min = time_s->tm_sec = 0; @@ -476,18 +488,18 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform) time_s->tm_min = time_s->tm_sec = 59; } - /* Convert timestamp. */ + /* Convert timestamp */ if (longform) { - p += sprintf((char *) p, "%04u%02u%02u%02u%02u%02u00", - 1900 + time_s->tm_year, 1 + time_s->tm_mon, time_s->tm_mday, + p += sprintf((char *)p, "%04u%02u%02u%02u%02u%02u00", + 1900 + (unsigned)time_s->tm_year, 1 + time_s->tm_mon, time_s->tm_mday, time_s->tm_hour, time_s->tm_min, time_s->tm_sec); } else { - *p++ = time_s->tm_year; /* year since 1900 */ - *p++ = 1 + time_s->tm_mon; /* month */ - *p++ = time_s->tm_mday; /* day */ - *p++ = time_s->tm_hour; /* hour */ - *p++ = time_s->tm_min; /* minute */ - *p++ = time_s->tm_sec; /* second */ + *p++ = (uint8_t)time_s->tm_year; /* year since 1900 */ + *p++ = (uint8_t)(1 + time_s->tm_mon); /* month */ + *p++ = (uint8_t)time_s->tm_mday; /* day */ + *p++ = (uint8_t)time_s->tm_hour; /* hour */ + *p++ = (uint8_t)time_s->tm_min; /* minute */ + *p++ = (uint8_t)time_s->tm_sec; /* second */ } if (format & VISO_FORMAT_ISO) *p++ = tz_offset; /* timezone (ISO only) */ @@ -782,9 +794,8 @@ viso_close(void *priv) if (viso->entry_map) free(viso->entry_map); - if (tf->log != NULL) { - - } + if (tf->log != NULL) + log_close(tf->log); free(viso); } @@ -1035,8 +1046,15 @@ next_dir: the timezone offset for descriptors and file times to use. */ tzset(); time_t now = time(NULL); - if (viso->format & VISO_FORMAT_ISO) /* timezones are ISO only */ - tz_offset = (now - mktime(gmtime(&now))) / (3600 / 4); + struct tm now_tm; + if (viso->format & VISO_FORMAT_ISO) { /* timezones are ISO only */ +#ifdef _WIN32 + gmtime_s(&now_tm, &now); // Windows: output first param, input second +#else + gmtime_r(&now, &now_tm); // POSIX: input first param, output second +#endif + tz_offset = (now - mktime(&now_tm)) / (3600 / 4); + } /* Get root directory basename for the volume ID. */ const char *basename = path_get_filename(viso->root_dir->path); @@ -1607,10 +1625,12 @@ end: return &viso->tf; } else { - image_viso_log(viso->tf.log, "Initialization failed\n"); - if (data) - free(data); - viso_close(&viso->tf); + if (viso != NULL) { + image_viso_log(viso->tf.log, "Initialization failed\n"); + if (data) + free(data); + viso_close(&viso->tf); + } return NULL; } } diff --git a/src/cdrom/cdrom_mitsumi.c b/src/cdrom/cdrom_mitsumi.c index e27faab94..47501c25c 100644 --- a/src/cdrom/cdrom_mitsumi.c +++ b/src/cdrom/cdrom_mitsumi.c @@ -8,11 +8,11 @@ * * Mitsumi CD-ROM emulation for the ISA bus. * - * - * * Authors: Miran Grca, + * Jasmine Iwanek, * - * Copyright 2022 Miran Grca. + * Copyright 2022 Miran Grca. + * Copyright 2024-2025 Jasmine Iwanek. */ #include #include @@ -33,10 +33,6 @@ #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 @@ -116,6 +112,8 @@ typedef struct mcd_t { int cur_toc_track; int pos; int newstat; + + cdrom_t *cdrom_dev; } mcd_t; #define CD_BCD(x) (((x) % 10) | (((x) / 10) << 4)) @@ -140,17 +138,15 @@ mitsumi_cdrom_log(const char *fmt, ...) #endif static int -mitsumi_cdrom_is_ready(const cdrom_t *dev) +mitsumi_cdrom_is_ready(const mcd_t *dev) { - return (dev->image_path[0] != 0x00); + return (dev->cdrom_dev->image_path[0] != 0x00); } static void mitsumi_cdrom_reset(mcd_t *dev) { - cdrom_t *cdrom = calloc(1, sizeof(cdrom_t)); - - dev->stat = mitsumi_cdrom_is_ready(cdrom) ? (STAT_READY | STAT_CHANGE) : 0; + dev->stat = mitsumi_cdrom_is_ready(dev) ? (STAT_READY | STAT_CHANGE) : 0; dev->cmdrd_count = 0; dev->cmdbuf_count = 0; dev->buf_count = 0; @@ -168,12 +164,11 @@ mitsumi_cdrom_reset(mcd_t *dev) static int mitsumi_cdrom_read_sector(mcd_t *dev, int first) { - cdrom_t *cdrom = calloc(1, sizeof(cdrom_t)); uint8_t status; int ret = 0; if (dev->drvmode == DRV_MODE_CDDA) { - status = cdrom_mitsumi_audio_play(cdrom, dev->readmsf, dev->readcount); + status = cdrom_mitsumi_audio_play(dev->cdrom_dev, dev->readmsf, dev->readcount); if (status == 1) return status; else @@ -187,15 +182,15 @@ mitsumi_cdrom_read_sector(mcd_t *dev, int first) dev->data = 0; return 0; } - cdrom_stop(cdrom); - ret = cdrom_readsector_raw(cdrom, dev->buf, cdrom->seek_pos, 0, 2, 0x10, (int *) &dev->readcount, 0); + cdrom_stop(dev->cdrom_dev); + ret = cdrom_readsector_raw(dev->cdrom_dev, dev->buf, dev->cdrom_dev->seek_pos, 0, 2, 0x10, (int *) &dev->readcount, 0); if (ret <= 0) return 0; if (dev->mode & 0x40) { dev->buf[12] = CD_BCD((dev->readmsf >> 16) & 0xff); dev->buf[13] = CD_BCD((dev->readmsf >> 8) & 0xff); } - dev->readmsf = cdrom_lba_to_msf_accurate(cdrom->seek_pos + 1); + dev->readmsf = cdrom_lba_to_msf_accurate(dev->cdrom_dev->seek_pos + 1); dev->buf_count = dev->dmalen + 1; dev->buf_idx = 0; dev->data = 1; @@ -258,7 +253,6 @@ static void mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) { mcd_t *dev = (mcd_t *) priv; - cdrom_t *cdrom = calloc(1, sizeof(cdrom_t)); pclog("Mitsumi CD-ROM OUT=%03x, val=%02x\n", port, val); switch (port & 1) { @@ -340,19 +334,19 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) break; } if (!dev->cmdrd_count) - dev->stat = mitsumi_cdrom_is_ready(cdrom) ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0; + dev->stat = mitsumi_cdrom_is_ready(dev) ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0; return; } dev->cmd = val; dev->cmdbuf_idx = 0; dev->cmdrd_count = 0; dev->cmdbuf_count = 1; - dev->cmdbuf[0] = mitsumi_cdrom_is_ready(cdrom) ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0; + dev->cmdbuf[0] = mitsumi_cdrom_is_ready(dev) ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0; dev->data = 0; switch (val) { case CMD_GET_INFO: - if (mitsumi_cdrom_is_ready(cdrom)) { - cdrom_get_track_buffer(cdrom, &(dev->cmdbuf[1])); + if (mitsumi_cdrom_is_ready(dev)) { + cdrom_get_track_buffer(dev->cdrom_dev, &(dev->cmdbuf[1])); dev->cmdbuf_count = 10; dev->readcount = 0; } else { @@ -361,7 +355,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) } break; case CMD_GET_Q: - if (mitsumi_cdrom_is_ready(cdrom)) { + if (mitsumi_cdrom_is_ready(dev)) { cdrom_get_q(cdrom, &(dev->cmdbuf[1]), &dev->cur_toc_track, dev->mode & MODE_GET_TOC); dev->cmdbuf_count = 11; dev->readcount = 0; @@ -378,7 +372,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) break; case CMD_STOPCDDA: case CMD_STOP: - cdrom_stop(cdrom); + cdrom_stop(dev->cdrom_dev); dev->drvmode = DRV_MODE_STOP; dev->cur_toc_track = 0; break; @@ -387,7 +381,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) break; case CMD_READ1X: case CMD_READ2X: - if (mitsumi_cdrom_is_ready(cdrom)) { + if (mitsumi_cdrom_is_ready(dev)) { dev->readcount = 0; dev->drvmode = (val == CMD_READ1X) ? DRV_MODE_CDDA : DRV_MODE_READ; dev->cmdrd_count = 6; @@ -403,7 +397,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) dev->cmdbuf_count = 3; break; case CMD_EJECT: - cdrom_stop(cdrom); + cdrom_stop(dev->cdrom_dev); cdrom_eject(0); dev->readcount = 0; break; @@ -434,10 +428,23 @@ mitsumi_cdrom_init(UNUSED(const device_t *info)) { mcd_t *dev = calloc(1, sizeof(mcd_t)); - dev->irq = MCD_DEFAULT_IRQ; - dev->dma = MCD_DEFAULT_DMA; + for (uint8_t i = 0; i < CDROM_NUM; i++) { + if (cdrom[i].bus_type == CDROM_BUS_MITSUMI) { + dev->cdrom_dev = &cdrom[i]; + break; + } + } - io_sethandler(MCD_DEFAULT_IOPORT, 3, + if (!dev->cdrom_dev) + return NULL; + + dev->cdrom_dev->priv = &dev; + + uint16_t base = device_get_config_hex16("base"); + dev->irq = device_get_config_int("irq"); + dev->dma = device_get_config_int("dma"); + + io_sethandler(base, 3, mitsumi_cdrom_in, NULL, NULL, mitsumi_cdrom_out, NULL, NULL, dev); mitsumi_cdrom_reset(dev); @@ -456,6 +463,64 @@ mitsumi_cdrom_close(void *priv) } } +static const device_config_t mitsumi_config[] = { + // clang-format off + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x310, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "300H", .value = 0x300 }, + { .description = "310H", .value = 0x310 }, + { .description = "320H", .value = 0x320 }, + { .description = "340H", .value = 0x340 }, + { .description = "350H", .value = 0x350 }, + { NULL } + }, + .bios = { { 0 } } + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 9", .value = 9 }, + { .description = "IRQ 10", .value = 10 }, + { .description = "IRQ 11", .value = 11 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 5", .value = 5 }, + { .description = "DMA 6", .value = 6 }, + { .description = "DMA 7", .value = 7 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format off +}; + const device_t mitsumi_cdrom_device = { .name = "Mitsumi CD-ROM interface", .internal_name = "mcd", @@ -467,5 +532,5 @@ const device_t mitsumi_cdrom_device = { .available = NULL, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL + .config = mitsumi_config }; diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c new file mode 100644 index 000000000..98ae6c057 --- /dev/null +++ b/src/cdrom/cdrom_mke.c @@ -0,0 +1,1078 @@ +/* + * 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. + * + * Panasonic/MKE CD-ROM emulation for the ISA bus. + * + * Authors: Miran Grca, + * Kevin Moonlight, + * Cacodemon345 + * + * Copyright (C) 2025 Miran Grca. + * Copyright (C) 2025 Cacodemon345. + * Copyright (C) 2024 Kevin Moonlight. + */ +#include +#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/pic.h> +#include <86box/dma.h> +#include <86box/cdrom.h> +#include <86box/cdrom_interface.h> +#include <86box/cdrom_mke.h> +#include <86box/plat.h> +#include <86box/ui.h> +#include <86box/sound.h> +#include <86box/fifo8.h> +#include <86box/timer.h> +#ifdef ENABLE_MKE_LOG +#include "cpu.h" +#endif + +/* +https://elixir.bootlin.com/linux/2.0.29/source/include/linux/sbpcd.h +CR-562-B is classified as Family1 in this driver, so uses the CMD1_ prefix. +*/ +#define CDROM_STATUS_DOOR 0x80 +#define CDROM_STATUS_DISC_IN 0x40 +#define CDROM_STATUS_SPIN_UP 0x20 +#define CDROM_STATUS_ERROR 0x10 +#define CDROM_STATUS_DOUBLE_SPEED 0x02 +#define CDROM_STATUS_READY 0x01 + +// Status returned from device +#define STAT_READY 0x01 +#define STAT_PLAY 0x08 +#define STAT_ERROR 0x10 +#define STAT_DISK 0x40 +#define STAT_TRAY 0x80 // Seems Correct + +#define CMD1_PAUSERESUME 0x0D +#define CMD1_RESET 0x0a +#define CMD1_LOCK_CTL 0x0c +#define CMD1_TRAY_CTL 0x07 +#define CMD1_MULTISESS 0x8d +#define CMD1_SUBCHANINF 0x11 +#define CMD1_ABORT 0x08 +// #define CMD1_PATH_CHECK 0x??? +#define CMD1_SEEK 0x01 +#define CMD1_READ 0x10 +#define CMD1_SPINUP 0x02 +#define CMD1_SPINDOWN 0x06 +#define CMD1_READ_UPC 0x88 +// #define CMD1_PLAY 0x??? +#define CMD1_PLAY_MSF 0x0e +#define CMD1_PLAY_TI 0x0f +#define CMD1_STATUS 0x05 +#define CMD1_READ_ERR 0x82 +#define CMD1_READ_VER 0x83 +#define CMD1_SETMODE 0x09 +#define CMD1_GETMODE 0x84 +#define CMD1_CAPACITY 0x85 +#define CMD1_READSUBQ 0x87 +#define CMD1_DISKINFO 0x8b +#define CMD1_READTOC 0x8c +#define CMD1_PAU_RES 0x0d +#define CMD1_PACKET 0x8e +#define CMD1_SESSINFO 0x8d + +typedef struct mke_t { + bool present; + bool tray_open; + + uint8_t command_buffer[7]; + uint8_t command_buffer_pending; + + uint8_t medium_changed; + + uint8_t vol0, vol1, patch0, patch1; + uint8_t mode_select[5]; + + uint8_t media_selected; // temporary hack + + Fifo8 data_fifo; + Fifo8 info_fifo; + + cdrom_t * cdrom_dev; + + uint32_t sector_type; + uint32_t sector_flags; + + uint32_t unit_attention; + + uint8_t cdbuffer[624240 * 2]; + + uint32_t data_to_push; + + pc_timer_t timer; + + char ver[512]; + + uint8_t is_error; + uint8_t sense[8]; + + uint8_t temp_buf[65536]; +} mke_t; + +typedef struct mke_interface_t { + mke_t mke[4]; + + uint8_t is_sb; + + uint8_t drvsel; + uint8_t data_select; +} mke_interface_t; + +#ifdef ENABLE_MKE_LOG +int mke_do_log = ENABLE_MKE_LOG; + +static void +mke_log(const char *fmt, ...) +{ + va_list ap; + + if (mke_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define mke_log(fmt, ...) +#endif + +#define CHECK_READY() \ + { \ + if (!mke_pre_execution_check(mke)) \ + return; \ + } + +#define REPORT_IF_NOT_READY() \ + { \ + if (!mke_pre_execution_check(mke)) { \ + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); \ + } \ + } + +#define CHECK_READY_READ() \ + { \ + if (!mke_pre_execution_check(mke)) { \ + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); \ + return; \ + } \ + } + +static void +mke_update_sense(mke_t *mke, uint8_t error) +{ + /* FreeBSD calls this addrval, but what is it? */ + mke->sense[0] = 0x00; + mke->sense[1] = mke->command_buffer[0]; + mke->sense[2] = error; + + mke->is_error = 1; +} + +static void +mke_cdrom_insert(void *priv) +{ + mke_t *dev = (mke_t *) priv; + + if ((dev == NULL) || (dev->cdrom_dev == NULL)) + return; + + if (dev->cdrom_dev->ops == NULL) { + dev->medium_changed = 0; + dev->cdrom_dev->cd_status = CD_STATUS_EMPTY; + if (timer_is_enabled(&dev->timer)) { + timer_disable(&dev->timer); + dev->data_to_push = 0; + } + mke_log("Media removal\n"); + } else if (dev->cdrom_dev->cd_status & CD_STATUS_TRANSITION) { + dev->medium_changed = 1; + /* Turn off the medium changed status. */ + dev->cdrom_dev->cd_status &= ~CD_STATUS_TRANSITION; + mke_log("Media insert\n"); + } else { + dev->medium_changed = 0; + dev->cdrom_dev->cd_status |= CD_STATUS_TRANSITION; + mke_log("Media transition\n"); + } +} + +static int +mke_pre_execution_check(mke_t *mke) +{ + int ready = 1; + + if ((mke->cdrom_dev->cd_status == CD_STATUS_PLAYING) || + (mke->cdrom_dev->cd_status == CD_STATUS_PAUSED)) { + ready = 1; + goto skip_ready_check; + } + + if (mke->cdrom_dev->cd_status & CD_STATUS_TRANSITION) { + if (mke->command_buffer[0] == 0x82) + ready = 0; + else { + mke_cdrom_insert(mke); + + ready = ((mke->cdrom_dev->cd_status != CD_STATUS_EMPTY) && (mke->cdrom_dev->cd_status != CD_STATUS_DVD_REJECTED)); + } + } else + ready = ((mke->cdrom_dev->cd_status != CD_STATUS_EMPTY) && (mke->cdrom_dev->cd_status != CD_STATUS_DVD_REJECTED)); + +skip_ready_check: + /* + If the drive is not ready, there is no reason to keep the + UNIT ATTENTION condition present, as we only use it to mark + disc changes. + */ + if (!ready && (mke->medium_changed > 0)) + mke->medium_changed = 0; + + /* + If the UNIT ATTENTION condition is set and the command does not allow + execution under it, error out and report the condition. + */ + if (mke->medium_changed == 1) { + /* + Only increment the unit attention phase if the command can + not pass through it. + */ + mke_log("Unit attention now 2\n"); + mke->medium_changed++; + mke_update_sense(mke, 0x11); \ + return 0; + } else if (mke->medium_changed == 2) { + if (mke->command_buffer[0] != 0x82) { + mke_log("Unit attention now 0\n"); + mke->medium_changed = 0; + } + } + + /* + Unless the command is REQUEST SENSE, clear the sense. This will *NOT* clear + the UNIT ATTENTION condition if it's set. + */ + if (mke->command_buffer[0] != 0x82) { + memset(mke->sense, 0x00, 8); + mke->is_error = 0; + } + + if (!ready && (mke->command_buffer[0] != 0x05)) { + mke_log("Not ready (%02X)\n", mke->command_buffer[0]); + mke_update_sense(mke, 0x03); + return 0; + } + + return 1; +} + +uint8_t +mke_cdrom_status(cdrom_t *dev, mke_t *mke) +{ + uint8_t status = 0; + /* + This bit seems to always be set? + Bit 4 never set? + */ + status |= 2; + if (dev->cd_status == CD_STATUS_PLAYING) + status |= STAT_PLAY; + if (dev->cd_status == CD_STATUS_PAUSED) + status |= STAT_PLAY; + if (mke->is_error) + status |= 0x10; + /* Always set? */ + status |= 0x20; + status |= STAT_TRAY; + if (mke->cdrom_dev->cd_status != CD_STATUS_EMPTY) { + status |= STAT_DISK; + status |= STAT_READY; + } + + return status; +} + +void +mke_get_subq(mke_t *mke, uint8_t *b) +{ + cdrom_t *dev = mke->cdrom_dev; + + cdrom_get_current_subchannel_sony(dev, mke->temp_buf, 1); + /* ? */ + b[0] = 0x80; + b[1] = ((mke->temp_buf[0] & 0xf) << 4) | ((mke->temp_buf[0] & 0xf0) >> 4); + b[2] = mke->temp_buf[1]; + b[3] = mke->temp_buf[2]; + b[4] = mke->temp_buf[6]; + b[5] = mke->temp_buf[7]; + b[6] = mke->temp_buf[8]; + b[7] = mke->temp_buf[3]; + b[8] = mke->temp_buf[4]; + b[9] = mke->temp_buf[5]; + /* ? */ + b[10] = 0; + mke_log("mke_get_subq: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10]); +} + +/* Lifted from FreeBSD */ +static void +blk_to_msf(int blk, unsigned char *msf) +{ + blk = blk + 150; /* 2 seconds skip required to + reach ISO data */ + msf[0] = blk / 4500; + blk = blk % 4500; + msf[1] = blk / 75; + msf[2] = blk % 75; + + return; +} + +uint8_t +mke_read_toc(mke_t *mke, unsigned char *b, uint8_t track) { + cdrom_t *dev = mke->cdrom_dev; +#if 0 + track_info_t ti; + int last_track; +#endif + const raw_track_info_t *trti = (raw_track_info_t *) mke->temp_buf; + int num = 0; + int ret = 0; + + dev->ops->get_raw_track_info(dev->local, &num, mke->temp_buf); + + if (num > 0) { + if (track == 0xaa) + track = 0xa2; + + int trk = - 1; + + for (int i = (num - 1); i >= 0; i--) { + if (trti[i].point == track) { + trk = i; + break; + } + } + + if (trk != -1) { + b[0] = 0; + b[1] = trti[trk].adr_ctl; + b[2] = (trti[trk].point == 0xa2) ? 0xaa : trti[trk].point; + b[3] = 0; + b[4] = trti[trk].pm; + b[5] = trti[trk].ps; + b[6] = trti[trk].pf; + b[7] = 0; + + ret = 1; + } + + mke_log("mke_read_toc: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + } + + return ret; +} + + +uint8_t +mke_disc_info(mke_t *mke, unsigned char *b) +{ + cdrom_t *dev = mke->cdrom_dev; + uint8_t disc_type_buf[34]; + int first_track; + int last_track; + + cdrom_read_toc(dev, mke->temp_buf, CD_TOC_NORMAL, 0, 2 << 8, 65536); + cdrom_read_disc_information(dev, disc_type_buf); + first_track = mke->temp_buf[2]; + last_track = mke->temp_buf[3]; + + b[0] = disc_type_buf[8]; + b[1] = first_track; + b[2] = last_track; + b[3] = 0; + b[4] = 0; + b[5] = 0; + blk_to_msf(dev->cdrom_capacity, &b[3]); + mke_log("mke_disc_info: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + b[0], b[1], b[2], b[3], b[4], b[5]); + return 1; +} + +uint8_t +mke_disc_capacity(cdrom_t *dev, unsigned char *b) +{ + b[0] = 0x00; + b[1] = 0x00; + b[2] = 0x00; + b[3] = 0x08; + b[4] = 0x00; + + blk_to_msf(dev->cdrom_capacity, &b[0]); + mke_log("mke_disc_capacity: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + b[0], b[1], b[2], b[3], b[4]); + return 1; +} + +void +mke_read_multisess(mke_t *mke) +{ + cdrom_t *dev = mke->cdrom_dev; + uint8_t *b = (uint8_t *) &(mke->temp_buf[32768]); + const raw_track_info_t *trti = (raw_track_info_t *) mke->temp_buf; + int num = 0; + int first_sess = 0; + int last_sess = 0; + + dev->ops->get_raw_track_info(dev->local, &num, mke->temp_buf); + + if (num > 0) { + int trk = - 1; + + for (int i = 0; i < num; i++) { + if (trti[i].point == 0xa2) { + first_sess = trti[i].session; + break; + } + } + + for (int i = (num - 1); i >= 0; i--) { + if (trti[i].point == 0xa2) { + last_sess = trti[i].session; + break; + } + } + + for (int i = 0; i < num; i++) { + if ((trti[i].point >= 1) && (trti[i].point >= 99) && + (trti[i].session == last_sess)) { + trk = i; + break; + } + } + + if ((first_sess > 0) && (last_sess < 0) && (trk != -1)) { + b[0] = (first_sess == last_sess) ? 0x00 : 0x80; + b[1] = trti[trk].pm; + b[2] = trti[trk].ps; + b[3] = trti[trk].pf; + b[4] = 0; + b[5] = 0; + } + + fifo8_push_all(&mke->info_fifo, b, 6); + + mke_log("mke_read_multisess: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + b[0], b[1], b[2], b[3], b[4], b[5]); + } else { + memset(b, 0x00, 6); + fifo8_push_all(&mke->info_fifo, b, 6); + } +} + +static void +mke_reset(mke_t *mke) +{ + cdrom_stop(mke->cdrom_dev); + timer_disable(&mke->timer); + mke->sector_type = 0x08 | (1 << 4); + mke->sector_flags = 0x10; + memset(mke->mode_select, 0, 5); + mke->mode_select[2] = 0x08; + mke->patch0 = 0x01; + mke->patch1 = 0x02; + mke->vol0 = 255; + mke->vol1 = 255; + mke->cdrom_dev->sector_size = 2048; +} + +void +mke_command_callback(void *priv) +{ + mke_t *mke = (mke_t *) priv; + + switch (mke->command_buffer[0]) { + case CMD1_SEEK: { + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + } + case CMD1_READ: { + fifo8_push_all(&mke->data_fifo, mke->cdbuffer, mke->data_to_push); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + mke->data_to_push = 0; + ui_sb_update_icon(SB_CDROM | mke->cdrom_dev->id, 0); + break; + } + } +} + +void +mke_command(mke_t *mke, uint8_t value) +{ + uint16_t i; + /* This is wasteful handling of buffers for compatibility, but will optimize later. */ + uint8_t x[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int old_cd_status; + + if (mke->command_buffer_pending) { + mke->command_buffer[6 - mke->command_buffer_pending + 1] = value; + mke->command_buffer_pending--; + } + + if (mke->command_buffer[0] == CMD1_ABORT) { + mke_log("CMD_ABORT\n"); + fifo8_reset(&mke->info_fifo); + fifo8_reset(&mke->data_fifo); + timer_disable(&mke->timer); + mke->command_buffer[0] = 0; + mke->command_buffer_pending = 7; + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + } + + if (!mke->command_buffer_pending && mke->command_buffer[0]) { + mke->command_buffer_pending = 7; + mke_log("mke_command: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", + mke->command_buffer[0], mke->command_buffer[1], + mke->command_buffer[2], mke->command_buffer[3], + mke->command_buffer[4], mke->command_buffer[5], + mke->command_buffer[6]); + switch (mke->command_buffer[0]) { + case 0x03: + fifo8_reset(&mke->info_fifo); + cdrom_stop(mke->cdrom_dev); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case 0x06: + fifo8_reset(&mke->info_fifo); + cdrom_stop(mke->cdrom_dev); + cdrom_eject(mke->cdrom_dev->id); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case 0x07: + fifo8_reset(&mke->info_fifo); + cdrom_reload(mke->cdrom_dev->id); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_RESET: + mke_reset(mke); + break; + case CMD1_READ: { + uint32_t count = mke->command_buffer[6]; + uint8_t *buf = mke->cdbuffer; + int res = 0; + uint64_t lba = MSFtoLBA(mke->command_buffer[1], mke->command_buffer[2], + mke->command_buffer[3]) - 150; + int len __attribute__((unused)) = 0; + + CHECK_READY_READ(); + mke->data_to_push = 0; + + while (count) { + if ((res = cdrom_readsector_raw(mke->cdrom_dev, buf, lba, 0, + mke->sector_type, mke->sector_flags, &len, 0)) > 0) { + lba++; + buf += mke->cdrom_dev->sector_size; + mke->data_to_push += mke->cdrom_dev->sector_size; + } else { + mke_update_sense(mke, (res == 0) ? 0x10 : 0x05); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + } + count--; + } + if (count != 0) { + fifo8_reset(&mke->data_fifo); + mke->data_to_push = 0; + } else { + ui_sb_update_icon(SB_CDROM | mke->cdrom_dev->id, 1); + timer_on_auto(&mke->timer, (1000000.0 / (176400.0 * 2.)) * mke->data_to_push); + } + break; + } case CMD1_READSUBQ: + if (mke_pre_execution_check(mke)) { + mke_get_subq(mke, (uint8_t *) &x); + } + fifo8_reset(&mke->info_fifo); + fifo8_push_all(&mke->info_fifo, x, 11); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_SETMODE: + /* Returns 1 */ + fifo8_reset(&mke->info_fifo); + mke_log("CMD: SET MODE:"); + for (i = 0; i < 6; i++) { + mke_log("%02x ", mke->command_buffer[i + 1]); + } + mke_log("\n"); + switch (mke->command_buffer[1]) { + case 0: + switch (mke->command_buffer[2]) { + case 0x00: /* Cooked */ + mke->sector_type = 0x08 | (1 << 4); + mke->sector_flags = 0x10; + mke->cdrom_dev->sector_size = 2048; + break; + case 0x81: /* XA */ + case 0x01: /* User */ { + uint32_t sector_size = (mke->command_buffer[3] << 8) | + mke->command_buffer[4]; + + if (!sector_size) { + mke_update_sense(mke, 0x0e); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + return; + } else { + switch (sector_size) { + case 2048: + mke->sector_type = 0x08 | (1 << 4); + mke->sector_flags = 0x10; + mke->cdrom_dev->sector_size = 2048; + break; + case 2052: + mke->sector_type = 0x18; + mke->sector_flags = 0x30; + mke->cdrom_dev->sector_size = 2052; + break; + case 2324: + mke->sector_type = 0x1b; + mke->sector_flags = 0x18; + mke->cdrom_dev->sector_size = 2324; + break; + case 2336: + mke->sector_type = 0x1c; + mke->sector_flags = 0x58; + mke->cdrom_dev->sector_size = 2336; + break; + case 2340: + mke->sector_type = 0x18; + mke->sector_flags = 0x78; + mke->cdrom_dev->sector_size = 2340; + break; + case 2352: + mke->sector_type = 0x00; + mke->sector_flags = 0xf8; + mke->cdrom_dev->sector_size = 2352; + break; + default: + mke_update_sense(mke, 0x0e); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + return; + } + } + break; + } case 0x82: /* DA */ + mke->sector_type = 0x00; + mke->sector_flags = 0xf8; + mke->cdrom_dev->sector_size = 2352; + break; + default: + mke_update_sense(mke, 0x0e); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + return; + } + + memcpy(mke->mode_select, &mke->command_buffer[2], 5); + break; + case 5: + mke->vol0 = mke->command_buffer[4]; + mke->vol1 = mke->command_buffer[6]; + mke->patch0 = mke->command_buffer[3]; + mke->patch1 = mke->command_buffer[5]; + break; + } + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_GETMODE: + /* 6 */ + mke_log("GET MODE\n"); + if (mke->command_buffer[1] == 5) { + uint8_t volsettings[5] = { 0, mke->patch0, mke->vol0, mke->patch1, mke->vol1 }; + fifo8_push_all(&mke->info_fifo, volsettings, 5); + } else + fifo8_push_all(&mke->info_fifo, mke->mode_select, 5); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_PAUSERESUME: + CHECK_READY_READ(); + cdrom_audio_pause_resume(mke->cdrom_dev, mke->command_buffer[1] >> 7); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_CAPACITY: + /* 6 */ + mke_log("DISK CAPACITY\n"); + if (mke_pre_execution_check(mke)) + mke_disc_capacity(mke->cdrom_dev, (uint8_t *) &x); + fifo8_push_all(&mke->info_fifo, x, 5); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_DISKINFO: + /* 7 */ + mke_log("DISK INFO\n"); + fifo8_reset(&mke->info_fifo); + if (mke_pre_execution_check(mke)) + mke_disc_info(mke, (uint8_t *) &x); + fifo8_push_all(&mke->info_fifo, x, 6); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_READTOC: + fifo8_reset(&mke->info_fifo); + if (mke_pre_execution_check(mke)) + mke_read_toc(mke, (uint8_t *) &x, mke->command_buffer[2]); + fifo8_push_all(&mke->info_fifo, x, 8); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_PLAY_TI: + /* Index is ignored for now. */ + fifo8_reset(&mke->info_fifo); + CHECK_READY_READ(); + if (!cdrom_audio_play(mke->cdrom_dev, mke->command_buffer[1], mke->command_buffer[3], 2)) + mke_update_sense(mke, 0x10); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_PLAY_MSF: + fifo8_reset(&mke->info_fifo); + CHECK_READY_READ(); + mke_log("PLAY MSF:"); + for (i = 0; i < 6; i++) { + mke_log("%02x ", mke->command_buffer[i + 1]); + } + mke_log("\n"); + { + int msf = 1; + int pos = (mke->command_buffer[1] << 16) | (mke->command_buffer[2] << 8) | + mke->command_buffer[3]; + int len = (mke->command_buffer[4] << 16) | (mke->command_buffer[5] << 8) | + mke->command_buffer[6]; + if (!cdrom_audio_play(mke->cdrom_dev, pos, len, msf)){ + mke_update_sense(mke, 0x10); + } + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + } + break; + case CMD1_SEEK: + old_cd_status = mke->cdrom_dev->cd_status; + fifo8_reset(&mke->info_fifo); + CHECK_READY_READ(); + /* TODO: DOES THIS IMPACT CURRENT PLAY LENGTH? */ + mke_log("SEEK MSF:"); + for (i = 0; i < 6; i++) { + mke_log("%02x ", mke->command_buffer[i + 1]); + } + + cdrom_stop(mke->cdrom_dev); + /* Note for self: Panasonic/MKE drives send seek commands in MSF format. */ + cdrom_seek(mke->cdrom_dev, MSFtoLBA(mke->command_buffer[1], mke->command_buffer[2], + mke->command_buffer[3]) - 150, 0); + if ((old_cd_status == CD_STATUS_PLAYING) || (old_cd_status == CD_STATUS_PAUSED)) { + cdrom_audio_play(mke->cdrom_dev, mke->cdrom_dev->seek_pos, -1, 0); + cdrom_audio_pause_resume(mke->cdrom_dev, old_cd_status == CD_STATUS_PLAYING); + } + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_SESSINFO: + fifo8_reset(&mke->info_fifo); + mke_log("CMD: READ SESSION INFO\n"); + if (mke_pre_execution_check(mke)) + mke_read_multisess(mke); + else + fifo8_push_all(&mke->info_fifo, x, 6); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_READ_UPC: + fifo8_reset(&mke->info_fifo); + mke_log("CMD: READ UPC\n"); + uint8_t upc[8] = { [0] = 80 }; + fifo8_push_all(&mke->info_fifo, upc, 8); + REPORT_IF_NOT_READY(); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_READ_ERR: + fifo8_reset(&mke->info_fifo); + mke_log("CMD: READ ERR\n"); + mke_log("ERROR: %02X %02X %02X %02X %02X %02X %02X %02X\n", + mke->sense[0], mke->sense[1], mke->sense[2], mke->sense[3], + mke->sense[4], mke->sense[5], mke->sense[6], mke->sense[7]); + { + uint8_t temp[8]; + memset(temp, mke->sense[2], 8); + fifo8_push_all(&mke->info_fifo, mke->sense, 8); + } + mke->is_error = 0; + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_READ_VER: + /* SB2CD Expects 12 bytes, but drive only returns 11. */ + fifo8_reset(&mke->info_fifo); + fifo8_push_all(&mke->info_fifo, (uint8_t *) mke->ver, 10); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + case CMD1_STATUS: + fifo8_reset(&mke->info_fifo); + CHECK_READY_READ(); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); + break; + default: + mke_log("MKE: Unknown Commnad [%02x]\n", mke->command_buffer[0]); + break; + } + } else if (!mke->command_buffer_pending) { + /* + We are done but not in a command. + Should we make sure it is a valid command here? + */ + mke->command_buffer[0] = value; + mke->command_buffer_pending = 6; + } +} + +void +mke_write(uint16_t port, uint8_t val, void *priv) +{ + mke_interface_t *mki = (mke_interface_t *) priv; + mke_t *mke = &(mki->mke[mki->drvsel & 0x03]); + uint8_t sb[8] = { 0x00, 0x02, 0x01, 0x03 }; + + mke_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, port, val); + + /* if (mke->present || ((port & 0x0003) == 0x0003)) */ switch (port & 0x0003) { + case 0: + if (mke->present) + mke_command(mke, val); + break; + case 1: + if (mki->is_sb) + mki->data_select = val; + break; + case 2: + if (mke->present) + mke_reset(mke); + break; + case 3: + if (mki->is_sb) + mki->drvsel = (val & 0xfc) | sb[val & 0x03]; + else + mki->drvsel = val; + break; + default: + break; + } +} + +uint8_t +mke_read(uint16_t port, void *priv) +{ + mke_interface_t *mki = (mke_interface_t *) priv; + mke_t *mke = &(mki->mke[mki->drvsel & 0x03]); + uint8_t ret = 0x00; + + if (mke->present) switch (port & 0x0003) { + case 0: + /* Info */ + if (mki->is_sb && mki->data_select) + ret = fifo8_num_used(&mke->data_fifo) ? fifo8_pop(&mke->data_fifo) : 0x00; + else + ret = fifo8_num_used(&mke->info_fifo) ? fifo8_pop(&mke->info_fifo) : 0x00; + break; + case 1: + /* + Status: + - 1 = Status Change; + - 2 = Data Ready; + - 4 = Response Ready; + - 8 = Attention / Issue? + */ + ret = 0xff; + if (fifo8_num_used(&mke->data_fifo)) + /* Data FIFO */ + ret ^= 2; + if (fifo8_num_used(&mke->info_fifo)) + /* Status FIFO */ + ret ^= 4; + if (mke->is_error) + ret ^= 8; + break; + case 2: + /* Data */ + if (!mki->is_sb) + ret = fifo8_num_used(&mke->data_fifo) ? fifo8_pop(&mke->data_fifo) : 0x00; + break; + default: + mke_log("MKE Unknown Read Port: %04X\n", port); + ret = 0xff; + break; + } else if ((port & 0x0003) == 0x0003) + /* This is needed for the Windows 95 built-in driver to function correctly. */ + ret = 0xff; + + mke_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, port, ret); + + return ret; +} + +uint32_t +mke_get_volume(void *priv, int channel) +{ + mke_t *dev = (mke_t *) priv; + + return channel == 0 ? dev->vol0 : dev->vol1; +} + +uint32_t +mke_get_channel(void *priv, int channel) +{ + mke_t *dev = (mke_t *) priv; + + return channel == 0 ? dev->patch0 : dev->patch1; +} + +void +mke_close(void *priv) +{ + mke_interface_t *mki = (mke_interface_t *) calloc(1, sizeof(mke_interface_t)); + + for (uint8_t i = 0; i < 4; i++) { + mke_t *mke = &(mki->mke[i]); + + if (mke->present) { + timer_disable(&mke->timer); + + fifo8_destroy(&mke->data_fifo); + fifo8_destroy(&mke->info_fifo); + } + } + + free(mki); +} + +void * +mke_init(const device_t *info) +{ + mke_interface_t *mki = (mke_interface_t *) calloc(1, sizeof(mke_interface_t)); + int num = 0; + + for (uint8_t i = 0; i < CDROM_NUM; i++) { + if (cdrom[i].bus_type == CDROM_BUS_MKE) { + cdrom_t *dev = &cdrom[i]; + + mke_t *mke = &(mki->mke[dev->mke_channel]); + + mke->present = 1; + + memset(mke->ver, 0x00, 512); + cdrom_generate_name_mke(dev->type, mke->ver); + mke->ver[10] = 0x00; + + fifo8_create(&mke->info_fifo, 128); + fifo8_create(&mke->data_fifo, 624240 * 2); + fifo8_reset(&mke->info_fifo); + fifo8_reset(&mke->data_fifo); + mke->cdrom_dev = dev; + mke->command_buffer_pending = 7; + mke->sector_type = 0x08 | (1 << 4); + mke->sector_flags = 0x10; + mke->mode_select[2] = 0x08; + mke->patch0 = 0x01; + mke->patch1 = 0x02; + mke->vol0 = 255; + mke->vol1 = 255; + dev->sector_size = 2048; + + dev->priv = mke; + dev->insert = mke_cdrom_insert; + dev->get_volume = mke_get_volume; + dev->get_channel = mke_get_channel; + dev->cached_sector = -1; + + timer_add(&mke->timer, mke_command_callback, mke, 0); + + num++; + + if (num == 4) + break; + } + } + + mki->is_sb = info->local; + + uint16_t base = device_get_config_hex16("base"); + io_sethandler(base, 4, mke_read, NULL, NULL, mke_write, NULL, NULL, mki); + + return mki; +} + +static const device_config_t mke_config[] = { + // clang-format off + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x250, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "220H", .value = 0x220 }, + { .description = "230H", .value = 0x230 }, + { .description = "250H", .value = 0x250 }, + { .description = "260H", .value = 0x260 }, + { .description = "270H", .value = 0x270 }, + { .description = "290H", .value = 0x290 }, + { .description = "300H", .value = 0x300 }, + { .description = "310H", .value = 0x310 }, + { .description = "320H", .value = 0x320 }, + { .description = "330H", .value = 0x330 }, + { .description = "340H", .value = 0x340 }, + { NULL } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format off +}; + +const device_t mke_cdrom_device = { + .name = "Panasonic/MKE CD-ROM interface (Creative)", + .internal_name = "mkecd", + .flags = DEVICE_ISA, + .local = 1, + .init = mke_init, + .close = mke_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = mke_config +}; + +const device_t mke_cdrom_noncreative_device = { + .name = "Panasonic/MKE CD-ROM interface", + .internal_name = "mkecd_normal", + .flags = DEVICE_ISA, + .local = 0, + .init = mke_init, + .close = mke_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = mke_config +}; diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 6018dd045..d61b5c53d 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -17,7 +17,9 @@ add_library(chipset OBJECT 82c100.c + acc2036.c acc2168.c + cs8220.c cs8230.c ali1429.c ali1435.c @@ -39,12 +41,15 @@ add_library(chipset OBJECT intel_i450kx.c intel_sio.c intel_piix.c + isa486c.c ../ioapic.c neat.c + olivetti_eva.c opti283.c opti291.c opti391.c opti495.c + opti498.c opti499.c opti602.c opti822.c @@ -71,6 +76,7 @@ add_library(chipset OBJECT sis_5572_usb.c sis_5595_pmu.c sis_55xx.c + sl82c461.c via_vt82c49x.c via_vt82c505.c gc100.c @@ -83,7 +89,3 @@ add_library(chipset OBJECT vl82c480.c wd76c10.c ) - -if(OLIVETTI) - target_sources(chipset PRIVATE olivetti_eva.c) -endif() diff --git a/src/chipset/acc2036.c b/src/chipset/acc2036.c new file mode 100644 index 000000000..3984f82e0 --- /dev/null +++ b/src/chipset/acc2036.c @@ -0,0 +1,346 @@ +/* + * 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 ACC 2036 chipset. + * + * Authors: Miran Grca, + * + * Copyright 2025 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/mem.h> +#include <86box/port_92.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/chipset.h> + +typedef struct { + uint32_t virt; + uint32_t phys; + + mem_mapping_t mapping; +} ram_page_t; + +typedef struct { + uint8_t reg; + uint8_t regs[32]; + + ram_page_t ram_mid_pages[24]; + ram_page_t ems_pages[4]; +} acc2036_t; + +static uint8_t +acc2036_mem_read(uint32_t addr, void *priv) +{ + ram_page_t *dev = (ram_page_t *) priv; + uint8_t ret = 0xff; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + ret = ram[addr]; + + return ret; +} + +static uint16_t +acc2036_mem_readw(uint32_t addr, void *priv) +{ + ram_page_t *dev = (ram_page_t *) priv; + uint16_t ret = 0xffff; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + ret = *(uint16_t *) &(ram[addr]); + + return ret; +} + +static void +acc2036_mem_write(uint32_t addr, uint8_t val, void *priv) +{ + ram_page_t *dev = (ram_page_t *) priv; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + ram[addr] = val; +} + +static void +acc2036_mem_writew(uint32_t addr, uint16_t val, void *priv) +{ + ram_page_t *dev = (ram_page_t *) priv; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + *(uint16_t *) &(ram[addr]) = val; +} + +static void +acc2036_recalc(acc2036_t *dev) +{ + uint32_t ems_bases[4] = { 0x000c0000, 0x000c8000, 0x000d0000, 0x000e0000 }; + + int start_i = (ems_bases[dev->regs[0x0c] & 0x03] - 0x000a0000) >> 14; + int end_i = start_i + 3; + + for (int i = 0; i < 24; i++) { + ram_page_t *rp = &dev->ram_mid_pages[i]; + mem_mapping_disable(&rp->mapping); + } + + for (int i = 0; i < 4; i++) { + ram_page_t *ep = &dev->ems_pages[i]; + mem_mapping_disable(&ep->mapping); + } + + for (int i = 0; i < 24; i++) { + ram_page_t *rp = &dev->ram_mid_pages[i]; + + if ((dev->regs[0x03] & 0x08) && (i >= start_i) && (i <= end_i)) { + /* EMS */ + ram_page_t *ep = &dev->ems_pages[i - start_i]; + + mem_mapping_disable(&rp->mapping); + mem_mapping_set_addr(&ep->mapping, ep->virt, 0x000040000); + mem_mapping_set_exec(&ep->mapping, ram + ep->phys); + mem_set_mem_state_both(ep->virt, 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else { + int master_write; + int master_read; + int bit; + int ew_flag; + int er_flag; + int flags; + uint8_t val; + + mem_mapping_set_addr(&rp->mapping, rp->virt, 0x000040000); + mem_mapping_set_exec(&rp->mapping, ram + rp->phys); + + if ((i >= 8) && (i <= 15)) { + /* 0C0000-0DFFFF */ + master_write = dev->regs[0x02] & 0x08; + master_read = dev->regs[0x02] & 0x04; + bit = ((i - 8) >> 1); + val = dev->regs[0x0d] & (1 << bit); + if (i >= 12) { + ew_flag = (dev->regs[0x07] & 0x80) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL; + er_flag = (dev->regs[0x07] & 0x80) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL; + } else { + ew_flag = (dev->regs[0x07] & 0x40) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL; + er_flag = (dev->regs[0x07] & 0x40) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL; + } + flags = (val && master_write) ? MEM_WRITE_INTERNAL : ew_flag; + flags |= (val && master_read) ? MEM_READ_INTERNAL : er_flag; + mem_set_mem_state_both(rp->virt, 0x00004000, flags); + } else if (i > 15) { + /* 0E0000-0FFFFF */ + master_write = dev->regs[0x02] & 0x02; + master_read = dev->regs[0x02] & 0x01; + bit = ((i - 8) >> 2); + val = dev->regs[0x0c] & (1 << bit); + if (i >= 20) { + ew_flag = MEM_WRITE_EXTANY; + er_flag = MEM_READ_EXTANY; + } else { + ew_flag = (dev->regs[0x0c] & 0x10) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL; + er_flag = (dev->regs[0x0c] & 0x10) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL; + } + flags = (val && master_write) ? MEM_WRITE_INTERNAL : ew_flag; + flags |= (val && master_read) ? MEM_READ_INTERNAL : er_flag; + mem_set_mem_state_both(rp->virt, 0x00004000, flags); + } + } + } + + if (dev->regs[0x00] & 0x40) + mem_set_mem_state_both(0x00fe0000, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else + mem_set_mem_state_both(0x00fe0000, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + + for (int i = 0x01; i <= 0x06; i++) { + uint32_t base = 0x00fe0000 - (i * 0x00010000); + + if (dev->regs[i] & 0x40) + mem_set_mem_state_both(base, 0x00008000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else + mem_set_mem_state_both(base, 0x00008000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + + if (dev->regs[i] & 0x80) + mem_set_mem_state_both(base + 0x00008000, 0x00008000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else + mem_set_mem_state_both(base + 0x00008000, 0x00008000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + + mem_remap_top(0); + if (dev->regs[0x03] & 0x10) { + if (dev->regs[0x02] & 0x0c) + mem_remap_top(128); + else if (dev->regs[0x02] & 0x03) + mem_remap_top(256); + else + mem_remap_top(384); + } + + flushmmucache_nopc(); +} + +static uint8_t +acc2036_in(uint16_t port, void *priv) { + acc2036_t *dev = (acc2036_t *) priv; + uint8_t reg = dev->reg - 0x20; + uint8_t ret = 0xff; + + if (port & 0x0001) switch (dev->reg) { + default: + break; + case 0x20 ... 0x2e: + case 0x31 ... 0x3f: + ret = dev->regs[reg]; + break; + } else + ret = dev->reg; + + return ret; +} + +static void +acc2036_out(uint16_t port, uint8_t val, void *priv) { + acc2036_t *dev = (acc2036_t *) priv; + uint8_t reg = dev->reg - 0x20; + + if (port & 0x0001) switch (dev->reg) { + default: + break; + case 0x20 ... 0x23: + dev->regs[reg] = val; + acc2036_recalc(dev); + break; + case 0x24 ... 0x2b: + dev->regs[reg] = val; + dev->ems_pages[(reg - 0x04) >> 1].phys = ((dev->regs[reg & 0xfe] & 0x1f) << 19) | + ((dev->regs[reg | 0x01] & 0x1f) << 14); + acc2036_recalc(dev); + break; + case 0x2c: case 0x2d: + dev->regs[reg] = val; + acc2036_recalc(dev); + break; + case 0x2e: + dev->regs[reg] = val | 0x10; + break; + case 0x31: + dev->regs[reg] = val; + mem_a20_alt = (val & 0x01); + mem_a20_recalc(); + flushmmucache(); + if (val & 0x02) { + softresetx86(); /* Pulse reset! */ + cpu_set_edx(); + flushmmucache(); + } + break; + case 0x32 ... 0x3f: + dev->regs[reg] = val; + break; + } else + dev->reg = val; +} + +static void +acc2036_close(void *priv) +{ + acc2036_t *dev = (acc2036_t *) priv; + + free(dev); +} + +static void * +acc2036_init(UNUSED(const device_t *info)) +{ + acc2036_t *dev = (acc2036_t *) calloc(1, sizeof(acc2036_t)); + + for (int i = 0; i < 24; i++) { + ram_page_t *rp = &dev->ram_mid_pages[i]; + + rp->virt = 0x000a0000 + (i << 14); + rp->phys = 0x000a0000 + (i << 14); + mem_mapping_add(&rp->mapping, rp->virt, 0x00004000, + acc2036_mem_read, acc2036_mem_readw, NULL, + acc2036_mem_write, acc2036_mem_writew, NULL, + ram + rp->phys, MEM_MAPPING_INTERNAL, rp); + } + + for (int i = 0; i < 4; i++) { + ram_page_t *ep = &dev->ems_pages[i]; + + ep->virt = 0x000d0000 + (i << 14); + ep->phys = 0x00000000 + (i << 14); + mem_mapping_add(&ep->mapping, ep->virt, 0x00004000, + acc2036_mem_read, acc2036_mem_readw, NULL, + acc2036_mem_write, acc2036_mem_writew, NULL, + ram + ep->phys, MEM_MAPPING_INTERNAL, ep); + mem_mapping_disable(&ep->mapping); + } + + mem_mapping_disable(&ram_mid_mapping); + + dev->regs[0x00] = 0x02; + dev->regs[0x0e] = 0x10; + dev->regs[0x11] = 0x01; + dev->regs[0x13] = 0x40; + dev->regs[0x15] = 0x40; + dev->regs[0x17] = 0x40; + dev->regs[0x19] = 0x40; + dev->regs[0x1b] = 0x40; + dev->regs[0x1c] = 0x22; + dev->regs[0x1d] = 0xc4; + dev->regs[0x1f] = 0x30; + acc2036_recalc(dev); + + mem_a20_alt = 0x01; + mem_a20_recalc(); + flushmmucache(); + + io_sethandler(0x00f2, 0x0002, + acc2036_in, NULL, NULL, acc2036_out, NULL, NULL, dev); + + device_add(&port_92_device); + + return dev; +} + +const device_t acc2036_device = { + .name = "ACC 2036", + .internal_name = "acc2036", + .flags = 0, + .local = 0, + .init = acc2036_init, + .close = acc2036_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/ali1409.c b/src/chipset/ali1409.c index 5009a6505..619843cda 100644 --- a/src/chipset/ali1409.c +++ b/src/chipset/ali1409.c @@ -61,91 +61,238 @@ ali1409_log(const char *fmt, ...) #endif typedef struct ali_1409_t { - uint8_t is_g; uint8_t index; uint8_t cfg_locked; - uint8_t reg_57h; uint8_t regs[256]; + uint8_t shadow[4]; uint8_t last_reg; } ali1409_t; +/* + This here is because from the two BIOS'es I used to reverse engineer this, + it is unclear which of the two interpretations of the shadow RAM register + operation is correct. + The 16 kB interpretation appears to work fine right now but it may be wrong, + so I left the 32 kB interpretation in as well. + */ +#ifdef INTERPRETATION_32KB +#define SHADOW_SIZE 0x00008000 +#else +#define SHADOW_SIZE 0x00004000 +#endif + +static void +ali1409_shadow_recalc(ali1409_t *dev) +{ + uint32_t base = 0x000c0000; + + for (uint8_t i = 0; i < 4; i++) { + uint8_t reg = 0x08 + i; + +#ifdef INTERPRETATION_32KB + for (uint8_t j = 0; j < 4; j += 2) { + uint8_t mask = (0x03 << j); +#else + for (uint8_t j = 0; j < 4; j++) { + uint8_t mask = (0x01 << j); +#endif + uint8_t r_on = dev->regs[reg] & 0x10; + uint8_t w_on = dev->regs[reg] & 0x20; + uint8_t val = dev->regs[reg] & mask; + uint8_t xor = (dev->shadow[i] ^ dev->regs[reg]) & (mask | 0x30); + int read = r_on ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + int write = w_on ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + + if (xor) { +#ifdef INTERPRETATION_32KB + switch (val >> j) { + case 0x00: + mem_set_mem_state_both(base, SHADOW_SIZE, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + break; + case 0x01: + mem_set_mem_state_both(base, SHADOW_SIZE, MEM_READ_EXTANY | write); + break; + case 0x02: + mem_set_mem_state_both(base, SHADOW_SIZE, read | write); + break; + case 0x03: + mem_set_mem_state_both(base, SHADOW_SIZE, read | MEM_WRITE_EXTANY); + break; + } +#else + switch (val >> j) { + case 0x00: + mem_set_mem_state_both(base, SHADOW_SIZE, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + break; + case 0x01: + mem_set_mem_state_both(base, SHADOW_SIZE, read | write); + break; + } +#endif + } + + base += SHADOW_SIZE; + } + + dev->shadow[i] = dev->regs[reg]; + } + + flushmmucache_nopc(); +} static void ali1409_write(uint16_t addr, uint8_t val, void *priv) { ali1409_t *dev = (ali1409_t *) priv; - ali1409_log ("INPUT:addr %02x ,Value %02x \n" , addr , val); + ali1409_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, addr, val); - if (addr & 1) { - if (dev->cfg_locked) { - if (dev->last_reg == 0x14 && val == 0x09) - dev->cfg_locked = 0; + if (addr & 0x0001) { + if (dev->cfg_locked) { + if ((dev->last_reg == 0x14) && (val == 0x09)) + dev->cfg_locked = 0; - dev->last_reg = val; - return; - } + dev->last_reg = val; + return; + } - if (dev->index == 0xff && val == 0xff) - dev->cfg_locked = 1; - else { - ali1409_log("Write reg %02x %02x %08x\n", dev->index, val, cs); - dev->regs[dev->index] = val; + /* It appears writing anything at all to register 0xFF locks it again. */ + if (dev->index == 0xff) + dev->cfg_locked = 1; + else if (dev->index < 0x44) { + ali1409_log("[%04X:%08X] [W] Register %02X = %02X\n", CS, cpu_state.pc, dev->index, val); - switch (dev->index) { - case 0xa: - switch ((val >> 4) & 3) { - case 0: - mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1: - mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2: - mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 3: - mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } + if (dev->index < 0x10) { + dev->regs[dev->index] = val; + + /* + There are still a lot of unknown here, but unfortunately, this is + as far as I have been able to come with two BIOS'es that are + available (the Acer 100T and an AMI Color dated 07/07/91). + */ + switch (dev->index) { + case 0x02: + /* + - Bit 7: The RAS address hold time: + - 0: 1/2 T; + - 1: 1 T. + - Bits 6-4: The RAS precharge time: + - 0, 0, 0: 1.5 T; + - 0, 0, 1: 2 T; + - 0, 1, 0: 2.5 T; + - 0, 1, 1: 3 T; + - 1, 0, 0: 3.5 T; + - 1, 0, 1: 4 T; + - 1, 1, 0: Reserved; + - 1, 1, 1: Reserved. + - Bit 3: Early miss cycle: + - 0: Disabled; + - 1: Enabled. + */ + break; + case 0x03: + /* + - Bit 6: CAS pulse for read cycle: + - 0: 1 T; + - 1: 1.5 T or 2 T. + I can not get the 2.5 T or 3 T setting to apply so + I have no idea what bit governs that. + - Bits 5, 4: CAS pulse for write cycle: + - 0, 0: 0.5 T or 1 T; + - 0, 1: 1.5 T or 2 T; + - 1, 0: 2.5 T or 3 T; + - 1, 1: Reserved. + - Bit 3: CAS active for read cycle: + - 0: Disabled; + - 1: Enabled. + - Bit 2: CAS active for write cycle: + - 0: Disabled; + - 1: Enabled. + */ + break; + case 0x06: + /* + - Bits 6-4: Clock divider: + - 0, 0, 0: / 2; + - 0, 0, 1: / 4; + - 0, 1, 0: / 8; + - 0, 1, 1: Reserved; + - 1, 0, 0: / 3; + - 1, 0, 1: / 6; + - 1, 1, 0: / 5; + - 1, 1, 1: / 10. + */ + switch ((val >> 4) & 7) { + default: + case 3: /* Reserved */ + cpu_set_isa_speed(7159091); break; - case 0xb: - switch ((val >> 4) & 3) { - case 0: - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - break; - case 1: - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); - break; - case 2: - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTANY| MEM_WRITE_INTERNAL); - break; - case 3: - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } + + case 0: + cpu_set_isa_speed(cpu_busspeed / 2); + break; + + case 1: + cpu_set_isa_speed(cpu_busspeed / 4); + break; + + case 2: + cpu_set_isa_speed(cpu_busspeed / 8); + break; + + case 4: + cpu_set_isa_speed(cpu_busspeed / 3); + break; + + case 5: + cpu_set_isa_speed(cpu_busspeed / 6); + break; + + case 6: + cpu_set_isa_speed(cpu_busspeed / 5); + break; + + case 7: + cpu_set_isa_speed(cpu_busspeed / 10); break; } + break; + case 0x08 ... 0x0b: + ali1409_shadow_recalc(dev); + break; + case 0x0c: + /* + This appears to be turbo in bit 4 (1 = on, 0 = off), + and bus speed in the rest of the bits. + */ + break; + case 0x0d: + cpu_cache_ext_enabled = !!(val & 0x08); + cpu_update_waitstates(); + break; } - } else - dev->index = val; + } + } + } else + dev->index = val; } static uint8_t ali1409_read(uint16_t addr, void *priv) { - ali1409_log ("reading at %02X\n",addr); const ali1409_t *dev = (ali1409_t *) priv; uint8_t ret = 0xff; if (dev->cfg_locked) ret = 0xff; - if (addr & 1) { - if ((dev->index >= 0xc0 || dev->index == 0x20) && cpu_iscyrix) - ret = 0xff; + else if (addr & 0x0001) { + if (dev->index < 0x44) ret = dev->regs[dev->index]; - } else - ret = dev->index; + } else + ret = dev->index; + + ali1409_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + return ret; } @@ -166,17 +313,16 @@ ali1409_init(UNUSED(const device_t *info)) dev->cfg_locked = 1; - /* M1409 Ports: - 22h Index Port - 23h Data Port - */ - - ali1409_log ("Bus speed: %i", cpu_busspeed); - + ali1409_log("Bus speed: %i\n", cpu_busspeed); io_sethandler(0x0022, 0x0002, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev); - io_sethandler(0x037f, 0x0001, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev); - io_sethandler(0x03f3, 0x0001, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev); + + dev->regs[0x0f] = 0x08; + + cpu_set_isa_speed(7159091); + + cpu_cache_ext_enabled = 0; + cpu_update_waitstates(); return dev; } diff --git a/src/chipset/cs8220.c b/src/chipset/cs8220.c new file mode 100644 index 000000000..4c08ecef5 --- /dev/null +++ b/src/chipset/cs8220.c @@ -0,0 +1,289 @@ +/* + * 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 C&T CS8220 ("PC/AT") chipset. + * + * Authors: Miran Grca, + * + * Copyright 2025 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/mem.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/chipset.h> + +typedef struct { + uint32_t virt; + uint32_t phys; + + uint32_t size; + + mem_mapping_t mapping; +} ram_bank_t; + +typedef struct { + uint8_t regs[3]; + + ram_bank_t ram_banks[3]; +} cs8220_t; + +static uint8_t +cs8220_mem_read(uint32_t addr, void *priv) +{ + ram_bank_t *dev = (ram_bank_t *) priv; + uint8_t ret = 0xff; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + ret = ram[addr]; + + return ret; +} + +static uint16_t +cs8220_mem_readw(uint32_t addr, void *priv) +{ + ram_bank_t *dev = (ram_bank_t *) priv; + uint16_t ret = 0xffff; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + ret = *(uint16_t *) &(ram[addr]); + + return ret; +} + +static void +cs8220_mem_write(uint32_t addr, uint8_t val, void *priv) +{ + ram_bank_t *dev = (ram_bank_t *) priv; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + ram[addr] = val; +} + +static void +cs8220_mem_writew(uint32_t addr, uint16_t val, void *priv) +{ + ram_bank_t *dev = (ram_bank_t *) priv; + + addr = (addr - dev->virt) + dev->phys; + + if (addr < (mem_size << 10)) + *(uint16_t *) &(ram[addr]) = val; +} + +static uint8_t +cs8220_in(uint16_t port, void *priv) { + cs8220_t *dev = (cs8220_t *) priv; + uint8_t ret = 0xff; + + switch (port) { + case 0x00a4 ... 0x00a5: + ret = dev->regs[port & 0x0001]; + break; + case 0x00ab: + ret = dev->regs[2]; + break; + } + + return ret; +} + +static void +cs8220_out(uint16_t port, uint8_t val, void *priv) { + cs8220_t *dev = (cs8220_t *) priv; + + switch (port) { + case 0x00a4: + dev->regs[0] = val; + mem_a20_alt = val & 0x40; + mem_a20_recalc(); + break; + case 0x00a5: + dev->regs[1] = val; + if (val & 0x01) { + mem_mapping_set_addr(&dev->ram_banks[0].mapping, 0, 0x000040000); + mem_mapping_disable(&dev->ram_banks[1].mapping); + mem_mapping_disable(&dev->ram_banks[2].mapping); + } else { + mem_mapping_set_addr(&dev->ram_banks[0].mapping, 0, dev->ram_banks[0].size); + mem_mapping_enable(&dev->ram_banks[1].mapping); + mem_mapping_enable(&dev->ram_banks[2].mapping); + } + break; + case 0x00ab: + dev->regs[2] = val; + break; + } +} + +static void +cs8220_close(void *priv) +{ + cs8220_t *dev = (cs8220_t *) priv; + + free(dev); +} + +static void * +cs8220_init(UNUSED(const device_t *info)) +{ + cs8220_t *dev = (cs8220_t *) calloc(1, sizeof(cs8220_t)); + + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); + + /* + Dell System 200: 640 kB soldered on-board, any other RAM is expansion. + */ + if (!strcmp(machine_get_internal_name(), "dells200")) switch (mem_size) { + default: + dev->ram_banks[2].virt = 0x00100000; + dev->ram_banks[2].phys = 0x000a0000; + dev->ram_banks[2].size = (mem_size << 10) - 0x000a0000; + fallthrough; + case 640: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00080000; + dev->ram_banks[1].virt = 0x00080000; + dev->ram_banks[1].phys = 0x00080000; + dev->ram_banks[1].size = 0x00020000; + break; + /* + We are limited to steps of equal size, so we have to simulate some + memory expansions to work around the chipset's limits. + */ + } else switch (mem_size) { + case 256: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00020000; + dev->ram_banks[1].virt = 0x00020000; + dev->ram_banks[1].phys = 0x00020000; + dev->ram_banks[1].size = 0x00020000; + break; + case 384: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00020000; + /* Pretend there's a 128k expansion. */ + dev->ram_banks[2].virt = 0x00020000; + dev->ram_banks[2].phys = 0x00020000; + dev->ram_banks[2].size = 0x00040000; + break; + case 512: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00080000; + break; + default: + dev->ram_banks[2].virt = 0x00100000; + dev->ram_banks[2].phys = 0x000a0000; + dev->ram_banks[2].size = (mem_size << 10) - 0x000a0000; + fallthrough; + case 640: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00080000; + dev->ram_banks[1].virt = 0x00080000; + dev->ram_banks[1].phys = 0x00080000; + dev->ram_banks[1].size = 0x00020000; + break; + case 768: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00080000; + dev->ram_banks[1].virt = 0x00080000; + dev->ram_banks[1].phys = 0x00080000; + dev->ram_banks[1].size = 0x00020000; + /* Pretend there's a 128k expansion. */ + dev->ram_banks[2].virt = 0x00100000; + dev->ram_banks[2].phys = 0x00080000; + dev->ram_banks[2].size = 0x00020000; + break; + case 896: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00080000; + dev->ram_banks[1].virt = 0x00080000; + dev->ram_banks[1].phys = 0x00080000; + dev->ram_banks[1].size = 0x00020000; + /* Pretend there's a 256k expansion. */ + dev->ram_banks[2].virt = 0x00100000; + dev->ram_banks[2].phys = 0x00080000; + dev->ram_banks[2].size = 0x00040000; + break; + case 1024: + dev->ram_banks[0].virt = 0x00000000; + dev->ram_banks[0].phys = 0x00000000; + dev->ram_banks[0].size = 0x00080000; + dev->ram_banks[1].virt = 0x00100000; + dev->ram_banks[1].phys = 0x00080000; + dev->ram_banks[1].size = 0x00080000; + break; + } + + if (dev->ram_banks[0].size > 0x00000000) + mem_mapping_add(&dev->ram_banks[0].mapping, dev->ram_banks[0].virt, dev->ram_banks[0].size, + cs8220_mem_read, cs8220_mem_readw, NULL, + cs8220_mem_write, cs8220_mem_writew, NULL, + ram + dev->ram_banks[0].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[0])); + + if (dev->ram_banks[1].size > 0x00000000) + mem_mapping_add(&dev->ram_banks[1].mapping, dev->ram_banks[1].virt, dev->ram_banks[1].size, + cs8220_mem_read, cs8220_mem_readw, NULL, + cs8220_mem_write, cs8220_mem_writew, NULL, + ram + dev->ram_banks[1].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[1])); + + if (dev->ram_banks[2].size > 0x00000000) + mem_mapping_add(&dev->ram_banks[2].mapping, dev->ram_banks[2].virt, dev->ram_banks[2].size, + cs8220_mem_read, cs8220_mem_readw, NULL, + cs8220_mem_write, cs8220_mem_writew, NULL, + ram + dev->ram_banks[2].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[2])); + + io_sethandler(0x00a4, 0x0002, + cs8220_in, NULL, NULL, cs8220_out, NULL, NULL, dev); + io_sethandler(0x00ab, 0x0001, + cs8220_in, NULL, NULL, cs8220_out, NULL, NULL, dev); + + return dev; +} + +const device_t cs8220_device = { + .name = "C&T CS8220 (PC/AT)", + .internal_name = "cs8220", + .flags = 0, + .local = 0, + .init = cs8220_init, + .close = cs8220_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index f9d6af150..8e6ce97c3 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -1013,7 +1013,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) case INTEL_430TX: if (!dev->smram_locked) { i4x0_smram_handler_phase0(dev); - regs[0x71] = (regs[0x71] & 0x20) | (val & 0xdf); + regs[0x71] = (regs[0x71] & 0x60) | (val & 0x9f); + regs[0x71] &= (val & 0x40); i4x0_smram_handler_phase1(dev); } break; @@ -1041,9 +1042,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) regs[0x72] = (val & 0x7f); else regs[0x72] = (regs[0x72] & 0x87) | (val & 0x78); - dev->smram_locked = (val & 0x10); - if (dev->smram_locked) - regs[0x72] &= 0xbf; + if (val & 0x08) { + dev->smram_locked = (val & 0x10); + if (dev->smram_locked) + regs[0x72] &= 0xbf; + } } } else { if (dev->smram_locked) @@ -1577,6 +1580,8 @@ i4x0_reset(void *priv) dev->regs[0x68 + i] = 0x00; } + dev->smram_locked = 0; + if (dev->type >= INTEL_430FX) { dev->regs[0x72] &= 0xef; /* Forcibly unlock the SMRAM register. */ i4x0_write(0, 0x72, 0x02, priv); @@ -1656,7 +1661,12 @@ i4x0_init(const device_t *info) regs[0x57] = 0x31; regs[0x59] = 0x0f; regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = 0x02; - dev->max_drb = 3; + /* At the very least the 420ZX seems to read to 0x64, per the SB486PV. */ + if (dev->type == INTEL_420ZX) { + regs[0x64] = 0x02; + dev->max_drb = 4; + } else + dev->max_drb = 3; dev->drb_unit = 1; dev->drb_default = 0x02; break; diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 6969d3274..e0d80f348 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -59,7 +59,6 @@ typedef struct piix_io_trap_t { } piix_io_trap_t; typedef struct _piix_ { - uint8_t cur_readout_reg; uint8_t rev; uint8_t type; uint8_t func_shift; @@ -67,7 +66,6 @@ typedef struct _piix_ { uint8_t pci_slot; uint8_t no_mirq0; uint8_t regs[4][256]; - uint8_t readout_regs[256]; uint16_t func0_id; uint16_t nvr_io_base; uint16_t acpi_io_base; @@ -157,6 +155,7 @@ piix_ide_handlers(piix_t *dev, int bus) uint16_t side; if (bus & 0x01) { + piix_log("Disabling primary IDE...\n"); ide_pri_disable(); if (dev->type == 5) { @@ -172,11 +171,14 @@ piix_ide_handlers(piix_t *dev, int bus) ide_set_side(0, side); } - if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x41] & 0x80)) + if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x41] & 0x80)) { + piix_log("Enabling primary IDE...\n"); ide_pri_enable(); + } } if (bus & 0x02) { + piix_log("Disabling secondary IDE...\n"); ide_sec_disable(); if (dev->type == 5) { @@ -192,8 +194,10 @@ piix_ide_handlers(piix_t *dev, int bus) ide_set_side(1, side); } - if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x43] & 0x80)) + if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x43] & 0x80)) { + piix_log("Enabling secondary IDE...\n"); ide_sec_enable(); + } } } @@ -467,6 +471,13 @@ piix_write(int func, int addr, uint8_t val, void *priv) uint8_t *fregs; uint16_t base; + /* Dell OptiPlex Gn+ shows that register 02:FF is aliased in 01:FF. */ + if ((dev->type == 4) && (func == 1) && (addr == 0xff)) + func = 2; + + if ((func == 1) || (addr == 0xf8) || (addr == 0xf9)) + piix_log("[W] %02X:%02X = %02X\n", func, addr, val); + /* Return on unsupported function. */ if (dev->max_func > 0) { if (func > dev->max_func) @@ -738,6 +749,8 @@ piix_write(int func, int addr, uint8_t val, void *priv) fregs[addr] = val; break; case 0xb0: + if (val & 0x10) + warning("Write %02X to B0\n", val); if (dev->type == 4) fregs[addr] = (fregs[addr] & 0x8c) | (val & 0x73); else if (dev->type == 5) @@ -747,6 +760,8 @@ piix_write(int func, int addr, uint8_t val, void *priv) alt_access = !!(val & 0x20); break; case 0xb1: + if (val & 0x18) + warning("Write %02X to B1\n", val); if (dev->type > 3) fregs[addr] = val & 0xdf; break; @@ -925,6 +940,12 @@ piix_write(int func, int addr, uint8_t val, void *priv) if (dev->type > 4) fregs[addr] = val; break; + case 0xf8: + case 0xf9: + /* Undocumented! */ + if (dev->type == 4) + fregs[addr] = val; + break; default: break; } @@ -1171,6 +1192,10 @@ piix_read(int func, int addr, void *priv) uint8_t ret = 0xff; const uint8_t *fregs; + /* Dell OptiPlex Gn+ shows that register 02:FF is aliased in 01:FF. */ + if ((dev->type == 4) && (func == 1) && (addr == 0xff)) + func = 2; + if ((dev->type == 3) && (func == 2) && (dev->max_func == 1) && (addr >= 0x40)) ret = 0x00; @@ -1185,31 +1210,6 @@ piix_read(int func, int addr, void *priv) return ret; } -static void -board_write(uint16_t port, uint8_t val, void *priv) -{ - piix_t *dev = (piix_t *) priv; - - if (port == 0x00e0) - dev->cur_readout_reg = val; - else if (port == 0x00e1) - dev->readout_regs[dev->cur_readout_reg] = val; -} - -static uint8_t -board_read(uint16_t port, void *priv) -{ - const piix_t *dev = (piix_t *) priv; - uint8_t ret = 0x64; - - if (port == 0x00e0) - ret = dev->cur_readout_reg; - else if (port == 0x00e1) - ret = dev->readout_regs[dev->cur_readout_reg]; - - return ret; -} - static void piix_reset_hard(piix_t *dev) { @@ -1226,7 +1226,7 @@ piix_reset_hard(piix_t *dev) 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_line(dev->bm[1], 15); sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); } @@ -1342,6 +1342,10 @@ piix_reset_hard(piix_t *dev) fregs[0x45] = 0x55; fregs[0x46] = 0x01; } + if (dev->type == 4) { + fregs[0xf8] = 0x30; + fregs[0xf9] = 0x0f; + } if ((dev->type == 1) && (dev->rev == 2)) dev->max_func = 0; /* It starts with IDE disabled, then enables it. */ else @@ -1617,47 +1621,16 @@ piix_init(const device_t *info) else cpu_set_isa_pci_div(3); - dma_alias_set(); + if (dev->type > 1) + dma_alias_set(); + else + dma_alias_set_piix(); if (dev->type < 4) pci_enable_mirq(0); if (dev->type < 3) pci_enable_mirq(1); - dev->readout_regs[0] = 0xff; - dev->readout_regs[1] = 0x40; - dev->readout_regs[2] = 0xff; - - /* Port E1 register 01 (TODO: Find how multipliers > 3.0 are defined): - - Bit 6: 1 = can boot, 0 = no; - Bit 7, 1 = multiplier (00 = 2.5, 01 = 2.0, 10 = 3.0, 11 = 1.5); - Bit 5, 4 = bus speed (00 = 50 MHz, 01 = 66 MHz, 10 = 60 MHz, 11 = ????): - Bit 7, 5, 4, 1: 0000 = 125 MHz, 0010 = 166 MHz, 0100 = 150 MHz, 0110 = ??? MHz; - 0001 = 100 MHz, 0011 = 133 MHz, 0101 = 120 MHz, 0111 = ??? MHz; - 1000 = 150 MHz, 1010 = 200 MHz, 1100 = 180 MHz, 1110 = ??? MHz; - 1001 = 75 MHz, 1011 = 100 MHz, 1101 = 90 MHz, 1111 = ??? MHz */ - - if (cpu_busspeed <= 40000000) - dev->readout_regs[1] |= 0x30; - else if ((cpu_busspeed > 40000000) && (cpu_busspeed <= 50000000)) - dev->readout_regs[1] |= 0x00; - else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) - dev->readout_regs[1] |= 0x20; - else if (cpu_busspeed > 60000000) - dev->readout_regs[1] |= 0x10; - - if (cpu_dmulti <= 1.5) - dev->readout_regs[1] |= 0x82; - else if ((cpu_dmulti > 1.5) && (cpu_dmulti <= 2.0)) - dev->readout_regs[1] |= 0x02; - else if ((cpu_dmulti > 2.0) && (cpu_dmulti <= 2.5)) - dev->readout_regs[1] |= 0x00; - else if (cpu_dmulti > 2.5) - dev->readout_regs[1] |= 0x80; - - io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev); - #if 0 device_add(&i8254_sec_device); #endif diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index 9b6d28ab1..b11ec0765 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -355,7 +355,23 @@ sio_config_read(uint16_t port, UNUSED(void *priv)) ret = 0xff; break; case 5: - ret = 0xd3; + /* + Dell Dimension XPS P60 jumpers: + - Bit 5: Disable CMOS Setup (1 = yes, 0 = no). + + Dell OptiPlex 560/L jumpers: + - Bit 1: Password (1 = disable, 0 = enable); + - Bit 5: Clear CMOS (1 = no, 0 = yes). + - Bits 7, 6: Board type: + - 0, 0 = L; + - 0, 1 = MT; + - 1, 0 = M; + - 1, 1 = M. + */ + if (!strcmp(machine_get_internal_name(), "opti560l")) + ret = 0x20; + else + ret = 0xd3; switch (cpu_pci_speed) { case 20000000: diff --git a/src/chipset/isa486c.c b/src/chipset/isa486c.c new file mode 100644 index 000000000..6494ed1b8 --- /dev/null +++ b/src/chipset/isa486c.c @@ -0,0 +1,131 @@ +#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/plat_unused.h> +#include <86box/chipset.h> + +typedef struct isa486c_t { + uint8_t regs[3]; +} isa486c_t; + +static void +isa486c_recalcmapping(isa486c_t *dev) +{ + uint32_t shflags = 0; + uint32_t bases[5] = { 0x000c0000, 0x000c8000, 0x000d0000, 0x000d8000, 0x000e0000 }; + uint32_t sizes[5] = { 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00020000 }; + + if (dev->regs[1] & 0x20) + shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL; + else + shflags = MEM_READ_INTERNAL | MEM_WRITE_EXTANY; + + shadowbios = 0; + shadowbios_write = 0; + + for (uint8_t i = 0; i < 5; i++) + if (dev->regs[1] & (1 << i)) { + if (i == 4) { + shadowbios = 1; + shadowbios_write = !!(dev->regs[1] & 0x20); + } + + mem_set_mem_state_both(bases[i], sizes[i], shflags); + } else + mem_set_mem_state_both(bases[i], sizes[i], MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + flushmmucache_nopc(); +} + +static void +isa486c_write(uint16_t addr, uint8_t val, void *priv) +{ + isa486c_t *dev = (isa486c_t *) priv; + + switch (addr) { + case 0x0023: + dev->regs[0] = val; + break; + /* + Port 25h: + - Bit 0 = Video BIOS (C000-C7FF) shadow enabled; + - Bit 1 = C800-C8FF shadow enabled; + - Bit 2 = D000-D7FF shadow enabled; + - Bit 3 = D800-DFFF shadow enabled; + - Bit 4 = E000-FFFF shadow enabled (or F0000-FFFFF?); + - Bit 5 = If set, read from ROM, write to shadow; + - Bit 6 = KEN Video & BIOS enabled (cacheability!). + */ + case 0x0025: + dev->regs[1] = val; + isa486c_recalcmapping(dev); + break; + case 0x0027: + dev->regs[2] = val; + break; + } +} + +static uint8_t +isa486c_read(uint16_t addr, void *priv) +{ + isa486c_t *dev = (isa486c_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + case 0x0023: + ret = dev->regs[0]; + break; + case 0x0025: + ret = dev->regs[1]; + break; + case 0x0027: + ret = dev->regs[2]; + break; + } + + return ret; +} + +static void +isa486c_close(void *priv) +{ + isa486c_t *dev = (isa486c_t *) priv; + + free(dev); +} + +static void * +isa486c_init(UNUSED(const device_t *info)) +{ + isa486c_t *dev = (isa486c_t *) calloc(1, sizeof(isa486c_t)); + + io_sethandler(0x0023, 0x0001, isa486c_read, NULL, NULL, isa486c_write, NULL, NULL, dev); + io_sethandler(0x0025, 0x0001, isa486c_read, NULL, NULL, isa486c_write, NULL, NULL, dev); + io_sethandler(0x0027, 0x0001, isa486c_read, NULL, NULL, isa486c_write, NULL, NULL, dev); + + return dev; +} + +const device_t isa486c_device = { + .name = "ASUS ISA-486C Gate Array", + .internal_name = "isa486c", + .flags = 0, + .local = 0, + .init = isa486c_init, + .close = isa486c_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/neat.c b/src/chipset/neat.c index 0661f89ee..0aa6fe5b6 100644 --- a/src/chipset/neat.c +++ b/src/chipset/neat.c @@ -988,7 +988,7 @@ neat_read(uint16_t port, void *priv) if ((dev->indx >= 0x60) && (dev->indx <= 0x6e)) ret = dev->regs[dev->indx]; else if (dev->indx == 0x6f) - ret = (dev->regs[dev->indx] & 0xfd) | ~(mem_a20_alt & 0x02); + ret = (dev->regs[dev->indx] & 0xfd) | ((~mem_a20_alt) & 0x02); break; default: diff --git a/src/chipset/olivetti_eva.c b/src/chipset/olivetti_eva.c index 7defac6ae..0dcbdd21f 100644 --- a/src/chipset/olivetti_eva.c +++ b/src/chipset/olivetti_eva.c @@ -73,26 +73,24 @@ olivetti_eva_write(uint16_t addr, uint8_t val, void *priv) break; case 0x069: dev->reg_069 = val; - /* - * Unfortunately, if triggered, the BIOS remapping function fails causing - * a fatal error. Therefore, this code section is currently commented. - */ -#if 0 - if (val & 1) { + mem_remap_top(0); + if (val == 0x01) { /* * Set the register to 7 or above for the BIOS to trigger the * memory remapping function if shadowing is active. */ - dev->reg_069 = 0x7; + dev->reg_069 = 0x07; } - if (val & 8) { + if (val & 0x08) { /* * Activate shadowing for region e0000-fffff */ mem_remap_top(256); - mem_set_mem_state_both(0xa0000, 0x60000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else { + mem_remap_top(384); + mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); } -#endif break; default: break; @@ -143,7 +141,7 @@ olivetti_eva_init(UNUSED(const device_t *info)) dev->reg_067 = 0x00; /* RAM enable registers */ - dev->reg_069 = 0x0; + dev->reg_069 = 0x00; io_sethandler(0x0065, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev); io_sethandler(0x0067, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev); @@ -152,13 +150,6 @@ olivetti_eva_init(UNUSED(const device_t *info)) /* When shadowing is not enabled in BIOS, all upper memory is available as XMS */ mem_remap_top(384); - /* - * Default settings when NVRAM is cleared activate shadowing. - * Thus, to avoid boot errors, remap only 256k from UMB to XMS. - * Remove this block once BIOS memory remapping works. - */ - mem_remap_top(256); - return dev; } diff --git a/src/chipset/opti283.c b/src/chipset/opti283.c index 395ad4212..81780cf10 100644 --- a/src/chipset/opti283.c +++ b/src/chipset/opti283.c @@ -16,6 +16,7 @@ * Copyright 2021 Tiseno100. * Copyright 2021 Miran Grca. */ +#include #include #include #include @@ -158,7 +159,20 @@ opti283_shadow_recalc(opti283_t *dev) rom = dev->regs[0x11] & (1 << ((i >> 2) + 4)); opti283_log("OPTI 283: %i/%08X: %i, %i, %i\n", i, base, (i >= 4) ? (1 << (i - 4)) : (1 << (i + 4)), (1 << (i >> 2)), (1 << ((i >> 2) + 4))); - if (sh_enable && rom) { + if (sh_copy) { + if (base >= 0x000e0000) + shadowbios_write |= 1; + if (base >= 0x000d0000) + dev->shadow_high |= 1; + + if (base >= 0xe0000) { + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + opti283_log("OPTI 283: %08X-%08X READ_EXTANY, WRITE_INTERNAL\n", base, base + 0x3fff); + } else { + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + opti283_log("OPTI 283: %08X-%08X READ_EXTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff); + } + } else if (sh_enable && rom) { if (base >= 0x000e0000) shadowbios |= 1; if (base >= 0x000d0000) @@ -171,13 +185,8 @@ opti283_shadow_recalc(opti283_t *dev) if (base >= 0x000e0000) shadowbios_write |= 1; - if (sh_copy) { - mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff); - } else { - mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_EXTERNAL\n", base, base + 0x3fff); - } + mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff); } } else { if (base >= 0xe0000) { @@ -239,9 +248,21 @@ opti283_write(uint16_t addr, uint8_t val, void *priv) dev->regs[dev->index] = (dev->regs[dev->index] & 0x80) | (val & 0x7f); break; - case 0x14: + case 0x14: { + double bus_clk; + switch (val & 0x01) { + default: + case 0x00: + bus_clk = cpu_busspeed / 6.0; + break; + case 0x01: + bus_clk = cpu_busspeed / 4.0; + break; + } + cpu_set_isa_speed((int) round(bus_clk)); reset_on_hlt = !!(val & 0x40); fallthrough; + } case 0x11: case 0x12: case 0x13: @@ -310,6 +331,8 @@ opti283_init(UNUSED(const device_t *info)) opti283_shadow_recalc(dev); + cpu_set_isa_speed((int) round(cpu_busspeed / 6.0)); + device_add(&port_92_device); return dev; diff --git a/src/chipset/opti495.c b/src/chipset/opti495.c index aa4e4b4c5..8521dbd17 100644 --- a/src/chipset/opti495.c +++ b/src/chipset/opti495.c @@ -8,14 +8,13 @@ * * Implementation of the OPTi 82C493/82C495 chipset. * - * - * * Authors: Tiseno100, * Miran Grca, * * Copyright 2008-2020 Tiseno100. * Copyright 2016-2020 Miran Grca. */ +#include #include #include #include @@ -28,6 +27,7 @@ #include <86box/io.h> #include <86box/device.h> #include <86box/mem.h> +#include <86box/plat_fallthrough.h> #include <86box/port_92.h> #include <86box/chipset.h> @@ -166,6 +166,27 @@ opti495_write(uint16_t addr, uint8_t val, void *priv) case 0x26: opti495_recalc(dev); break; + + case 0x25: { + double bus_clk; + switch (val & 0x03) { + default: + case 0x00: + bus_clk = cpu_busspeed / 6.0; + break; + case 0x01: + bus_clk = cpu_busspeed / 4.0; + break; + case 0x02: + bus_clk = cpu_busspeed / 3.0; + break; + case 0x03: + bus_clk = (cpu_busspeed * 2.0) / 5.0; + break; + } + cpu_set_isa_speed((int) round(bus_clk)); + break; + } } } @@ -259,6 +280,8 @@ opti495_init(const device_t *info) io_sethandler(0x00e1, 0x0002, opti495_read, NULL, NULL, opti495_write, NULL, NULL, dev); + cpu_set_isa_speed((int) round(cpu_busspeed / 6.0)); + return dev; } @@ -276,11 +299,25 @@ const device_t opti493_device = { .config = NULL }; -const device_t opti495_device = { +const device_t opti495slc_device = { .name = "OPTi 82C495", - .internal_name = "opti495", + .internal_name = "opti495slc", .flags = 0, - .local = OPTI495XLC, + .local = OPTI495SLC, + .init = opti495_init, + .close = opti495_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t opti495sx_device = { + .name = "OPTi 82C495SX", + .internal_name = "opti495sx", + .flags = 0, + .local = OPTI495SX, .init = opti495_init, .close = opti495_close, .reset = NULL, diff --git a/src/chipset/opti498.c b/src/chipset/opti498.c new file mode 100644 index 000000000..2d3dc6709 --- /dev/null +++ b/src/chipset/opti498.c @@ -0,0 +1,360 @@ +/* + * 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 82C498 chipset. + * + * Authors: Miran Grca, + * + * Copyright 2025 Miran Grca. + */ +#include +#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/mem.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> +#include <86box/port_92.h> +#include <86box/chipset.h> + +#ifdef ENABLE_OPTI498_LOG +int opti498_do_log = ENABLE_OPTI498_LOG; + +static void +opti498_log(const char *fmt, ...) +{ + va_list ap; + + if (opti498_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define opti498_log(fmt, ...) +#endif + +typedef struct mem_remapping_t { + uint32_t phys; + uint32_t virt; +} mem_remapping_t; + +typedef struct opti498_t { + uint8_t index; + /* 0x30 for 496/497, 0x70 for 498. */ + uint8_t reg_base; + uint8_t shadow_high; + uint8_t regs[256]; + mem_remapping_t mem_remappings[2]; + mem_mapping_t mem_mappings[2]; +} opti498_t; + +static uint8_t +opti498_read_remapped_ram(uint32_t addr, void *priv) +{ + const mem_remapping_t *dev = (mem_remapping_t *) priv; + + return mem_read_ram((addr - dev->virt) + dev->phys, priv); +} + +static uint16_t +opti498_read_remapped_ramw(uint32_t addr, void *priv) +{ + const mem_remapping_t *dev = (mem_remapping_t *) priv; + + return mem_read_ramw((addr - dev->virt) + dev->phys, priv); +} + +static uint32_t +opti498_read_remapped_raml(uint32_t addr, void *priv) +{ + const mem_remapping_t *dev = (mem_remapping_t *) priv; + + return mem_read_raml((addr - dev->virt) + dev->phys, priv); +} + +static void +opti498_write_remapped_ram(uint32_t addr, uint8_t val, void *priv) +{ + const mem_remapping_t *dev = (mem_remapping_t *) priv; + + mem_write_ram((addr - dev->virt) + dev->phys, val, priv); +} + +static void +opti498_write_remapped_ramw(uint32_t addr, uint16_t val, void *priv) +{ + const mem_remapping_t *dev = (mem_remapping_t *) priv; + + mem_write_ramw((addr - dev->virt) + dev->phys, val, priv); +} + +static void +opti498_write_remapped_raml(uint32_t addr, uint32_t val, void *priv) +{ + const mem_remapping_t *dev = (mem_remapping_t *) priv; + + mem_write_raml((addr - dev->virt) + dev->phys, val, priv); +} + +static void +opti498_shadow_recalc(opti498_t *dev) +{ + uint32_t base; + uint32_t rbase; + uint8_t sh_enable; + uint8_t sh_mode; + uint8_t rom; + uint8_t sh_copy; + + shadowbios = shadowbios_write = 0; + dev->shadow_high = 0; + + opti498_log("OPTI 498: %02X %02X %02X %02X\n", dev->regs[0x02], dev->regs[0x03], dev->regs[0x04], dev->regs[0x05]); + + if (dev->regs[0x02] & 0x80) { + if (dev->regs[0x04] & 0x02) { + mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + opti498_log("OPTI 498: F0000-FFFFF READ_EXTANY, WRITE_EXTANY\n"); + } else { + shadowbios_write = 1; + mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + opti498_log("OPTI 498: F0000-FFFFF READ_EXTANY, WRITE_INTERNAL\n"); + } + } else { + shadowbios = 1; + mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + opti498_log("OPTI 498: F0000-FFFFF READ_INTERNAL, WRITE_DISABLED\n"); + } + + sh_copy = dev->regs[0x02] & 0x08; + for (uint8_t i = 0; i < 12; i++) { + base = 0xc0000 + (i << 14); + if (i >= 4) + sh_enable = dev->regs[0x03] & (1 << (i - 4)); + else + sh_enable = dev->regs[0x04] & (1 << (i + 4)); + sh_mode = dev->regs[0x02] & (1 << (i >> 2)); + rom = dev->regs[0x02] & (1 << ((i >> 2) + 4)); + opti498_log("OPTI 498: %i/%08X: %i, %i, %i\n", i, base, (i >= 4) ? (1 << (i - 4)) : (1 << (i + 4)), (1 << (i >> 2)), (1 << ((i >> 2) + 4))); + + if (sh_copy) { + if (base >= 0x000e0000) + shadowbios_write |= 1; + if (base >= 0x000d0000) + dev->shadow_high |= 1; + + if (base >= 0xe0000) { + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + opti498_log("OPTI 498: %08X-%08X READ_EXTANY, WRITE_INTERNAL\n", base, base + 0x3fff); + } else { + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + opti498_log("OPTI 498: %08X-%08X READ_EXTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff); + } + } else if (sh_enable && rom) { + if (base >= 0x000e0000) + shadowbios |= 1; + if (base >= 0x000d0000) + dev->shadow_high |= 1; + + if (sh_mode) { + mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + opti498_log("OPTI 498: %08X-%08X READ_INTERNAL, WRITE_DISABLED\n", base, base + 0x3fff); + } else { + if (base >= 0x000e0000) + shadowbios_write |= 1; + + mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + opti498_log("OPTI 498: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff); + } + } else { + if (base >= 0xe0000) { + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_DISABLED); + opti498_log("OPTI 498: %08X-%08X READ_EXTANY, WRITE_DISABLED\n", base, base + 0x3fff); + } else { + mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_DISABLED); + opti498_log("OPTI 498: %08X-%08X READ_EXTERNAL, WRITE_DISABLED\n", base, base + 0x3fff); + } + } + } + + rbase = ((uint32_t) (dev->regs[0x05] & 0x3f)) << 20; + + if (rbase > 0) { + dev->mem_remappings[0].virt = rbase; + mem_mapping_set_addr(&dev->mem_mappings[0], rbase, 0x00020000); + + if (!dev->shadow_high) { + rbase += 0x00020000; + dev->mem_remappings[1].virt = rbase; + mem_mapping_set_addr(&dev->mem_mappings[1], rbase, 0x00020000); + } else + mem_mapping_disable(&dev->mem_mappings[1]); + } else { + mem_mapping_disable(&dev->mem_mappings[0]); + mem_mapping_disable(&dev->mem_mappings[1]); + } + + flushmmucache_nopc(); +} + +static void +opti498_write(uint16_t addr, uint8_t val, void *priv) +{ + opti498_t *dev = (opti498_t *) priv; + uint8_t reg = dev->index - dev->reg_base; + + switch (addr) { + default: + break; + + case 0x22: + dev->index = val; + break; + + case 0x24: + opti498_log("OPTi 498: dev->regs[%02x] = %02x\n", dev->index, val); + + if ((reg >= 0x00) && (reg <= 0x0b)) switch (reg) { + default: + break; + + case 0x00: + dev->regs[reg] = (dev->regs[reg] & 0xc0) | (val & 0x3f); + break; + + case 0x01: + case 0x07 ... 0x0b: + dev->regs[reg] = val; + break; + + case 0x02: + case 0x03: + case 0x04: + case 0x05: + dev->regs[reg] = val; + opti498_shadow_recalc(dev); + break; + + case 0x06: { + double bus_clk; + dev->regs[reg] = val; + switch (val & 0x03) { + default: + case 0x00: + bus_clk = cpu_busspeed / 8.0; + break; + case 0x01: + bus_clk = cpu_busspeed / 6.0; + break; + case 0x02: + bus_clk = cpu_busspeed / 5.0; + break; + case 0x03: + bus_clk = cpu_busspeed / 4.0; + break; + } + cpu_set_isa_speed((int) round(bus_clk)); + reset_on_hlt = !!(val & 0x40); + break; + } + } + + dev->index = 0xff; + break; + } +} + +static uint8_t +opti498_read(uint16_t addr, void *priv) +{ + opti498_t *dev = (opti498_t *) priv; + uint8_t reg = dev->index - dev->reg_base; + uint8_t ret = 0xff; + + if (addr == 0x24) { + if ((reg >= 0x00) && (reg <= 0x0b)) + ret = dev->regs[reg]; + + dev->index = 0xff; + } + + return ret; +} + +static void +opti498_close(void *priv) +{ + opti498_t *dev = (opti498_t *) priv; + + free(dev); +} + +static void * +opti498_init(UNUSED(const device_t *info)) +{ + opti498_t *dev = (opti498_t *) calloc(1, sizeof(opti498_t)); + + dev->reg_base = info->local & 0xff; + + io_sethandler(0x0022, 0x0001, opti498_read, NULL, NULL, opti498_write, NULL, NULL, dev); + io_sethandler(0x0024, 0x0001, opti498_read, NULL, NULL, opti498_write, NULL, NULL, dev); + + dev->regs[0x00] = 0x1f; + dev->regs[0x01] = 0x8f; + dev->regs[0x02] = 0xf0; + dev->regs[0x07] = 0x70; + dev->regs[0x09] = 0x70; + + dev->mem_remappings[0].phys = 0x000a0000; + dev->mem_remappings[1].phys = 0x000d0000; + + mem_mapping_add(&dev->mem_mappings[0], 0, 0x00020000, + opti498_read_remapped_ram, opti498_read_remapped_ramw, opti498_read_remapped_raml, + opti498_write_remapped_ram, opti498_write_remapped_ramw, opti498_write_remapped_raml, + &ram[dev->mem_remappings[0].phys], MEM_MAPPING_INTERNAL, &dev->mem_remappings[0]); + mem_mapping_disable(&dev->mem_mappings[0]); + + mem_mapping_add(&dev->mem_mappings[1], 0, 0x00020000, + opti498_read_remapped_ram, opti498_read_remapped_ramw, opti498_read_remapped_raml, + opti498_write_remapped_ram, opti498_write_remapped_ramw, opti498_write_remapped_raml, + &ram[dev->mem_remappings[1].phys], MEM_MAPPING_INTERNAL, &dev->mem_remappings[1]); + mem_mapping_disable(&dev->mem_mappings[1]); + + opti498_shadow_recalc(dev); + + cpu_set_isa_speed((int) round(cpu_busspeed / 8.0)); + + device_add(&port_92_device); + + return dev; +} + +const device_t opti498_device = { + .name = "OPTi 82C498", + .internal_name = "opti498", + .flags = 0, + .local = 0x70, + .init = opti498_init, + .close = opti498_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/opti499.c b/src/chipset/opti499.c index d54e8184e..383b8e3e2 100644 --- a/src/chipset/opti499.c +++ b/src/chipset/opti499.c @@ -16,6 +16,7 @@ * Copyright 2008-2020 Tiseno100. * Copyright 2016-2020 Miran Grca. */ +#include #include #include #include @@ -148,9 +149,28 @@ opti499_write(uint16_t addr, uint8_t val, void *priv) default: break; - case 0x20: + case 0x20: { + double coeff = (val & 0x10) ? 1.0 : 2.0; + double bus_clk; + switch (dev->regs[0x25] & 0x03) { + default: + case 0x00: + bus_clk = (cpu_busspeed * coeff) / 6.0; + break; + case 0x01: + bus_clk = (cpu_busspeed * coeff) / 5.0; + break; + case 0x02: + bus_clk = (cpu_busspeed * coeff) / 4.0; + break; + case 0x03: + bus_clk = (cpu_busspeed * coeff) / 3.0; + break; + } + cpu_set_isa_speed((int) round(bus_clk)); reset_on_hlt = !(val & 0x02); break; + } case 0x21: cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10); @@ -163,6 +183,28 @@ opti499_write(uint16_t addr, uint8_t val, void *priv) case 0x2d: opti499_recalc(dev); break; + + case 0x25: { + double coeff = (dev->regs[0x20] & 0x10) ? 1.0 : 2.0; + double bus_clk; + switch (val & 0x03) { + default: + case 0x00: + bus_clk = (cpu_busspeed * coeff) / 8.0; + break; + case 0x01: + bus_clk = (cpu_busspeed * coeff) / 6.0; + break; + case 0x02: + bus_clk = (cpu_busspeed * coeff) / 5.0; + break; + case 0x03: + bus_clk = (cpu_busspeed * coeff) / 4.0; + break; + } + cpu_set_isa_speed((int) round(bus_clk)); + break; + } } } @@ -229,6 +271,8 @@ opti499_reset(void *priv) cpu_update_waitstates(); opti499_recalc(dev); + + cpu_set_isa_speed((int) round((cpu_busspeed * 2.0) / 6.0)); } static void diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c index cb55ef2a7..16b324963 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -16,6 +16,7 @@ * Copyright 2008-2020 Tiseno100. * Copyright 2016-2020 Miran Grca. */ +#include #include #include #include @@ -182,6 +183,27 @@ opti895_write(uint16_t addr, uint8_t val, void *priv) smram_state_change(dev->smram, 0, !!(val & 0x80)); break; + case 0x25: { + double bus_clk; + switch (val & 0x03) { + default: + case 0x00: + bus_clk = cpu_busspeed / 6.0; + break; + case 0x01: + bus_clk = cpu_busspeed / 5.0; + break; + case 0x02: + bus_clk = cpu_busspeed / 4.0; + break; + case 0x03: + bus_clk = cpu_busspeed / 3.0; + break; + } + cpu_set_isa_speed((int) round(bus_clk)); + break; + } + case 0xe0: if (!(val & 0x01)) dev->forced_green = 0; @@ -294,6 +316,8 @@ opti895_init(const device_t *info) smram_enable(dev->smram, 0x00030000, 0x000b0000, 0x00010000, 0, 1); + cpu_set_isa_speed((int) round(cpu_busspeed / 6.0)); + return dev; } diff --git a/src/chipset/scamp.c b/src/chipset/scamp.c index 8e7892c2e..7ad7b3db2 100644 --- a/src/chipset/scamp.c +++ b/src/chipset/scamp.c @@ -840,7 +840,7 @@ recalc_sltptr(scamp_t *dev) recalc_ems(dev); } } else { - for (uint8_t i = 0; i < (sltptr / EMS_PGSIZE); i++) + for (uint32_t i = 0; i < (sltptr / EMS_PGSIZE); i++) scamp_mem_update_state(dev, i * EMS_PGSIZE, EMS_PGSIZE, 0x00, MEM_FMASK_SLOTBUS); for (uint8_t i = (sltptr / EMS_PGSIZE); i < 40; i++) @@ -1177,7 +1177,7 @@ scamp_init(UNUSED(const device_t *info)) dev->mem_flags[i] = MEM_FLAG_READ | MEM_FLAG_WRITE; scamp_mem_update_state(dev, i * EMS_PGSIZE, EMS_PGSIZE, 0x00, MEM_FMASK_RW); - if (i >= 60) + if (i >= 56) scamp_mem_update_state(dev, i * EMS_PGSIZE, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); } } diff --git a/src/chipset/sis_5511_h2p.c b/src/chipset/sis_5511_h2p.c index b94e69f26..c8cb44a0a 100644 --- a/src/chipset/sis_5511_h2p.c +++ b/src/chipset/sis_5511_h2p.c @@ -259,7 +259,7 @@ sis_5511_host_to_pci_write(int addr, uint8_t val, void *priv) 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); + spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x02); break; case 0x71: /* DRAM Bank Register 0-0 */ diff --git a/src/chipset/sis_85c4xx.c b/src/chipset/sis_85c4xx.c index 51f7fd4e6..49d0418ce 100644 --- a/src/chipset/sis_85c4xx.c +++ b/src/chipset/sis_85c4xx.c @@ -15,6 +15,7 @@ * * Copyright 2019-2020 Miran Grca. */ +#include #include #include #include @@ -33,6 +34,7 @@ #include <86box/mem.h> #include <86box/smram.h> #include <86box/pic.h> +#include <86box/plat_fallthrough.h> #include <86box/keyboard.h> #include <86box/machine.h> #include <86box/chipset.h> @@ -82,6 +84,14 @@ static uint8_t ram_471[64] = { 0x00, 0x00, 0x01, 0x01, 0x02, 0x20, 0x09, 0x09, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d }; +static uint8_t ram_asus[64] = { 0x00, 0x00, 0x01, 0x10, 0x10, 0x20, 0x03, 0x11, + 0x11, 0x05, 0x05, 0x12, 0x12, 0x13, 0x13, 0x13, + 0x13, 0x21, 0x06, 0x14, 0x14, 0x15, 0x15, 0x15, + 0x15, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, + 0x1d, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, + 0x17, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, + 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f }; static uint8_t ram_tg486g[64] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, @@ -162,17 +172,32 @@ sis_85c471_get_row(ram_bank_t *dev, uint32_t addr) uint32_t ret = 0x00000000; switch (dev->virt_size) { - case 0x04000000: - ret = (addr >> 14) & 0x00000fff; - break; - case 0x01000000: - ret = (addr >> 13) & 0x000007ff; + case 0x00100000: + case 0x00200000: + ret |= (addr >> 13) & 0x00000001; + ret |= ((addr >> 12) & 0x00000001) << 1; + ret |= ((addr >> 14) & 0x0000003f) << 2; + ret |= ((addr >> 11) & 0x00000001) << 8; + ret |= ((addr >> 20) & 0x00000001) << 9; + ret |= ((addr >> 22) & 0x00000001) << 10; + ret |= ((addr >> 24) & 0x00000001) << 11; break; case 0x00400000: - ret = (addr >> 12) & 0x000003ff; + case 0x00800000: + ret |= (addr >> 13) & 0x00000001; + ret |= ((addr >> 12) & 0x00000001) << 1; + ret |= ((addr >> 14) & 0x000000ff) << 2; + ret |= ((addr >> 22) & 0x00000001) << 10; + ret |= ((addr >> 24) & 0x00000001) << 11; break; - case 0x00100000: - ret = (addr >> 11) & 0x000001ff; + case 0x01000000: + case 0x02000000: + case 0x04000000: + ret |= (addr >> 13) & 0x00000001; + ret |= ((addr >> 22) & 0x00000001) << 1; + ret |= ((addr >> 14) & 0x000000ff) << 2; + ret |= ((addr >> 23) & 0x00000001) << 10; + ret |= ((addr >> 24) & 0x00000001) << 11; break; } @@ -185,17 +210,31 @@ sis_85c471_get_col(ram_bank_t *dev, uint32_t addr) uint32_t ret = 0x00000000; switch (dev->virt_size) { - case 0x04000000: - ret = (addr >> 2) & 0x00000fff; - break; - case 0x01000000: - ret = (addr >> 2) & 0x000007ff; + case 0x00100000: + case 0x00200000: + ret |= (addr >> 3) & 0x00000001; + ret |= ((addr >> 2) & 0x00000001) << 1; + ret |= ((addr >> 4) & 0x0000003f) << 2; + ret |= ((addr >> 10) & 0x00000001) << 8; + ret |= ((addr >> 21) & 0x00000001) << 9; + ret |= ((addr >> 23) & 0x00000001) << 10; + ret |= ((addr >> 25) & 0x00000001) << 11; break; case 0x00400000: - ret = (addr >> 2) & 0x000003ff; + case 0x00800000: + ret |= (addr >> 3) & 0x00000001; + ret |= ((addr >> 2) & 0x00000001) << 1; + ret |= ((addr >> 4) & 0x000000ff) << 2; + ret |= ((addr >> 23) & 0x00000001) << 10; + ret |= ((addr >> 25) & 0x00000001) << 11; break; - case 0x00100000: - ret = (addr >> 2) & 0x000001ff; + case 0x01000000: + case 0x02000000: + case 0x04000000: + ret |= (addr >> 3) & 0x00000001; + ret |= ((addr >> 2) & 0x00000001) << 1; + ret |= ((addr >> 4) & 0x000001ff) << 2; + ret |= ((addr >> 25) & 0x00000001) << 11; break; } @@ -208,17 +247,26 @@ sis_85c471_set_row(ram_bank_t *dev, uint32_t addr) uint32_t ret = 0x00000000; switch (dev->phys_size) { - case 0x04000000: - ret = (addr & 0x00000fff) << 14; + case 0x00100000: + ret = (addr & 0x1ff) << 11; break; - case 0x01000000: - ret = (addr & 0x000007ff) << 13; + case 0x00200000: + ret = (addr & 0x3ff) << 11; break; case 0x00400000: - ret = (addr & 0x000003ff) << 12; + ret = (addr & 0x3ff) << 12; break; - case 0x00100000: - ret = (addr & 0x000002ff) << 11; + case 0x00800000: + ret = (addr & 0x7ff) << 12; + break; + case 0x01000000: + ret = (addr & 0x7ff) << 13; + break; + case 0x02000000: + ret = (addr & 0xfff) << 13; + break; + case 0x04000000: + ret = (addr & 0xfff) << 14; break; } @@ -231,23 +279,28 @@ sis_85c471_set_col(ram_bank_t *dev, uint32_t addr) uint32_t ret = 0x00000000; switch (dev->phys_size) { - case 0x04000000: - ret = (addr & 0x00000fff) << 2; - break; - case 0x01000000: - ret = (addr & 0x000007ff) << 2; + case 0x00100000: + case 0x00200000: + ret = (addr & 0x1ff) << 2; break; case 0x00400000: - ret = (addr & 0x000003ff) << 2; + case 0x00800000: + ret = (addr & 0x3ff) << 2; break; - case 0x00100000: - ret = (addr & 0x000002ff) << 2; + case 0x01000000: + case 0x02000000: + ret = (addr & 0x7ff) << 2; + break; + case 0x04000000: + ret = (addr & 0xfff) << 2; break; } return ret; } +uint8_t reg09 = 0x00; + static uint8_t sis_85c471_read_ram(uint32_t addr, void *priv) { @@ -255,12 +308,10 @@ sis_85c471_read_ram(uint32_t addr, void *priv) uint32_t rel = addr - dev->virt_base; uint8_t ret = 0xff; - if ((dev->virt_size == 0x01000000) && (dev->phys_size == 0x00400000)) { - uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); - uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); - uint32_t dw = rel & 0x00000003; - rel = row | col | dw; - } + uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); + uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); + uint32_t dw = rel & 0x00000003; + rel = row | col | dw; addr = (rel + dev->phys_base); @@ -277,12 +328,10 @@ sis_85c471_read_ramw(uint32_t addr, void *priv) uint32_t rel = addr - dev->virt_base; uint16_t ret = 0xffff; - if ((dev->virt_size == 0x01000000) && (dev->phys_size == 0x00400000)) { - uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); - uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); - uint32_t dw = rel & 0x00000003; - rel = row | col | dw; - } + uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); + uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); + uint32_t dw = rel & 0x00000003; + rel = row | col | dw; addr = (rel + dev->phys_base); @@ -299,12 +348,10 @@ sis_85c471_read_raml(uint32_t addr, void *priv) uint32_t rel = addr - dev->virt_base; uint32_t ret = 0xffffffff; - if ((dev->virt_size == 0x01000000) && (dev->phys_size == 0x00400000)) { - uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); - uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); - uint32_t dw = rel & 0x00000003; - rel = row | col | dw; - } + uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); + uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); + uint32_t dw = rel & 0x00000003; + rel = row | col | dw; addr = (rel + dev->phys_base); @@ -320,12 +367,10 @@ sis_85c471_write_ram(uint32_t addr, uint8_t val, void *priv) ram_bank_t *dev = (ram_bank_t *) priv; uint32_t rel = addr - dev->virt_base; - if ((dev->virt_size == 0x01000000) && (dev->phys_size == 0x00400000)) { - uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); - uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); - uint32_t dw = rel & 0x00000003; - rel = row | col | dw; - } + uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); + uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); + uint32_t dw = rel & 0x00000003; + rel = row | col | dw; addr = (rel + dev->phys_base); @@ -339,12 +384,10 @@ sis_85c471_write_ramw(uint32_t addr, uint16_t val, void *priv) ram_bank_t *dev = (ram_bank_t *) priv; uint32_t rel = addr - dev->virt_base; - if ((dev->virt_size == 0x01000000) && (dev->phys_size == 0x00400000)) { - uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); - uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); - uint32_t dw = rel & 0x00000003; - rel = row | col | dw; - } + uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); + uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); + uint32_t dw = rel & 0x00000003; + rel = row | col | dw; addr = (rel + dev->phys_base); @@ -358,12 +401,10 @@ sis_85c471_write_raml(uint32_t addr, uint32_t val, void *priv) ram_bank_t *dev = (ram_bank_t *) priv; uint32_t rel = addr - dev->virt_base; - if ((dev->virt_size == 0x01000000) && (dev->phys_size == 0x00400000)) { - uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); - uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); - uint32_t dw = rel & 0x00000003; - rel = row | col | dw; - } + uint32_t row = sis_85c471_set_row(dev, sis_85c471_get_row(dev, rel)); + uint32_t col = sis_85c471_set_col(dev, sis_85c471_get_col(dev, rel)); + uint32_t dw = rel & 0x00000003; + rel = row | col | dw; addr = (rel + dev->phys_base); @@ -492,6 +533,8 @@ sis_85c471_banks_split(uint32_t *b_ex, uint32_t *banks) static void sis_85c471_banks_recalc(sis_85c4xx_t *dev) { + reg09 = dev->regs[0x09]; + for (uint8_t i = 0; i < 8; i++) mem_mapping_disable(&dev->ram_banks[i].mapping); @@ -553,13 +596,6 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv) switch (rel_reg) { case 0x00: - if (val & 0x01) { - kbc_at_set_fast_reset(0); - cpu_cpurst_on_sr = 1; - } else { - kbc_at_set_fast_reset(1); - cpu_cpurst_on_sr = 0; - } break; case 0x01: @@ -572,7 +608,7 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv) case 0x08: if (valxor) sis_85c4xx_recalcmapping(dev); - if (rel_reg == 0x08) + if ((rel_reg == 0x08) && dev->is_471) flushmmucache(); break; @@ -587,6 +623,41 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv) sis_85c4xx_recalcremap(dev); break; + case 0x10: + if (dev->reg_base == 0x50) { + double bus_clk; + + switch (val & 0xe0) { + default: + case 0x00: + bus_clk = 7159091.0; + break; + case 0x02: + bus_clk = cpu_busspeed / 10.0; + break; + case 0x04: + bus_clk = cpu_busspeed / 8.0; + break; + case 0x06: + bus_clk = cpu_busspeed / 6.0; + break; + case 0x80: + bus_clk = cpu_busspeed / 5.0; + break; + case 0xa0: + bus_clk = cpu_busspeed / 4.0; + break; + case 0xc0: + bus_clk = cpu_busspeed / 3.0; + break; + case 0xe0: + bus_clk = cpu_busspeed / 2.0; + break; + } + cpu_set_isa_speed((int) round(bus_clk)); + } + break; + case 0x13: if (dev->is_471 && (valxor & 0xf0)) { smram_disable(dev->smram); @@ -694,17 +765,25 @@ sis_85c4xx_reset(void *priv) if (dev->is_471) { dev->regs[0x09] = 0x40; - if (mem_size_mb >= 64) { + + if (!strcmp(machine_get_internal_name(), "vli486sv2g")) { + if (mem_size_mb == 64) + dev->regs[0x09] |= 0x1f; + else + dev->regs[0x09] |= ram_asus[mem_size_mb]; + } else if (mem_size_mb >= 64) { if ((mem_size_mb >= 64) && (mem_size_mb < 68)) dev->regs[0x09] |= 0x33; - if ((mem_size_mb >= 68) && (mem_size_mb < 72)) + else if ((mem_size_mb >= 68) && (mem_size_mb < 72)) dev->regs[0x09] |= 0x2b; - if ((mem_size_mb >= 72) && (mem_size_mb < 80)) + else if ((mem_size_mb >= 72) && (mem_size_mb < 80)) dev->regs[0x09] |= 0x2d; - if ((mem_size_mb >= 80) && (mem_size_mb < 96)) + else if ((mem_size_mb >= 80) && (mem_size_mb < 96)) dev->regs[0x09] |= 0x2f; + else if ((mem_size_mb >= 96) && (mem_size_mb < 128)) + dev->regs[0x09] |= 0x34; else - dev->regs[0x09] |= 0x29; + dev->regs[0x09] |= 0x35; } else if (!strcmp(machine_get_internal_name(), "tg486g")) dev->regs[0x09] |= ram_tg486g[mem_size_mb]; else @@ -761,6 +840,9 @@ sis_85c4xx_reset(void *priv) dev->force_flush = 1; sis_85c4xx_recalcmapping(dev); + + if (dev->reg_base == 0x50) + cpu_set_isa_speed((int) round(7159091.0)); } static void diff --git a/src/chipset/sl82c461.c b/src/chipset/sl82c461.c new file mode 100644 index 000000000..f94aa2e99 --- /dev/null +++ b/src/chipset/sl82c461.c @@ -0,0 +1,362 @@ +/* + * 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 Symphony SL82C461 (Haydn II) chipset. + * + * Symphony SL82C461 Configuration Registers (WARNING: May be inaccurate!): + * + * - Register 00h: + * - Bit 6: External cache present (if clear, AMI BIOS'es will not + * allow enabling external cache). + * + * - Register 01h: + * - Bit 0: Fast Gate A20 Enable (Handler mostly). + * Is it? Enabling/disabling fast gate A20 doesn't appear + * to do much to any register at all. + * + * - Register 02h: + * - Bit 0: Optional Chipset Turbo Pin; + * - Bits 4-2: + * - 000 = CLK2/3; + * - 001 = CLK2/4; + * - 010 = CLK2/5; + * - 011 = 7.159 MHz (ATCLK2); + * - 100 = CLK2/6; + * - 110 = CLK2/2.5; + * - 111 = CLK2/2. + * + * - Register 06h: + * - Bit 2: Decoupled Refresh Option. + * + * - Register 08h: + * - Bits 3, 2: I/O Recovery Time (SYSCLK): + * - 0, 0 = 0; + * - 1, 1 = 12. + * - Bit 1: Extended ALE. + * + * - Register 25h: + * Bit 7 here causes AMI 111192 CMOS Setup to return 7168 KB RAM + * instead of 6912 KB. This is 256 KB off. Relocation? + * Also, returning bit 5 clear instead of set, causes the AMI BIOS + * to set bits 0,1 of register 45h to 1,0 instead of 0,1. + * + * - Register 2Dh: + * - Bit 7: Enable 256KB Memory Relocation; + * - Bit 6: Enable 384KB Memory Relocation, bit 7 must also be set. + * + * - Register 2Eh: + * - Bit 7: CC000-CFFFF Shadow Read Enable; + * - Bit 6: CC000-CFFFF Shadow Write Enable; + * - Bit 5: C8000-CBFFF Shadow Read Enable; + * - Bit 4: C8000-CBFFF Shadow Write Enable; + * - Bit 3: C4000-C7FFF Shadow Read Enable; + * - Bit 2: C4000-C7FFF Shadow Write Enable; + * - Bit 1: C0000-C3FFF Shadow Read Enable; + * - Bit 0: C0000-C3FFF Shadow Write Enable. + * + * - Register 2Fh: + * - Bit 7: DC000-DFFFF Shadow Read Enable; + * - Bit 6: DC000-DFFFF Shadow Write Enable; + * - Bit 5: D8000-DBFFF Shadow Read Enable; + * - Bit 4: D8000-DBFFF Shadow Write Enable; + * - Bit 3: D4000-D7FFF Shadow Read Enable; + * - Bit 2: D4000-D7FFF Shadow Write Enable; + * - Bit 1: D0000-D3FFF Shadow Read Enable; + * - Bit 0: D0000-D3FFF Shadow Write Enable. + * + * - Register 30h: + * - Bit 7: E0000-EFFFF Shadow Read Enable; + * - Bit 6: E0000-EFFFF Shadow Write Enable. + * + * - Register 31h: + * - Bit 7: F0000-FFFFF Shadow Read Enable; + * - Bit 6: F0000-FFFFF Shadow Write Enable. + * + * - Register 33h (NOTE: Waitstates also affect register 32h): + * - Bits 3, 0: + * - 0,0 = 0 W/S; + * - 1,0 = 1 W/S; + * - 1,1 = 2 W/S. + * + * - Register 40h: + * - Bit 3: External Cache Enabled (0 = yes, 1 = no); + * I also see bits 5, 4, 3 of register 44h affected: + * - 38h (so all 3 set) when cache is disabled; + * - 00h (all 3 clear) when it's enabled. + * + * - Register 45h: + * - Bit 3: Video Shadow RAM Cacheable; + * - Bit 4: Adapter Shadow RAM Cacheable; + * - Bit 5: BIOS Shadow RAM Cacheable. + * + * Authors: Miran Grca, + * Tiseno100, + * + * Copyright 2025 Miran Grca. + * Copyright 2021-2025 Tiseno100. + */ +#include +#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/mem.h> +#include <86box/chipset.h> + +typedef struct { + uint8_t index; + uint8_t regs[256]; + uint8_t shadow[4]; +} sl82c461_t; + +#ifdef ENABLE_SL82C461_LOG +int sl82c461_do_log = ENABLE_SL82C461_LOG; + +static void +sl82c461_log(const char *fmt, ...) +{ + va_list ap; + + if (sl82c461_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define sl82c461_log(fmt, ...) +#endif + +static void +sl82c461_recalcmapping(sl82c461_t *dev) +{ + int do_shadow = 0; + + for (uint32_t i = 0; i < 8; i += 2) { + if ((dev->regs[0x2e] ^ dev->shadow[0x00]) & (3 << i)) { + uint32_t base = 0x000c0000 + ((i >> 1) << 14); + uint32_t read = ((dev->regs[0x2e] >> i) & 0x02) ? MEM_READ_INTERNAL : + MEM_READ_EXTANY; + uint32_t write = ((dev->regs[0x2e] >> i) & 0x01) ? MEM_WRITE_INTERNAL : + MEM_WRITE_EXTANY; + + mem_set_mem_state_both(base, 0x00004000, read | write); + + do_shadow++; + } + + if ((dev->regs[0x2f] ^ dev->shadow[0x01]) & (3 << i)) { + uint32_t base = 0x000d0000 + ((i >> 1) << 14); + uint32_t read = ((dev->regs[0x2f] >> i) & 0x02) ? MEM_READ_INTERNAL : + MEM_READ_EXTANY; + uint32_t write = ((dev->regs[0x2f] >> i) & 0x01) ? MEM_WRITE_INTERNAL : + MEM_WRITE_EXTANY; + + mem_set_mem_state_both(base, 0x00004000, read | write); + + do_shadow++; + } + } + + if ((dev->regs[0x30] ^ dev->shadow[0x02]) & 0xc0) { + uint32_t base = 0x000e0000; + uint32_t read = ((dev->regs[0x30] >> 6) & 0x02) ? MEM_READ_INTERNAL : + MEM_READ_EXTANY; + uint32_t write = ((dev->regs[0x30] >> 6) & 0x01) ? MEM_WRITE_INTERNAL : + MEM_WRITE_EXTANY; + + mem_set_mem_state_both(base, 0x00010000, read | write); + + do_shadow++; + } + + if ((dev->regs[0x31] ^ dev->shadow[0x03]) & 0xc0) { + uint32_t base = 0x000f0000; + uint32_t read = ((dev->regs[0x31] >> 6) & 0x02) ? MEM_READ_INTERNAL : + MEM_READ_EXTANY; + uint32_t write = ((dev->regs[0x31] >> 6) & 0x01) ? MEM_WRITE_INTERNAL : + MEM_WRITE_EXTANY; + + shadowbios = !!((dev->regs[0x31] >> 6) & 0x02); + shadowbios_write = !!((dev->regs[0x31] >> 6) & 0x01); + + mem_set_mem_state_both(base, 0x00010000, read | write); + + do_shadow++; + } + + if (do_shadow) { + memcpy(dev->shadow, &(dev->regs[0x2e]), 4 * sizeof(uint8_t)); + flushmmucache_nopc(); + } +} + +static void +sl82c461_write(uint16_t addr, uint8_t val, void *priv) +{ + sl82c461_t *dev = (sl82c461_t *) priv; + + sl82c461_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, addr, val); + + if (addr & 0x0001) { + dev->regs[dev->index] = val; + + switch (dev->index) { + case 0x01: + /* NOTE: This is to be verified. */ + mem_a20_alt = val & 1; + mem_a20_recalc(); + break; + case 0x02: { + double bus_clk; + switch (val & 0x1c) { + case 0x00: + bus_clk = cpu_busspeed / 3.0; + break; + case 0x04: + bus_clk = cpu_busspeed / 4.0; + break; + case 0x08: + bus_clk = cpu_busspeed / 5.0; + break; + default: + case 0x0c: + bus_clk = 7159091.0; + break; + case 0x10: + bus_clk = cpu_busspeed / 6.0; + break; + case 0x18: + bus_clk = cpu_busspeed / 2.5; + break; + case 0x1c: + bus_clk = cpu_busspeed / 2.0; + break; + } + cpu_set_isa_speed((int) round(bus_clk)); + break; + } case 0x2d: + switch (val & 0xc0) { + case 0xc0: + mem_remap_top(384); + break; + case 0x80: + mem_remap_top(256); + break; + default: + case 0x00: + mem_remap_top(0); + break; + } + break; + case 0x2e ... 0x31: + sl82c461_recalcmapping(dev); + break; + case 0x33: + switch (val & 0x09) { + default: + case 0x00: + cpu_waitstates = 0; + break; + case 0x08: + cpu_waitstates = 1; + break; + case 0x09: + cpu_waitstates = 2; + break; + } + cpu_update_waitstates(); + break; + case 0x40: + cpu_cache_ext_enabled = !(val & 0x08); + cpu_update_waitstates(); + break; + } + } else + dev->index = val; +} + +static uint8_t +sl82c461_read(uint16_t addr, void *priv) +{ + sl82c461_t *dev = (sl82c461_t *) priv; + uint8_t ret = 0x00; + + if (addr & 0x0001) + if (dev->index == 0x00) + ret = dev->regs[dev->index] | 0x40; + else + ret = dev->regs[dev->index]; + else + ret = dev->index; + + sl82c461_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + + return ret; +} + +static void +sl82c461_close(void *priv) +{ + sl82c461_t *dev = (sl82c461_t *) priv; + + free(dev); +} + +static void * +sl82c461_init(const device_t *info) +{ + sl82c461_t *dev = (sl82c461_t *) calloc(1, sizeof(sl82c461_t)); + + dev->regs[0x00] = 0x40; + + dev->regs[0x02] = 0x0c; + dev->regs[0x40] = 0x08; + + memset(dev->shadow, 0xff, 4 * sizeof(uint8_t)); + + mem_a20_alt = 0x00; + mem_a20_recalc(); + + cpu_set_isa_speed(7159091.0); + + sl82c461_recalcmapping(dev); + + cpu_waitstates = 0; + cpu_cache_ext_enabled = 0; + + cpu_update_waitstates(); + + io_sethandler(0x00a8, 2, + sl82c461_read, NULL, NULL, + sl82c461_write, NULL, NULL, dev); + + return dev; +} + +const device_t sl82c461_device = { + .name = "Symphony SL82C461 (Haydn II)", + .internal_name = "sis_85c471", + .flags = 0, + .local = 0, + .init = sl82c461_init, + .close = sl82c461_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index 13dbd97e9..f3075323a 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -80,10 +80,12 @@ typedef struct stpc_serial_t { } stpc_serial_t; typedef struct stpc_lpt_t { - uint8_t unlocked; - uint8_t offset; - uint8_t reg1; - uint8_t reg4; + uint8_t unlocked; + uint8_t offset; + uint8_t reg1; + uint8_t reg4; + + lpt_t *lpt; } stpc_lpt_t; #ifdef ENABLE_STPC_LOG @@ -977,22 +979,22 @@ stpc_lpt_handlers(stpc_lpt_t *dev, uint8_t val) { const uint8_t new_addr = (val & 0x03); - lpt1_remove(); + lpt_port_remove(dev->lpt); switch (new_addr) { case 0x1: stpc_log("STPC: Remapping parallel port to LPT3\n"); - lpt1_setup(LPT_MDA_ADDR); + lpt_port_setup(dev->lpt, LPT_MDA_ADDR); break; case 0x2: stpc_log("STPC: Remapping parallel port to LPT1\n"); - lpt1_setup(LPT1_ADDR); + lpt_port_setup(dev->lpt, LPT1_ADDR); break; case 0x3: stpc_log("STPC: Remapping parallel port to LPT2\n"); - lpt1_setup(LPT2_ADDR); + lpt_port_setup(dev->lpt, LPT2_ADDR); break; default: @@ -1063,6 +1065,8 @@ stpc_lpt_init(UNUSED(const device_t *info)) stpc_lpt_t *dev = (stpc_lpt_t *) calloc(1, sizeof(stpc_lpt_t)); + dev->lpt = device_add_inst(&lpt_port_device, 1); + stpc_lpt_reset(dev); io_sethandler(0x3f0, 2, diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c index 889691988..55901b32e 100644 --- a/src/chipset/umc_hb4.c +++ b/src/chipset/umc_hb4.c @@ -270,6 +270,8 @@ hb4_smram(hb4_t *dev) } umc_smram_recalc(dev->smram_base >> 12, 1); + + flushmmucache(); } static void @@ -398,55 +400,6 @@ hb4_close(void *priv) free(dev); } -static void -ims8848_write(uint16_t addr, uint8_t val, void *priv) -{ - hb4_t *dev = (hb4_t *) priv; - - switch (addr) { - case 0x22: - dev->idx = val; - break; - case 0x23: - if (((val & 0x0f) == ((dev->idx >> 4) & 0x0f)) && ((val & 0xf0) == ((dev->idx << 4) & 0xf0))) - dev->access_data = 1; - break; - case 0x24: - if (dev->access_data) - dev->access_data = 0; - break; - - default: - break; - } -} - -static uint8_t -ims8848_read(uint16_t addr, void *priv) -{ - uint8_t ret = 0xff; - hb4_t *dev = (hb4_t *) priv; - - switch (addr) { - case 0x22: - ret = dev->idx; - break; - case 0x23: - ret = (dev->idx >> 4) | (dev->idx << 4); - break; - case 0x24: - if (dev->access_data) { - ret = dev->pci_conf[dev->idx]; - dev->access_data = 0; - } - break; - default: - break; - } - - return ret; -} - static void * hb4_init(UNUSED(const device_t *info)) { @@ -463,8 +416,6 @@ hb4_init(UNUSED(const device_t *info)) dev->smram_base = 0x000a0000; hb4_reset(dev); - io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev); - return dev; } diff --git a/src/chipset/vl82c480.c b/src/chipset/vl82c480.c index 496544c63..acb3568af 100644 --- a/src/chipset/vl82c480.c +++ b/src/chipset/vl82c480.c @@ -24,14 +24,16 @@ #include <86box/timer.h> #include <86box/device.h> #include <86box/io.h> +#include <86box/machine.h> #include <86box/mem.h> #include <86box/nmi.h> #include <86box/port_92.h> #include <86box/chipset.h> typedef struct vl82c480_t { - uint8_t idx; - uint8_t regs[256]; + uint8_t idx; + uint8_t regs[256]; + uint32_t banks[4]; } vl82c480_t; static int @@ -59,7 +61,7 @@ vl82c480_shflags(uint8_t access) } static void -vl82c480_recalc(vl82c480_t *dev) +vl82c480_recalc_shadow(vl82c480_t *dev) { uint32_t base; uint8_t access; @@ -69,8 +71,8 @@ vl82c480_recalc(vl82c480_t *dev) for (uint8_t i = 0; i < 6; i++) { for (uint8_t j = 0; j < 8; j += 2) { - base = 0x000a0000 + (i << 16) + (j << 13); - access = (dev->regs[0x0d + i] >> j) & 3; + base = 0x000a0000 + (i << 16) + (j << 13); + access = (dev->regs[0x0d + i] >> j) & 3; mem_set_mem_state(base, 0x4000, vl82c480_shflags(access)); shadowbios |= ((base >= 0xe0000) && (access & 0x02)); shadowbios_write |= ((base >= 0xe0000) && (access & 0x01)); @@ -80,6 +82,37 @@ vl82c480_recalc(vl82c480_t *dev) flushmmucache(); } +static void +vl82c480_recalc_banks(vl82c480_t *dev) +{ + uint32_t sizes[8] = { 0, 0, 1024, 2048, 4096, 8192, 16384, 32768 }; + uint8_t shifts[4] = { 0, 4, 0, 4 }; + uint8_t regs[4] = { 0x02, 0x02, 0x03, 0x03 }; + uint32_t total = 0; + + for (uint8_t i = 0; i < 4; i++) { + uint8_t shift = shifts[i]; + uint8_t reg = regs[i]; + uint8_t cfg = (dev->regs[reg] >> shift) & 0x7; + uint32_t size = sizes[cfg]; + + total += MIN(dev->banks[i], size); + } + + if (total > 1024) { + mem_mapping_set_addr(&ram_low_mapping, 0x00000000, 0x000a0000); + mem_mapping_set_addr(&ram_high_mapping, 0x00100000, (total - 1024) << 10); + } else { + if (total >= 1024) + mem_mapping_set_addr(&ram_low_mapping, 0x00000000, 0x000a0000); + else + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_high_mapping); + } + + flushmmucache(); +} + static void vl82c480_write(uint16_t addr, uint8_t val, void *priv) { @@ -91,11 +124,18 @@ vl82c480_write(uint16_t addr, uint8_t val, void *priv) break; case 0xed: - if (dev->idx >= 0x01 && dev->idx <= 0x24) { + if (((dev->idx >= 0x01) && (dev->idx <= 0x19)) || + ((dev->idx >= 0x20) && (dev->idx <= 0x24))) { switch (dev->idx) { default: dev->regs[dev->idx] = val; break; + case 0x02: case 0x03: + dev->regs[dev->idx] = val; + if (!strcmp(machine_get_internal_name(), "martin") || + !strcmp(machine_get_internal_name(), "prolineamt")) + vl82c480_recalc_banks(dev); + break; case 0x04: if (dev->regs[0x00] == 0x98) dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x08) | (val & 0xf7); @@ -108,14 +148,9 @@ vl82c480_write(uint16_t addr, uint8_t val, void *priv) case 0x07: dev->regs[dev->idx] = (dev->regs[dev->idx] & 0x40) | (val & 0xbf); break; - case 0x0d: - case 0x0e: - case 0x0f: - case 0x10: - case 0x11: - case 0x12: + case 0x0d ... 0x12: dev->regs[dev->idx] = val; - vl82c480_recalc(dev); + vl82c480_recalc_shadow(dev); break; } } @@ -124,8 +159,8 @@ vl82c480_write(uint16_t addr, uint8_t val, void *priv) /* TODO: This is actually Fast A20 disable. */ #if 0 case 0xee: - if (mem_a20_alt) - outb(0x92, inb(0x92) & ~2); + mem_a20_alt = 0x00; + mem_a20_recalc(); break; #endif @@ -146,14 +181,16 @@ vl82c480_read(uint16_t addr, void *priv) break; case 0xed: - ret = dev->regs[dev->idx]; + if (((dev->idx >= 0x01) && (dev->idx <= 0x19)) || + ((dev->idx >= 0x20) && (dev->idx <= 0x24))) + ret = dev->regs[dev->idx]; break; /* TODO: This is actually Fast A20 enable. */ #if 0 case 0xee: - if (!mem_a20_alt) - outb(0x92, inb(0x92) | 2); + mem_a20_alt = 0x02; + mem_a20_recalc(); break; #endif @@ -180,7 +217,12 @@ vl82c480_close(void *priv) static void * vl82c480_init(const device_t *info) { - vl82c480_t *dev = (vl82c480_t *) calloc(1, sizeof(vl82c480_t)); + vl82c480_t *dev = (vl82c480_t *) calloc(1, sizeof(vl82c480_t)); + uint32_t sizes[8] = { 0, 0, 1024, 2048, 4096, 8192, 16384, 32768 }; + uint32_t ms = mem_size; + uint8_t min_i = !strcmp(machine_get_internal_name(), "prolineamt") ? 1 : 0; + uint8_t min_j = !strcmp(machine_get_internal_name(), "prolineamt") ? 4 : 2; + uint8_t max_j = !strcmp(machine_get_internal_name(), "prolineamt") ? 8 : 7; dev->regs[0x00] = info->local; dev->regs[0x01] = 0xff; @@ -191,9 +233,31 @@ vl82c480_init(const device_t *info) dev->regs[0x07] = 0x21; dev->regs[0x08] = 0x38; + if (!strcmp(machine_get_internal_name(), "prolineamt")) { + dev->banks[0] = 4096; + + /* Bank 0 is ignored if 64 MB is installed. */ + if (ms != 65536) + ms -= 4096; + } + + if (ms > 0) for (uint8_t i = min_i; i < 4; i++) { + for (uint8_t j = min_j; j < max_j; j++) { + if (ms >= sizes[j]) + dev->banks[i] = sizes[j]; + else + break; + } + + ms -= dev->banks[i]; + + if ((ms == 0) || (dev->banks[i] == 0)) + break; + } + io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, dev); - device_add(&port_92_device); + device_add(&port_92_pci_device); return dev; } diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index 48bb56483..d11330c85 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -113,9 +113,9 @@ typedef struct mem_mapping_t ram_mapping; nvr_t *nvr; - - fdc_t *fdc; - serial_t *uart[2]; + fdc_t *fdc; + serial_t *uart[2]; + lpt_t *lpt; } wd76c10_t; static uint32_t bank_sizes[4] = { 0x00020000, /* 64 Kbit X 16 = 1024 Kbit = 128 kB, 8x 8 */ @@ -841,7 +841,7 @@ wd76c10_pf_loc_recalc(wd76c10_t *dev) uint8_t ems_page; uint32_t base; - for (uint8_t i = (0x031 + pf_loc); i <= (0x037 + pf_loc); i++) { + for (uint16_t i = (0x031 + pf_loc); i <= (0x037 + pf_loc); i++) { ems_page = (i - 0x10) & 0xf7; dev->mem_pages[i] = ems_page; base = ((uint32_t) i) << 14; @@ -911,19 +911,19 @@ wd76c10_ser_par_cs_recalc(wd76c10_t *dev) } /* LPT */ - lpt1_remove(); + lpt_port_remove(dev->lpt); switch ((dev->ser_par_cs >> 9) & 0x03) { case 1: - lpt1_setup(LPT_MDA_ADDR); - lpt1_irq(LPT1_IRQ); + lpt_port_setup(dev->lpt, LPT_MDA_ADDR); + lpt_port_irq(dev->lpt, LPT1_IRQ); break; case 2: - lpt1_setup(LPT1_ADDR); - lpt1_irq(LPT1_IRQ); + lpt_port_setup(dev->lpt, LPT1_ADDR); + lpt_port_irq(dev->lpt, LPT1_IRQ); break; case 3: - lpt1_setup(LPT2_ADDR); - lpt1_irq(LPT1_IRQ); + lpt_port_setup(dev->lpt, LPT2_ADDR); + lpt_port_irq(dev->lpt, LPT1_IRQ); break; } } @@ -1173,8 +1173,8 @@ wd76c10_inw(uint16_t port, void *priv) case 0xd072: ret = (serial_read(0x0002, dev->uart[0]) & 0xc0) << 8; ret |= (serial_read(0x0002, dev->uart[1]) & 0xc0) << 6; - ret |= (lpt_read_port(0, 0x0002) & 0x0f) << 8; - ret |= lpt_read_port(0, 0x0000); + ret |= (lpt_read_port(dev->lpt, 0x0002) & 0x0f) << 8; + ret |= lpt_read_port(dev->lpt, 0x0000); break; case 0xe072: @@ -1188,7 +1188,7 @@ wd76c10_inw(uint16_t port, void *priv) break; case 0xfc72: - ret = ((lpt_read_status(0) & 0x20) >> 2); + ret = ((lpt_read_status(dev->lpt) & 0x20) >> 2); ret |= (((uint16_t) dma_m) << 4); ret |= dev->toggle; dev->toggle ^= 0x8000; @@ -1303,6 +1303,7 @@ wd76c10_init(UNUSED(const device_t *info)) dev->nvr = device_add(&amstrad_megapc_nvr_device); dev->uart[0] = device_add_inst(&ns16450_device, 1); dev->uart[1] = device_add_inst(&ns16450_device, 2); + dev->lpt = device_add_inst(&lpt_port_device, 1); dev->fdc = device_add(&fdc_at_device); device_add(&ide_isa_device); diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h index 129d9a740..5d6a62c7a 100644 --- a/src/codegen/codegen_ops_x86-64.h +++ b/src/codegen/codegen_ops_x86-64.h @@ -3875,19 +3875,31 @@ FP_LOAD_IMM_Q(uint64_t v) static __inline void FP_FCHS(void) { + addbyte(0x48); /* MOVABS RAX, 0x8000000000000000 */ + addbyte(0xb8); + addquad(0x8000000000000000); + addbyte(0x66); /* MOVQ XMM15, RAX */ + addbyte(0x4c); + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xf8); + addbyte(0x48); /* XOR RAX, RAX */ + addbyte(0x31); + addbyte(0xc0); addbyte(0x8b); /*MOV EAX, TOP*/ addbyte(0x45); addbyte((uint8_t) cpu_state_offset(TOP)); - addbyte(0xf2); /*SUBSD XMM0, XMM0*/ + addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ addbyte(0x0f); - addbyte(0x5c); - addbyte(0xc0); - addbyte(0xf2); /*SUBSD XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x5c); + addbyte(0x7e); addbyte(0x44); addbyte(0xc5); addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x66); /* PXOR XMM0, XMM15 */ + addbyte(0x41); + addbyte(0x0F); + addbyte(0xEF); + addbyte(0xC7); addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ addbyte(0x64); addbyte(0x05); diff --git a/src/codegen/codegen_x86-64.c b/src/codegen/codegen_x86-64.c index c424cf8c5..fb775a2d0 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -818,6 +818,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p int over = 0; int pc_off = 0; int test_modrm = 1; + int in_lock = 0; int c; uint32_t op87 = 0x00000000; @@ -956,6 +957,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p break; case 0xf0: /*LOCK*/ + in_lock = 0; break; case 0xf2: /*REPNE*/ @@ -1013,6 +1015,9 @@ generate_call: STORE_IMM_ADDR_L((uintptr_t) &x87_op, op87); } + if (in_lock && ((opcode == 0x90) || (opcode == 0xec))) + goto codegen_skip; + if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) { uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); if (new_pc) { @@ -1040,7 +1045,13 @@ generate_call: } } - op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; +codegen_skip: + if (in_lock && ((opcode == 0x90) || (opcode == 0xec))) + /* This is always ILLEGAL. */ + op = x86_dynarec_opcodes_3DNOW[0xff]; + else + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; + if (op_ssegs != last_ssegs) { last_ssegs = op_ssegs; addbyte(0xC6); /*MOVB $0,(ssegs)*/ diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index bf34c2de8..e0b9b633a 100644 --- a/src/codegen/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -1857,6 +1857,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p int over = 0; int pc_off = 0; int test_modrm = 1; + int in_lock = 0; int c; uint32_t op87 = 0x00000000; @@ -1996,6 +1997,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p break; case 0xf0: /*LOCK*/ + in_lock = 1; break; case 0xf2: /*REPNE*/ @@ -2054,6 +2056,9 @@ generate_call: STORE_IMM_ADDR_L((uintptr_t) &x87_op, op87); } + if (in_lock && ((opcode == 0x90) || (opcode == 0xec))) + goto codegen_skip; + if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) { uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); if (new_pc) { @@ -2080,7 +2085,13 @@ generate_call: } } - op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; +codegen_skip: + if (in_lock && ((opcode == 0x90) || (opcode == 0xec))) + /* This is always ILLEGAL. */ + op = x86_dynarec_opcodes_3DNOW[0xff]; + else + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; + if (op_ssegs != last_ssegs) { last_ssegs = op_ssegs; diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index 44dd408ab..875dd72ca 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -395,6 +395,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p int over = 0; int test_modrm = 1; int pc_off = 0; + int in_lock = 0; uint32_t next_pc = 0; uint16_t op87 = 0x0000; #ifdef DEBUG_EXTRA @@ -556,6 +557,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p break; case 0xf0: /*LOCK*/ + in_lock = 1; break; case 0xf2: /*REPNE*/ @@ -675,6 +677,9 @@ generate_call: goto codegen_skip; #endif + if (in_lock && ((opcode == 0x90) || (opcode == 0xec))) + goto codegen_skip; + 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); if (new_pc) { @@ -692,13 +697,17 @@ generate_call: } } - // codegen_skip: +codegen_skip: if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) { op_table = x86_dynarec_opcodes; recomp_op_table = recomp_opcodes; } - op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; + if (in_lock && ((opcode == 0x90) || (opcode == 0xec))) + /* This is always ILLEGAL. */ + op = x86_dynarec_opcodes_3DNOW[0xff]; + else + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; if (!test_modrm || (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]) || (op_table == x86_dynarec_opcodes_3DNOW)) { int stack_offset = 0; @@ -737,8 +746,7 @@ generate_call: uop_MOV_PTR(ir, IREG_ea_seg, (void *) op_ea_seg); if (op_ssegs != last_op_ssegs) uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); - uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat); - uop_CALL_INSTRUCTION_FUNC(ir, op); + uop_CALL_INSTRUCTION_FUNC(ir, op, fetchdat); codegen_flags_changed = 0; codegen_mark_code_present(block, cs + cpu_state.pc, 8); diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index 82cc79cfd..2bb6281ff 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -218,6 +218,7 @@ codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { + host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); host_arm64_call(block, uop->p); host_arm64_CBNZ(block, REG_X0, (uintptr_t) codegen_exit_rout); diff --git a/src/codegen_new/codegen_backend_arm_uops.c b/src/codegen_new/codegen_backend_arm_uops.c index b6963562c..b186e0e3b 100644 --- a/src/codegen_new/codegen_backend_arm_uops.c +++ b/src/codegen_new/codegen_backend_arm_uops.c @@ -286,6 +286,7 @@ codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { + host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data); host_arm_call(block, uop->p); host_arm_TST_REG(block, REG_R0, REG_R0); host_arm_BNE(block, (uintptr_t) codegen_exit_rout); diff --git a/src/codegen_new/codegen_backend_x86-64_ops.c b/src/codegen_new/codegen_backend_x86-64_ops.c index fc6c1b492..9f89012c6 100644 --- a/src/codegen_new/codegen_backend_x86-64_ops.c +++ b/src/codegen_new/codegen_backend_x86-64_ops.c @@ -68,8 +68,10 @@ jmp(codeblock_t *block, uintptr_t func) void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_ADD8_REG_IMM - dst_reg & 8\n"); +#endif if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); @@ -82,8 +84,10 @@ host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_ADD16_REG_IMM - dst_reg & 8\n"); +#endif if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); @@ -101,8 +105,10 @@ host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_ADD32_REG_IMM - dst_reg & 8\n"); +#endif if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); @@ -120,8 +126,10 @@ host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) void host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_ADD64_REG_IMM - dst_reg & 8\n"); +#endif if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); @@ -132,8 +140,10 @@ host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_ADD8_REG_REG - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ @@ -141,8 +151,10 @@ host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_ADD16_REG_REG - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ @@ -150,8 +162,10 @@ host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_ADD32_REG_REG - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ @@ -160,8 +174,10 @@ host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_AND8_REG_IMM - dst_reg & 8\n"); +#endif if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); @@ -174,8 +190,10 @@ host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_AND16_REG_IMM - dst_reg & 8\n"); +#endif if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); @@ -193,8 +211,10 @@ host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_AND32_REG_IMM - dst_reg & 8\n"); +#endif if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); @@ -212,8 +232,10 @@ host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_AND8_REG_REG - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ @@ -221,8 +243,10 @@ host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_AND16_REG_REG - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ @@ -230,8 +254,10 @@ host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_AND32_REG_REG - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ @@ -482,8 +508,10 @@ host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offs void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) fatal("host_x86_LEA_REG_REG - bad reg\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b]*/ @@ -492,8 +520,10 @@ host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) fatal("host_x86_LEA_REG_REG_SHIFT - bad reg\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b * (1 << shift)]*/ @@ -575,8 +605,10 @@ host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) { int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); +#ifdef RECOMPILER_DEBUG if (src_reg & 8) fatal("host_x86_MOV8_ABS_REG - bad reg\n"); +#endif if (offset >= -128 && offset <= 127) { codegen_alloc_bytes(block, 3); @@ -599,8 +631,10 @@ host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) { int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); +#ifdef RECOMPILER_DEBUG if (src_reg & 8) fatal("host_x86_MOV16_ABS_REG - bad reg\n"); +#endif if (offset >= -128 && offset <= 127) { codegen_alloc_bytes(block, 4); @@ -619,8 +653,10 @@ host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) { int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); +#ifdef RECOMPILER_DEBUG if (src_reg & 8) fatal("host_x86_MOV32_ABS_REG - bad reg\n"); +#endif if (offset >= -128 && offset <= 127) { codegen_alloc_bytes(block, 3); @@ -643,8 +679,10 @@ host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) { int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); +#ifdef RECOMPILER_DEBUG if (src_reg & 8) fatal("host_x86_MOV64_ABS_REG - bad reg\n"); +#endif if (offset >= -128 && offset <= 127) { codegen_alloc_bytes(block, 4); @@ -665,8 +703,11 @@ host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int index_reg, int shift, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); +#endif + if (addr < 0x80 || addr >= 0xffffff80) { codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ @@ -680,24 +721,30 @@ host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_ void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV B[base_reg + index_reg], src_reg*/ } void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); +#endif codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV W[base_reg + index_reg], src_reg*/ } void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/ } @@ -708,8 +755,10 @@ host_x86_MOV8_REG_ABS(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) + 2147483648ULL); +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_MOV8_REG_ABS reg & 8\n"); +#endif if (offset >= -128 && offset <= 127) { codegen_alloc_bytes(block, 3); @@ -736,8 +785,10 @@ host_x86_MOV16_REG_ABS(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) + 2147483648ULL); +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_MOV16_REG_ABS reg & 8\n"); +#endif if (offset >= -128 && offset <= 127) { codegen_alloc_bytes(block, 4); @@ -766,8 +817,10 @@ host_x86_MOV32_REG_ABS(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) + 2147483648ULL); +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_MOV32_REG_ABS reg & 8\n"); +#endif if (offset >= -128 && offset <= 127) { codegen_alloc_bytes(block, 3); @@ -780,8 +833,13 @@ host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) 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); + } else if ((ram_offset < -2147483648LL) || (ram_offset > 2147483647LL) || !(block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 13); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV r9,(uintptr_t) p*/ + codegen_addquad(block, (uintptr_t) p); + codegen_addbyte3(block, 0x41, 0x8b, 0x01 | ((dst_reg & 7) << 3)); /*MOV dst_reg, [R9]*/ } else { - fatal("host_x86_MOV32_REG_ABS - out of range\n"); + fatal("host_x86_MOV32_REG_ABS - RAM offset = %016" PRIX64 " (p - ram = %016" PRIXPTR ")\n", ram_offset, (uintptr_t) p - (uintptr_t) ram); codegen_alloc_bytes(block, 6); codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ codegen_addbyte(block, 0x05 | ((dst_reg & 7) << 3)); @@ -793,8 +851,10 @@ host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p) { int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_MOV64_REG_ABS reg & 8\n"); +#endif if (offset >= -128 && offset <= 127) { codegen_alloc_bytes(block, 4); @@ -810,8 +870,10 @@ host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p) void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOV8_REG_ABS_REG_REG_SHIFT reg & 8\n"); +#endif if (addr < 0x80 || addr >= 0xffffff80) { codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ @@ -825,8 +887,10 @@ host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t ad void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOV32_REG_BASE_INDEX reg & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); /*MOV dst_reg, Q[base_reg + index_reg]*/ } @@ -834,8 +898,10 @@ host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (index_reg & 8)) fatal("host_x86_MOV64_REG_BASE_INDEX_SHIFT reg & 8\n"); +#endif codegen_alloc_bytes(block, 4); if (base_reg & 8) codegen_addbyte4(block, 0x49, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ @@ -846,8 +912,10 @@ host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_re void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (base_reg & 8)) fatal("host_x86_MOV16_REG_BASE_OFFSET reg & 8\n"); +#endif if (offset >= -128 && offset <= 127) { if (base_reg == REG_RSP) { @@ -864,8 +932,10 @@ host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, in void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (base_reg & 8)) fatal("host_x86_MOV32_REG_BASE_OFFSET reg & 8\n"); +#endif if (offset >= -128 && offset <= 127) { if (base_reg == REG_RSP) { @@ -881,8 +951,10 @@ host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, in void host_x86_MOV64_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (base_reg & 8)) fatal("host_x86_MOV64_REG_BASE_OFFSET reg & 8\n"); +#endif if (offset >= -128 && offset <= 127) { if (base_reg == REG_RSP) { @@ -900,8 +972,10 @@ host_x86_MOV64_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, in void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((src_reg & 8) || (base_reg & 8)) fatal("host_x86_MOV32_BASE_OFFSET_REG reg & 8\n"); +#endif if (offset >= -128 && offset <= 127) { if (base_reg == REG_RSP) { @@ -917,8 +991,10 @@ host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int void host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((src_reg & 8) || (base_reg & 8)) fatal("host_x86_MOV64_BASE_OFFSET_REG reg & 8\n"); +#endif if (offset >= -128 && offset <= 127) { if (base_reg == REG_RSP) { @@ -936,8 +1012,10 @@ host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data) { +#ifdef RECOMPILER_DEBUG if (base_reg & 8) fatal("host_x86_MOV32_BASE_OFFSET_IMM reg & 8\n"); +#endif if (offset >= -128 && offset <= 127) { if (base_reg == REG_RSP) { @@ -956,16 +1034,21 @@ host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uin void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) { +#ifdef RECOMPILER_DEBUG if (reg >= 8) fatal("host_x86_MOV8_REG_IMM reg >= 4\n"); +#endif + codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xb0 | reg, imm_data); /*MOV reg, imm_data*/ } void host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) { +#ifdef RECOMPILER_DEBUG if (reg & 8) fatal("host_x86_MOV16_REG_IMM reg & 8\n"); +#endif codegen_alloc_bytes(block, 6); codegen_addbyte2(block, 0x66, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ codegen_addword(block, imm_data); @@ -973,8 +1056,10 @@ host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data) { +#ifdef RECOMPILER_DEBUG if (reg & 8) fatal("host_x86_MOV32_REG_IMM reg & 8\n"); +#endif codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ codegen_addlong(block, imm_data); @@ -997,8 +1082,10 @@ host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_data) void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_MOV8_REG_REG - bad reg\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x88, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); @@ -1006,8 +1093,10 @@ host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_MOV16_REG_REG - bad reg\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); @@ -1015,8 +1104,10 @@ host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_MOV32_REG_REG - bad reg\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); @@ -1063,8 +1154,10 @@ host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOVZX_BASE_INDEX_32_8 reg & 8\n"); +#endif codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); @@ -1072,8 +1165,10 @@ host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, in void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) fatal("host_x86_MOVZX_BASE_INDEX_32_16 reg & 8\n"); +#endif codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); @@ -1082,8 +1177,10 @@ host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, i void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); +#endif codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ @@ -1091,8 +1188,10 @@ host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_MOVZX_REG_32_8 - bad reg\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ @@ -1100,8 +1199,10 @@ host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ @@ -1113,8 +1214,10 @@ host_x86_MOVZX_REG_ABS_16_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) + 2147483648ULL); +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_MOVZX_REG_ABS_16_8 - bad reg\n"); +#endif if (offset >= -128 && offset <= 127) { codegen_alloc_bytes(block, 5); @@ -1140,7 +1243,7 @@ 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) + 2147483648ULL); -#if 0 +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); #endif @@ -1179,8 +1282,10 @@ host_x86_MOVZX_REG_ABS_32_16(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) + 2147483648ULL); +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_MOVZX_REG_ABS_32_16 - bad reg\n"); +#endif if (offset >= -128 && offset <= 127) { codegen_alloc_bytes(block, 4); @@ -1209,8 +1314,10 @@ host_x86_NOP(codeblock_t *block) void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); +#endif if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); @@ -1223,8 +1330,10 @@ host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); +#endif if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); @@ -1242,8 +1351,10 @@ host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); +#endif if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); @@ -1261,8 +1372,10 @@ host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ @@ -1270,8 +1383,10 @@ host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ @@ -1279,8 +1394,10 @@ host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ @@ -1320,24 +1437,30 @@ host_x86_RET(codeblock_t *block) void host_x86_ROL8_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("ROL8 CL & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_ROL16_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("ROL16 CL & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_ROL32_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("ROL32 CL & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ } @@ -1345,24 +1468,30 @@ host_x86_ROL32_CL(codeblock_t *block, int dst_reg) void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("ROL8 imm & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("ROL16 imm & 8\n"); +#endif codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("ROL32 imm & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ } @@ -1370,24 +1499,30 @@ host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) void host_x86_ROR8_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("ROR8 CL & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_ROR16_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("ROR16 CL & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_ROR32_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("ROR32 CL & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ } @@ -1395,24 +1530,30 @@ host_x86_ROR32_CL(codeblock_t *block, int dst_reg) void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("ROR8 imm & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("ROR16 imm & 8\n"); +#endif codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("ROR32 im & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ } @@ -1420,8 +1561,10 @@ host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) void host_x86_SAR8_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SAR8 CL & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ @@ -1429,8 +1572,10 @@ host_x86_SAR8_CL(codeblock_t *block, int dst_reg) void host_x86_SAR16_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SAR16 CL & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ @@ -1438,8 +1583,10 @@ host_x86_SAR16_CL(codeblock_t *block, int dst_reg) void host_x86_SAR32_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SAR32 CL & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ @@ -1448,8 +1595,10 @@ host_x86_SAR32_CL(codeblock_t *block, int dst_reg) void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SAR8 imm & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ @@ -1457,8 +1606,10 @@ host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SAR16 imm & 8\n"); +#endif codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ @@ -1466,8 +1617,10 @@ host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SAR32 imm & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ } @@ -1475,8 +1628,10 @@ host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) void host_x86_SHL8_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SHL8 CL & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ @@ -1484,8 +1639,10 @@ host_x86_SHL8_CL(codeblock_t *block, int dst_reg) void host_x86_SHL16_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SHL16 CL & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ @@ -1493,8 +1650,10 @@ host_x86_SHL16_CL(codeblock_t *block, int dst_reg) void host_x86_SHL32_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SHL32 CL & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ @@ -1503,8 +1662,10 @@ host_x86_SHL32_CL(codeblock_t *block, int dst_reg) void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SHL8 imm & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ @@ -1512,8 +1673,10 @@ host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SHL16 imm & 8\n"); +#endif codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ @@ -1521,8 +1684,10 @@ host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SHL32 imm & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ @@ -1531,8 +1696,10 @@ host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) void host_x86_SHR8_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SHR8 CL & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ @@ -1540,8 +1707,10 @@ host_x86_SHR8_CL(codeblock_t *block, int dst_reg) void host_x86_SHR16_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SHR16 CL & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ @@ -1549,8 +1718,10 @@ host_x86_SHR16_CL(codeblock_t *block, int dst_reg) void host_x86_SHR32_CL(codeblock_t *block, int dst_reg) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SHR32 CL & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ @@ -1559,8 +1730,10 @@ host_x86_SHR32_CL(codeblock_t *block, int dst_reg) void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SHR8 imm & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ @@ -1568,8 +1741,10 @@ host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SHR16 imm & 8\n"); +#endif codegen_alloc_bytes(block, 4); codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ @@ -1577,8 +1752,10 @@ host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("SHR32 imm & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } @@ -1586,8 +1763,10 @@ host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_SUB8_REG_IMM - dst_reg & 8\n"); +#endif if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); @@ -1600,8 +1779,10 @@ host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_SUB16_REG_IMM - dst_reg & 8\n"); +#endif if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); @@ -1619,8 +1800,10 @@ host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_SUB32_REG_IMM - dst_reg & 8\n"); +#endif if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); @@ -1638,8 +1821,10 @@ host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) void host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_SUB64_REG_IMM - dst_reg & 8\n"); +#endif if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); @@ -1650,8 +1835,10 @@ host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_SUB8_REG_REG - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ @@ -1659,8 +1846,10 @@ host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_SUB16_REG_REG - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ @@ -1668,8 +1857,10 @@ host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_SUB32_REG_REG - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ @@ -1692,8 +1883,10 @@ host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_TEST32_REG - bad reg\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ @@ -1701,8 +1894,10 @@ host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("TEST32_REG_IMM reg & 8\n"); +#endif if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 5); codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ @@ -1717,8 +1912,10 @@ host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); +#endif if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); @@ -1731,8 +1928,10 @@ host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); +#endif if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); @@ -1750,8 +1949,10 @@ host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { +#ifdef RECOMPILER_DEBUG if (dst_reg & 8) fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); +#endif if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); @@ -1769,8 +1970,10 @@ host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ @@ -1778,8 +1981,10 @@ host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 3); codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ @@ -1787,8 +1992,10 @@ host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { +#ifdef RECOMPILER_DEBUG if ((dst_reg & 8) || (src_reg & 8)) fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); +#endif codegen_alloc_bytes(block, 2); codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c index 655896b54..356c8bcde 100644 --- a/src/codegen_new/codegen_backend_x86-64_uops.c +++ b/src/codegen_new/codegen_backend_x86-64_uops.c @@ -219,6 +219,11 @@ codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { +# if _WIN64 + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); +# else + host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); +# endif host_x86_CALL(block, uop->p); host_x86_TEST32_REG(block, REG_EAX, REG_EAX); host_x86_JNZ(block, codegen_exit_rout); @@ -631,9 +636,10 @@ codegen_FCHS(codeblock_t *block, uop_t *uop) 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); - host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); - host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg_a); + host_x86_MOV64_REG_IMM(block, REG_RCX, 0x8000000000000000); + host_x86_MOVQ_XREG_REG(block, REG_XMM_TEMP, REG_RCX); + host_x86_PXOR_XREG_XREG(block, dest_reg, REG_XMM_TEMP); } # ifdef RECOMPILER_DEBUG else diff --git a/src/codegen_new/codegen_backend_x86_uops.c b/src/codegen_new/codegen_backend_x86_uops.c index 02c441234..fad088822 100644 --- a/src/codegen_new/codegen_backend_x86_uops.c +++ b/src/codegen_new/codegen_backend_x86_uops.c @@ -221,6 +221,7 @@ codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data); host_x86_CALL(block, uop->p); host_x86_TEST32_REG(block, REG_EAX, REG_EAX); host_x86_JNZ(block, codegen_exit_rout); diff --git a/src/codegen_new/codegen_ir.c b/src/codegen_new/codegen_ir.c index ed8ae051f..d14fa0f23 100644 --- a/src/codegen_new/codegen_ir.c +++ b/src/codegen_new/codegen_ir.c @@ -38,7 +38,7 @@ codegen_ir_set_unroll(int count, int start, int first_instruction) static void duplicate_uop(ir_data_t *ir, uop_t *uop, int offset) { - uop_t *new_uop = uop_alloc(ir, uop->type); + uop_t *new_uop = uop_alloc_unroll(ir, uop->type); if (!ir_reg_is_invalid(uop->src_reg_a)) new_uop->src_reg_a = codegen_reg_read(uop->src_reg_a.reg); diff --git a/src/codegen_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h index d55e57f3d..60f7badea 100644 --- a/src/codegen_new/codegen_ir_defs.h +++ b/src/codegen_new/codegen_ir_defs.h @@ -41,8 +41,8 @@ #define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a | UOP_TYPE_BARRIER) #define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b | UOP_TYPE_BARRIER) #define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER) -/*UOP_CALL_INSTRUCTION_FUNC - call instruction handler at p, check return value and exit block if non-zero*/ -#define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER) +/*UOP_CALL_INSTRUCTION_FUNC - call instruction handler at p with fetchdat, check return value and exit block if non-zero*/ +#define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | UOP_TYPE_PARAMS_IMM | 0x11 | UOP_TYPE_BARRIER) #define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12) #define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) /*UOP_LOAD_SEG - load segment in src_reg_a to segment p via loadseg(), check return value and exit block if non-zero*/ @@ -377,6 +377,34 @@ uop_alloc(ir_data_t *ir, uint32_t uop_type) uop->jump_dest_uop = -1; uop->jump_list_next = -1; + if (uop_type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER)) + dirty_ir_regs[0] = dirty_ir_regs[1] = ~0ULL; + + return uop; +} + +static inline uop_t * +uop_alloc_unroll(ir_data_t *ir, uint32_t uop_type) +{ + uop_t *uop; + + if (ir->wr_pos >= UOP_NR_MAX) + fatal("Exceeded uOP max\n"); + + uop = &ir->uops[ir->wr_pos++]; + + uop->is_a16 = 0; + + uop->dest_reg_a = invalid_ir_reg; + uop->src_reg_a = invalid_ir_reg; + uop->src_reg_b = invalid_ir_reg; + uop->src_reg_c = invalid_ir_reg; + + uop->pc = cpu_state.oldpc; + + uop->jump_dest_uop = -1; + uop->jump_list_next = -1; + if (uop_type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER)) codegen_reg_mark_as_required(); @@ -662,7 +690,7 @@ uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int sr #define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) #define uop_CALL_FUNC_RESULT(ir, dst_reg, p) uop_gen_reg_dst_pointer(UOP_CALL_FUNC_RESULT, ir, dst_reg, p) -#define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) +#define uop_CALL_INSTRUCTION_FUNC(ir, p, imm) uop_gen_pointer_imm(UOP_CALL_INSTRUCTION_FUNC, ir, p, imm) #define uop_CMP_IMM_JZ(ir, src_reg, imm, p) uop_gen_reg_src_pointer_imm(UOP_CMP_IMM_JZ, ir, src_reg, p, imm) diff --git a/src/codegen_new/codegen_ops_stack.c b/src/codegen_new/codegen_ops_stack.c index fca9c9efa..f93289197 100644 --- a/src/codegen_new/codegen_ops_stack.c +++ b/src/codegen_new/codegen_ops_stack.c @@ -390,6 +390,8 @@ ropPUSHF(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUS uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); uop_CALL_FUNC(ir, flags_rebuild); sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_AND_IMM(ir, IREG_flags, IREG_flags, 0x7fd5); + uop_OR_IMM(ir, IREG_flags, IREG_flags, 0x0002); uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); SUB_SP(ir, 2); @@ -406,6 +408,8 @@ ropPUSHFD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNU uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); uop_CALL_FUNC(ir, flags_rebuild); + uop_AND_IMM(ir, IREG_flags, IREG_flags, 0x7fd5); + uop_OR_IMM(ir, IREG_flags, IREG_flags, 0x0002); if (cpu_CR4_mask & CR4_VME) uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x3c); else if (CPUID) diff --git a/src/codegen_new/codegen_reg.c b/src/codegen_new/codegen_reg.c index 75cf25ded..f91377df8 100644 --- a/src/codegen_new/codegen_reg.c +++ b/src/codegen_new/codegen_reg.c @@ -34,6 +34,8 @@ typedef struct host_reg_set_t { static host_reg_set_t host_reg_set; static host_reg_set_t host_fp_reg_set; +uint64_t dirty_ir_regs[2] = { 0, 0 }; + enum { REG_BYTE, REG_WORD, @@ -184,15 +186,36 @@ struct [IREG_temp1d] = { REG_DOUBLE, (void *) 48, REG_FP, REG_VOLATILE }, }; +static const uint8_t native_requested_sizes[9][8] = +{ + [REG_BYTE][IREG_SIZE_B >> IREG_SIZE_SHIFT] = 1, + [REG_FPU_ST_BYTE][IREG_SIZE_B >> IREG_SIZE_SHIFT] = 1, + [REG_WORD][IREG_SIZE_W >> IREG_SIZE_SHIFT] = 1, + [REG_DWORD][IREG_SIZE_L >> IREG_SIZE_SHIFT] = 1, + [REG_QWORD][IREG_SIZE_D >> IREG_SIZE_SHIFT] = 1, + [REG_FPU_ST_QWORD][IREG_SIZE_D >> IREG_SIZE_SHIFT] = 1, + [REG_DOUBLE][IREG_SIZE_D >> IREG_SIZE_SHIFT] = 1, + [REG_FPU_ST_DOUBLE][IREG_SIZE_D >> IREG_SIZE_SHIFT] = 1, + [REG_QWORD][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, + [REG_FPU_ST_QWORD][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, + [REG_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, + [REG_FPU_ST_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, + + [REG_POINTER][(sizeof(void *) == 4) ? (IREG_SIZE_L >> IREG_SIZE_SHIFT) : (IREG_SIZE_Q >> IREG_SIZE_SHIFT)] = 1 +}; + void codegen_reg_mark_as_required(void) { - for (uint8_t reg = 0; reg < IREG_COUNT; reg++) { + /* This used to start from IREG_EAX, now only starts from IREG_ESP since the first 4 registers are never optimized out. */ + /* It also no longer iterates through volatile registers unnecessarily. */ + for (uint8_t reg = IREG_ESP; reg < IREG_temp0; reg++) { int last_version = reg_last_version[reg]; - if (last_version > 0 && ireg_data[reg].is_volatile == REG_PERMANENT) + if (last_version > 0) reg_version[reg][last_version].flags |= REG_FLAGS_REQUIRED; } + dirty_ir_regs[0] = dirty_ir_regs[1] = 0; } int @@ -201,29 +224,7 @@ reg_is_native_size(ir_reg_t ir_reg) int native_size = ireg_data[IREG_GET_REG(ir_reg.reg)].native_size; int requested_size = IREG_GET_SIZE(ir_reg.reg); - switch (native_size) { - case REG_BYTE: - case REG_FPU_ST_BYTE: - return (requested_size == IREG_SIZE_B); - case REG_WORD: - return (requested_size == IREG_SIZE_W); - case REG_DWORD: - return (requested_size == IREG_SIZE_L); - case REG_QWORD: - case REG_FPU_ST_QWORD: - case REG_DOUBLE: - case REG_FPU_ST_DOUBLE: - return ((requested_size == IREG_SIZE_D) || (requested_size == IREG_SIZE_Q)); - case REG_POINTER: - if (sizeof(void *) == 4) - return (requested_size == IREG_SIZE_L); - return (requested_size == IREG_SIZE_Q); - - default: - fatal("get_reg_is_native_size: unknown native size %i\n", native_size); - } - - return 0; + return native_requested_sizes[native_size][requested_size >> IREG_SIZE_SHIFT]; } void @@ -256,6 +257,8 @@ codegen_reg_reset(void) host_fp_reg_set.locked = 0; host_fp_reg_set.nr_regs = CODEGEN_HOST_FP_REGS; + dirty_ir_regs[0] = dirty_ir_regs[1] = 0; + for (c = 0; c < IREG_COUNT; c++) { reg_last_version[c] = 0; reg_version[c][0].refcount = 0; diff --git a/src/codegen_new/codegen_reg.h b/src/codegen_new/codegen_reg.h index 2185fde45..a86bcd1cf 100644 --- a/src/codegen_new/codegen_reg.h +++ b/src/codegen_new/codegen_reg.h @@ -16,59 +16,45 @@ #define IREG_SIZE_Q (5 << IREG_SIZE_SHIFT) enum { - IREG_EAX = 0, - IREG_ECX = 1, - IREG_EDX = 2, - IREG_EBX = 3, - IREG_ESP = 4, - IREG_EBP = 5, - IREG_ESI = 6, - IREG_EDI = 7, + IREG_EAX, + IREG_ECX, + IREG_EDX, + IREG_EBX, + IREG_ESP, + IREG_EBP, + IREG_ESI, + IREG_EDI, - IREG_flags_op = 8, - IREG_flags_res = 9, - IREG_flags_op1 = 10, - IREG_flags_op2 = 11, + IREG_flags_op, + IREG_flags_res, + IREG_flags_op1, + IREG_flags_op2, - IREG_pc = 12, - IREG_oldpc = 13, + IREG_pc, + IREG_oldpc, - IREG_eaaddr = 14, - IREG_ea_seg = 15, - IREG_op32 = 16, - IREG_ssegsx = 17, + IREG_eaaddr, + IREG_ea_seg, + IREG_op32, + IREG_ssegsx, - IREG_rm_mod_reg = 18, + IREG_rm_mod_reg, - IREG_acycs = 19, - IREG_cycles = 20, + IREG_cycles, - IREG_CS_base = 21, - IREG_DS_base = 22, - IREG_ES_base = 23, - IREG_FS_base = 24, - IREG_GS_base = 25, - IREG_SS_base = 26, + IREG_CS_base, + IREG_DS_base, + IREG_ES_base, + IREG_FS_base, + IREG_GS_base, + IREG_SS_base, - IREG_CS_seg = 27, - IREG_DS_seg = 28, - IREG_ES_seg = 29, - IREG_FS_seg = 30, - IREG_GS_seg = 31, - IREG_SS_seg = 32, - - /*Temporary registers are stored on the stack, and are not guaranteed to - be preserved across uOPs. They will not be written back if they will - not be read again.*/ - IREG_temp0 = 33, - IREG_temp1 = 34, - IREG_temp2 = 35, - IREG_temp3 = 36, - - IREG_FPU_TOP = 37, - - IREG_temp0d = 38, - IREG_temp1d = 39, + IREG_CS_seg, + IREG_DS_seg, + IREG_ES_seg, + IREG_FS_seg, + IREG_GS_seg, + IREG_SS_seg, /*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag() to access. @@ -76,66 +62,79 @@ enum { used directly to index the stack. When it is clear, the difference between the current value of TOP and the value when the block was first compiled will be added to adjust for any changes in TOP.*/ - IREG_ST0 = 40, - IREG_ST1 = 41, - IREG_ST2 = 42, - IREG_ST3 = 43, - IREG_ST4 = 44, - IREG_ST5 = 45, - IREG_ST6 = 46, - IREG_ST7 = 47, + IREG_ST0, + IREG_ST1, + IREG_ST2, + IREG_ST3, + IREG_ST4, + IREG_ST5, + IREG_ST6, + IREG_ST7, - IREG_tag0 = 48, - IREG_tag1 = 49, - IREG_tag2 = 50, - IREG_tag3 = 51, - IREG_tag4 = 52, - IREG_tag5 = 53, - IREG_tag6 = 54, - IREG_tag7 = 55, + IREG_tag0, + IREG_tag1, + IREG_tag2, + IREG_tag3, + IREG_tag4, + IREG_tag5, + IREG_tag6, + IREG_tag7, - IREG_ST0_i64 = 56, - IREG_ST1_i64 = 57, - IREG_ST2_i64 = 58, - IREG_ST3_i64 = 59, - IREG_ST4_i64 = 60, - IREG_ST5_i64 = 61, - IREG_ST6_i64 = 62, - IREG_ST7_i64 = 63, + IREG_ST0_i64, + IREG_ST1_i64, + IREG_ST2_i64, + IREG_ST3_i64, + IREG_ST4_i64, + IREG_ST5_i64, + IREG_ST6_i64, + IREG_ST7_i64, - IREG_MM0x = 64, - IREG_MM1x = 65, - IREG_MM2x = 66, - IREG_MM3x = 67, - IREG_MM4x = 68, - IREG_MM5x = 69, - IREG_MM6x = 70, - IREG_MM7x = 71, + IREG_MM0x, + IREG_MM1x, + IREG_MM2x, + IREG_MM3x, + IREG_MM4x, + IREG_MM5x, + IREG_MM6x, + IREG_MM7x, - IREG_NPXCx = 72, - IREG_NPXSx = 73, + IREG_NPXCx, + IREG_NPXSx, - IREG_flagsx = 74, - IREG_eflagsx = 75, + IREG_flagsx, + IREG_eflagsx, - IREG_CS_limit_low = 76, - IREG_DS_limit_low = 77, - IREG_ES_limit_low = 78, - IREG_FS_limit_low = 79, - IREG_GS_limit_low = 80, - IREG_SS_limit_low = 81, + IREG_CS_limit_low, + IREG_DS_limit_low, + IREG_ES_limit_low, + IREG_FS_limit_low, + IREG_GS_limit_low, + IREG_SS_limit_low, - IREG_CS_limit_high = 82, - IREG_DS_limit_high = 83, - IREG_ES_limit_high = 84, - IREG_FS_limit_high = 85, - IREG_GS_limit_high = 86, - IREG_SS_limit_high = 87, + IREG_CS_limit_high, + IREG_DS_limit_high, + IREG_ES_limit_high, + IREG_FS_limit_high, + IREG_GS_limit_high, + IREG_SS_limit_high, - IREG_eaa16 = 88, - IREG_x87_op = 89, + IREG_eaa16, + IREG_x87_op, - IREG_COUNT = 90, + IREG_FPU_TOP, + + /*Temporary registers are stored on the stack, and are not guaranteed to + be preserved across uOPs. They will not be written back if they will + not be read again.*/ + IREG_temp0, + IREG_temp1, + IREG_temp2, + IREG_temp3, + + IREG_temp0d, + IREG_temp1d, + + IREG_COUNT, IREG_INVALID = 255, @@ -279,6 +278,7 @@ ireg_seg_limit_high(x86seg *seg) } extern uint8_t reg_last_version[IREG_COUNT]; +extern uint64_t dirty_ir_regs[2]; /*This version of the register must be calculated, regardless of whether it is apparently required or not. Do not optimise out.*/ @@ -363,10 +363,12 @@ codegen_reg_write(int reg, int uop_nr) int last_version = reg_last_version[IREG_GET_REG(reg)]; reg_version_t *version; -#ifndef RELEASE_BUILD - if (IREG_GET_REG(reg) == IREG_INVALID) - fatal("codegen_reg_write - IREG_INVALID\n"); -#endif + if (dirty_ir_regs[(IREG_GET_REG(reg) >> 6) & 3] & (1ull << ((uint64_t)IREG_GET_REG(reg) & 0x3full))) { + dirty_ir_regs[(IREG_GET_REG(reg) >> 6) & 3] &= ~(1ull << ((uint64_t)IREG_GET_REG(reg) & 0x3full)); + if ((IREG_GET_REG(reg) > IREG_EBX && IREG_GET_REG(reg) < IREG_temp0) && last_version > 0) { + reg_version[IREG_GET_REG(reg)][last_version].flags |= REG_FLAGS_REQUIRED; + } + } ireg.reg = reg; ireg.version = last_version + 1; @@ -376,12 +378,8 @@ codegen_reg_write(int reg, int uop_nr) } reg_last_version[IREG_GET_REG(reg)]++; -#ifndef RELEASE_BUILD - if (!reg_last_version[IREG_GET_REG(reg)]) - fatal("codegen_reg_write - version overflow\n"); - else -#endif - if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX) + + if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX) CPU_BLOCK_END(); if (reg_last_version[IREG_GET_REG(reg)] > max_version_refcount) max_version_refcount = reg_last_version[IREG_GET_REG(reg)]; diff --git a/src/config.c b/src/config.c index f3d771e30..77b796117 100644 --- a/src/config.c +++ b/src/config.c @@ -46,6 +46,7 @@ #include <86box/ini.h> #include <86box/config.h> #include <86box/isamem.h> +#include <86box/isarom.h> #include <86box/isartc.h> #include <86box/lpt.h> #include <86box/serial.h> @@ -55,6 +56,7 @@ #include <86box/fdd.h> #include <86box/fdc_ext.h> #include <86box/gameport.h> +#include <86box/keyboard.h> #include <86box/serial_passthrough.h> #include <86box/machine.h> #include <86box/mouse.h> @@ -64,7 +66,7 @@ #include <86box/scsi_device.h> #include <86box/cdrom.h> #include <86box/cdrom_interface.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/mo.h> #include <86box/sound.h> #include <86box/midi.h> @@ -127,8 +129,6 @@ load_global(void) confirm_exit = ini_section_get_int(cat, "confirm_exit", 1); confirm_save = ini_section_get_int(cat, "confirm_save", 1); - video_fullscreen_first = ini_section_get_int(cat, "video_fullscreen_first", 1); - inhibit_multimedia_keys = ini_section_get_int(cat, "inhibit_multimedia_keys", 0); mouse_sensitivity = ini_section_get_double(cat, "mouse_sensitivity", 1.0); @@ -171,6 +171,8 @@ load_general(void) video_grayscale = ini_section_get_int(cat, "video_grayscale", 0); video_graytype = ini_section_get_int(cat, "video_graytype", 0); + force_10ms = !!ini_section_get_int(cat, "force_10ms", 0); + rctrl_is_lalt = ini_section_get_int(cat, "rctrl_is_lalt", 0); update_icons = ini_section_get_int(cat, "update_icons", 1); @@ -272,7 +274,9 @@ load_machine(void) if (p != NULL) { migrate_from = p; /* Migrate renamed machines. */ - if (!strcmp(p, "430nx")) + if (!strcmp(p, "tandy")) + machine = machine_get_machine_from_internal_name("tandy1000sx"); + else if (!strcmp(p, "430nx")) machine = machine_get_machine_from_internal_name("586ip"); else if (!strcmp(p, "586mc1")) machine = machine_get_machine_from_internal_name("586is"); @@ -458,9 +462,6 @@ load_video(void) 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_standalone_enabled = !!ini_section_get_int(cat, "8514a", 0); @@ -488,6 +489,25 @@ load_input_devices(void) char temp[512]; char *p; + p = ini_section_get_string(cat, "keyboard_type", NULL); + if (p != NULL) + keyboard_type = keyboard_get_from_internal_name(p); + else if (strstr(machine_get_internal_name(), "pc5086")) + keyboard_type = KEYBOARD_TYPE_PC_XT; + else if (machine_has_bus(machine, MACHINE_BUS_PS2_PORTS)) { + if (machine_has_flags(machine, MACHINE_KEYBOARD_JIS)) + keyboard_type = KEYBOARD_TYPE_PS55; + else + keyboard_type = KEYBOARD_TYPE_PS2; + } else if (machine_has_bus(machine, MACHINE_BUS_ISA16) || + machine_has_bus(machine, MACHINE_BUS_PCI)) { + if (machine_has_flags(machine, MACHINE_KEYBOARD_JIS)) + keyboard_type = KEYBOARD_TYPE_AX; + else + keyboard_type = KEYBOARD_TYPE_AT; + } else + keyboard_type = KEYBOARD_TYPE_PC_XT; + p = ini_section_get_string(cat, "mouse_type", NULL); if (p != NULL) mouse_type = mouse_get_from_internal_name(p); @@ -667,8 +687,14 @@ load_network(void) 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")) + else if (!strcmp(p, "vde") || !strcmp(p, "3")) nc->net_type = NET_TYPE_VDE; + else if (!strcmp(p, "tap") || !strcmp(p, "4")) + nc->net_type = NET_TYPE_TAP; + else if (!strcmp(p, "nmswitch") || !strcmp(p, "5")) + nc->net_type = NET_TYPE_NMSWITCH; + else if (!strcmp(p, "nrswitch") || !strcmp(p, "6")) + nc->net_type = NET_TYPE_NRSWITCH; else nc->net_type = NET_TYPE_NONE; } else @@ -713,13 +739,18 @@ load_network(void) 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")) + else if (!strcmp(p, "vde") || !strcmp(p, "3")) nc->net_type = NET_TYPE_VDE; + else if (!strcmp(p, "tap") || !strcmp(p, "4")) + nc->net_type = NET_TYPE_TAP; + else if (!strcmp(p, "nmswitch") || !strcmp(p, "5")) + nc->net_type = NET_TYPE_NMSWITCH; + else if (!strcmp(p, "nrswitch") || !strcmp(p, "6")) + nc->net_type = NET_TYPE_NRSWITCH; 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) { @@ -737,6 +768,19 @@ load_network(void) } else strcpy(nc->host_dev_name, "none"); + sprintf(temp, "net_%02i_switch_group", c + 1); + net_cards_conf[c].switch_group = ini_section_get_int(cat, temp, 0); + + sprintf(temp, "net_%02i_promisc", c + 1); + net_cards_conf[c].promisc_mode = ini_section_get_int(cat, temp, 0); + + sprintf(temp, "net_%02i_nrs_host", c + 1); + p = ini_section_get_string(cat, temp, NULL); + if (p != NULL) + strncpy(net_cards_conf[c].nrs_hostname, p, sizeof(net_cards_conf[c].nrs_hostname) - 1); + else + strncpy(net_cards_conf[c].nrs_hostname, "", sizeof(net_cards_conf[c].nrs_hostname) - 1); + sprintf(temp, "net_%02i_link", c + 1); nc->link_state = ini_section_get_int(cat, temp, (NET_LINK_10_HD | NET_LINK_10_FD | @@ -770,8 +814,8 @@ load_ports(void) lpt_ports[c].enabled = !!ini_section_get_int(cat, temp, (c == 0) ? 1 : 0); sprintf(temp, "lpt%d_device", c + 1); - p = ini_section_get_string(cat, temp, "none"); - lpt_ports[c].device = lpt_device_get_from_internal_name(p); + p = ini_section_get_string(cat, temp, "none"); + lpt_ports[c].device = lpt_device_get_from_internal_name(p); } #if 0 @@ -797,6 +841,37 @@ load_ports(void) #endif } +static int +load_image_file(char *dest, char *p, uint8_t *ui_wp) +{ + char *prefix = ""; + int ret = 0; + + if (strstr(p, "wp://") == p) { + p += 5; + prefix = "wp://"; + if (ui_wp != NULL) + *ui_wp = 1; + } else if ((ui_wp != NULL) && *ui_wp) + prefix = "wp://"; + + if (path_abs(p)) { + if ((strlen(prefix) + strlen(p)) > (MAX_IMAGE_PATH_LEN - 1)) + ret = 1; + else + snprintf(dest, MAX_IMAGE_PATH_LEN, "%s%s", prefix, p); + } else { + if ((strlen(prefix) + strlen(usr_path) + strlen(path_get_slash(usr_path)) + strlen(p)) > (MAX_IMAGE_PATH_LEN - 1)) + ret = 1; + else + snprintf(dest, MAX_IMAGE_PATH_LEN, "%s%s%s%s", prefix, usr_path, path_get_slash(usr_path), p); + } + + path_normalize(dest); + + return ret; +} + /* Load "Storage Controllers" section. */ static void load_storage_controllers(void) @@ -806,7 +881,6 @@ load_storage_controllers(void) char *p; char temp[512]; int min = 0; - int free_p = 0; for (int c = min; c < SCSI_CARD_MAX; c++) { sprintf(temp, "scsicard_%d", c + 1); @@ -825,6 +899,8 @@ load_storage_controllers(void) else fdc_current[0] = FDC_INTERNAL; #else + int free_p = 0; + if (p == NULL) { if (machine_has_flags(machine, MACHINE_FDC)) { p = (char *) malloc((strlen("internal") + 1) * sizeof(char)); @@ -845,65 +921,70 @@ load_storage_controllers(void) } #endif - 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; - } - /* Migrate renamed and merged cards. */ - if (!strcmp(p, "xtide_plus")) { - hdc_current[0] = hdc_get_from_internal_name("xtide"); - migration_cat = ini_find_or_create_section(config, "PC/XT XTIDE"); - ini_section_set_string(migration_cat, "bios", "xt_plus"); - } else if (!strcmp(p, "xtide_at_386")) { - hdc_current[0] = hdc_get_from_internal_name("xtide_at"); - migration_cat = ini_find_or_create_section(config, "PC/AT XTIDE"); - ini_section_set_string(migration_cat, "bios", "at_386"); - } else - hdc_current[0] = hdc_get_from_internal_name(p); + for (int c = min; c < HDC_MAX; c++) { + sprintf(temp, "hdc_%d", c + 1); - if (free_p) { - free(p); - p = NULL; + p = ini_section_get_string(cat, temp, NULL); + if (p != NULL) + hdc_current[c] = hdc_get_from_internal_name(p); + else + hdc_current[c] = 0; } + /* Backwards compatibility for single HDC and standalone tertiary/quaternary IDE from v4.2 and older. */ + const char *legacy_cards[] = { NULL, "ide_ter", "ide_qua" }; + p = ini_section_get_string(cat, "hdc", NULL); + for (int i = !(p || machine_has_flags(machine, MACHINE_HDC)), j = 0; i < (sizeof(legacy_cards) / sizeof(legacy_cards[0])); i++) { + if (!legacy_cards[i] || (ini_section_get_int(cat, legacy_cards[i], 0) == 1)) { + /* Migrate to the first available HDC slot. */ + for (; j < (sizeof(hdc_current) / sizeof(hdc_current[0])); j++) { + if (!hdc_current[j]) { + if (!legacy_cards[i]) { + if (!p) { + hdc_current[j] = hdc_get_from_internal_name("internal"); + } else if (!strcmp(p, "xtide_plus")) { + hdc_current[j] = hdc_get_from_internal_name("xtide"); + sprintf(temp, "PC/XT XTIDE #%i", j + 1); + migration_cat = ini_find_or_create_section(config, temp); + ini_section_set_string(migration_cat, "bios", "xt_plus"); + } else if (!strcmp(p, "xtide_at_386")) { + hdc_current[j] = hdc_get_from_internal_name("xtide_at"); + sprintf(temp, "PC/AT XTIDE #%i", j + 1); + migration_cat = ini_find_or_create_section(config, temp); + ini_section_set_string(migration_cat, "bios", "at_386"); + } else { + hdc_current[j] = hdc_get_from_internal_name(p); + } + } else { + hdc_current[j] = hdc_get_from_internal_name(legacy_cards[i]); + } + break; + } + } + } + } + ini_section_delete_var(cat, "hdc"); + p = ini_section_get_string(cat, "cdrom_interface", NULL); if (p != NULL) cdrom_interface_current = cdrom_interface_get_from_internal_name(p); - if (free_p) { - free(p); - p = NULL; - } - - ide_ter_enabled = !!ini_section_get_int(cat, "ide_ter", 0); - ide_qua_enabled = !!ini_section_get_int(cat, "ide_qua", 0); - if (machine_has_bus(machine, MACHINE_BUS_CASSETTE)) cassette_enable = !!ini_section_get_int(cat, "cassette_enabled", 0); else cassette_enable = 0; + cassette_ui_writeprot = !!ini_section_get_int(cat, "cassette_writeprot", 0); + ini_section_delete_var(cat, "cassette_writeprot"); + p = ini_section_get_string(cat, "cassette_file", ""); if (!strcmp(p, usr_path)) p[0] = 0x00; if (p[0] != 0x00) { - if (path_abs(p)) { - if (strlen(p) > 511) - fatal("Configuration: Length of cassette_file is more than 511\n"); - else - strncpy(cassette_fname, p, 511); - } else - path_append_filename(cassette_fname, usr_path, p); - path_normalize(cassette_fname); + if (load_image_file(cassette_fname, p, (uint8_t *) &cassette_ui_writeprot)) + fatal("Configuration: Length of cassette_file is more than 511\n"); } p = ini_section_get_string(cat, "cassette_mode", "load"); @@ -917,16 +998,9 @@ load_storage_controllers(void) sprintf(temp, "cassette_image_history_%02i", 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("Configuration: Length of cassette_image_history_%02i is more " - "than %i\n", i + 1, MAX_IMAGE_PATH_LEN - 1); - else - snprintf(cassette_image_history[i], MAX_IMAGE_PATH_LEN, "%s", p); - } else - snprintf(cassette_image_history[i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path, - path_get_slash(usr_path), p); - path_normalize(cassette_image_history[i]); + if (load_image_file(cassette_image_history[i], p, NULL)) + fatal("Configuration: Length of cassette_image_history_%02i is more " + "than %i\n", i + 1, MAX_IMAGE_PATH_LEN - 1); } } cassette_pos = ini_section_get_int(cat, "cassette_position", 0); @@ -941,9 +1015,6 @@ load_storage_controllers(void) cassette_pcm = ini_section_get_int(cat, "cassette_pcm", 0); if (!cassette_pcm) ini_section_delete_var(cat, "cassette_pcm"); - cassette_ui_writeprot = !!ini_section_get_int(cat, "cassette_writeprot", 0); - if (!cassette_ui_writeprot) - ini_section_delete_var(cat, "cassette_writeprot"); if (!cassette_enable) { ini_section_delete_var(cat, "cassette_file"); @@ -996,11 +1067,6 @@ load_storage_controllers(void) } } } - - lba_enhancer_enabled = !!ini_section_get_int(cat, "lba_enhancer_enabled", 0); - - if (!lba_enhancer_enabled) - ini_section_delete_var(cat, "lba_enhancer_enabled"); } /* Load "Hard Disks" section. */ @@ -1217,17 +1283,28 @@ load_floppy_and_cdrom_drives(void) unsigned int board = 0; unsigned int dev = 0; int c; - int d = 0; + int d; int count = cdrom_get_type_count(); memset(temp, 0x00, sizeof(temp)); for (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 (!strcmp(p, "525_2hd_ps2")) + d = fdd_get_from_internal_name("525_2hd"); + else if (!strcmp(p, "35_2hd_ps2")) + d = fdd_get_from_internal_name("35_2hd"); + else + d = fdd_get_from_internal_name(p); + fdd_set_type(c, d); if (fdd_get_type(c) > 13) fdd_set_type(c, 13); + sprintf(temp, "fdd_%02i_writeprot", c + 1); + ui_writeprot[c] = !!ini_section_get_int(cat, temp, 0); + if (ui_writeprot[c] == 0) + ini_section_delete_var(cat, temp); + sprintf(temp, "fdd_%02i_fn", c + 1); p = ini_section_get_string(cat, temp, ""); @@ -1235,22 +1312,14 @@ load_floppy_and_cdrom_drives(void) p[0] = 0x00; if (p[0] != 0x00) { - if (path_abs(p)) { - if (strlen(p) > 511) - fatal("Configuration: Length of fdd_%02i_fn is more than 511\n", c + 1); - else - strncpy(floppyfns[c], p, 511); - } else - path_append_filename(floppyfns[c], usr_path, p); - path_normalize(floppyfns[c]); + if (load_image_file(floppyfns[c], p, (uint8_t *) &(ui_writeprot[c]))) + fatal("Configuration: Length of fdd_%02i_fn is more than 511\n", c + 1); } #if defined(ENABLE_CONFIG_LOG) && (ENABLE_CONFIG_LOG == 2) if (*p != '\0') config_log("Floppy%d: %ls\n", c, floppyfns[c]); #endif - sprintf(temp, "fdd_%02i_writeprot", c + 1); - ui_writeprot[c] = !!ini_section_get_int(cat, temp, 0); sprintf(temp, "fdd_%02i_turbo", c + 1); fdd_set_turbo(c, !!ini_section_get_int(cat, temp, 0)); sprintf(temp, "fdd_%02i_check_bpb", c + 1); @@ -1266,10 +1335,6 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%02i_fn", c + 1); ini_section_delete_var(cat, temp); } - if (ui_writeprot[c] == 0) { - sprintf(temp, "fdd_%02i_writeprot", c + 1); - ini_section_delete_var(cat, temp); - } if (fdd_get_turbo(c) == 0) { sprintf(temp, "fdd_%02i_turbo", c + 1); ini_section_delete_var(cat, temp); @@ -1283,16 +1348,9 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%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("Configuration: Length of fdd_%02i_image_history_%02i is more " - "than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); - else - snprintf(fdd_image_history[c][i], MAX_IMAGE_PATH_LEN, "%s", p); - } else - snprintf(fdd_image_history[c][i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path, - path_get_slash(usr_path), p); - path_normalize(fdd_image_history[c][i]); + if (load_image_file(fdd_image_history[c][i], p, NULL)) + fatal("Configuration: Length of fdd_%02i_image_history_%02i is more " + "than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); } } } @@ -1303,6 +1361,7 @@ load_floppy_and_cdrom_drives(void) ini_section_delete_var(cat, temp); sprintf(temp, "cdrom_%02i_parameters", c + 1); + d = 0; p = ini_section_get_string(cat, temp, NULL); if (p != NULL) sscanf(p, "%01u, %s", &d, s); @@ -1318,7 +1377,7 @@ load_floppy_and_cdrom_drives(void) cdrom[c].speed = ini_section_get_int(cat, temp, 8); sprintf(temp, "cdrom_%02i_type", c + 1); - p = ini_section_get_string(cat, temp, "86cd"); + p = ini_section_get_string(cat, temp, cdrom[c].bus_type == CDROM_BUS_MKE ? "cr563" : "86cd"); /* TODO: Configuration migration, remove when no longer needed. */ int cdrom_type = cdrom_get_from_internal_name(p); if (cdrom_type == -1) { @@ -1335,11 +1394,23 @@ load_floppy_and_cdrom_drives(void) 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; + cdrom[c].mke_channel = cdrom[c].ide_channel = cdrom[c].scsi_device_id = c & 3; - if (cdrom[c].bus_type == CDROM_BUS_ATAPI) { + if (cdrom[c].bus_type == CDROM_BUS_MKE) { + char *type = cdrom_get_internal_name(cdrom_get_type(c)); + + if (strstr(type, "cr56") == NULL) + cdrom_set_type(c, cdrom_get_from_internal_name("cr563_075")); + + sprintf(temp, "cdrom_%02i_mke_channel", c + 1); + cdrom[c].mke_channel = ini_section_get_int(cat, temp, c & 3); + + if (cdrom[c].mke_channel > 3) + cdrom[c].mke_channel = 3; + + } else 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); + sprintf(tmp2, "%01u:%01u", (c & 3) >> 1, (c & 3) & 1); p = ini_section_get_string(cat, temp, tmp2); sscanf(p, "%01u:%01u", &board, &dev); board &= 3; @@ -1350,13 +1421,13 @@ load_floppy_and_cdrom_drives(void) cdrom[c].ide_channel = 7; } else if (cdrom[c].bus_type == CDROM_BUS_SCSI) { sprintf(temp, "cdrom_%02i_scsi_location", c + 1); - sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2); + sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c & 3); p = ini_section_get_string(cat, temp, tmp2); sscanf(p, "%01u:%02u", &board, &dev); if (board >= SCSI_BUS_MAX) { /* Invalid bus - check legacy ID */ sprintf(temp, "cdrom_%02i_scsi_id", c + 1); - cdrom[c].scsi_device_id = ini_section_get_int(cat, temp, c + 2); + cdrom[c].scsi_device_id = ini_section_get_int(cat, temp, c & 3); if (cdrom[c].scsi_device_id > 15) cdrom[c].scsi_device_id = 15; @@ -1367,6 +1438,11 @@ load_floppy_and_cdrom_drives(void) } } + if (cdrom[c].bus_type != CDROM_BUS_MKE) { + sprintf(temp, "cdrom_%02i_mke_channel", c + 1); + ini_section_delete_var(cat, temp); + } + if (cdrom[c].bus_type != CDROM_BUS_ATAPI) { sprintf(temp, "cdrom_%02i_ide_channel", c + 1); ini_section_delete_var(cat, temp); @@ -1458,32 +1534,35 @@ load_other_removable_devices(void) unsigned int board = 0; unsigned int dev = 0; int c; + int legacy_zip_drives = 0; memset(temp, 0x00, sizeof(temp)); - for (c = 0; c < ZIP_NUM; c++) { + for (c = 0; c < RDISK_NUM; c++) { sprintf(temp, "zip_%02i_parameters", c + 1); p = ini_section_get_string(cat, temp, NULL); - if (p != NULL) - sscanf(p, "%01u, %s", &zip_drives[c].is_250, s); - else - sscanf("0, none", "%01u, %s", &zip_drives[c].is_250, s); - zip_drives[c].bus_type = hdd_string_to_bus(s, 1); + if (p != NULL) { + sscanf(p, "%01u, %s", &rdisk_drives[c].type, s); + legacy_zip_drives++; + } else + sscanf("0, none", "%01u, %s", &rdisk_drives[c].type, s); + rdisk_drives[c].type++; + rdisk_drives[c].bus_type = hdd_string_to_bus(s, 1); /* Default values, needed for proper operation of the Settings dialog. */ - zip_drives[c].ide_channel = zip_drives[c].scsi_device_id = c + 2; + rdisk_drives[c].ide_channel = rdisk_drives[c].scsi_device_id = c + 2; - if (zip_drives[c].bus_type == ZIP_BUS_ATAPI) { + if (rdisk_drives[c].bus_type == RDISK_BUS_ATAPI) { sprintf(temp, "zip_%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; - zip_drives[c].ide_channel = (board << 1) + dev; + rdisk_drives[c].ide_channel = (board << 1) + dev; - if (zip_drives[c].ide_channel > 7) - zip_drives[c].ide_channel = 7; - } else if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { + if (rdisk_drives[c].ide_channel > 7) + rdisk_drives[c].ide_channel = 7; + } else if (rdisk_drives[c].bus_type == RDISK_BUS_SCSI) { sprintf(temp, "zip_%02i_scsi_location", c + 1); sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2); p = ini_section_get_string(cat, temp, tmp2); @@ -1491,23 +1570,23 @@ load_other_removable_devices(void) if (board >= SCSI_BUS_MAX) { /* Invalid bus - check legacy ID */ sprintf(temp, "zip_%02i_scsi_id", c + 1); - zip_drives[c].scsi_device_id = ini_section_get_int(cat, temp, c + 2); + rdisk_drives[c].scsi_device_id = ini_section_get_int(cat, temp, c + 2); - if (zip_drives[c].scsi_device_id > 15) - zip_drives[c].scsi_device_id = 15; + if (rdisk_drives[c].scsi_device_id > 15) + rdisk_drives[c].scsi_device_id = 15; } else { board %= SCSI_BUS_MAX; dev &= 15; - zip_drives[c].scsi_device_id = (board << 4) + dev; + rdisk_drives[c].scsi_device_id = (board << 4) + dev; } } - if (zip_drives[c].bus_type != ZIP_BUS_ATAPI) { + if (rdisk_drives[c].bus_type != RDISK_BUS_ATAPI) { sprintf(temp, "zip_%02i_ide_channel", c + 1); ini_section_delete_var(cat, temp); } - if (zip_drives[c].bus_type != ZIP_BUS_SCSI) { + if (rdisk_drives[c].bus_type != RDISK_BUS_SCSI) { sprintf(temp, "zip_%02i_scsi_location", c + 1); ini_section_delete_var(cat, temp); } @@ -1517,60 +1596,156 @@ load_other_removable_devices(void) sprintf(temp, "zip_%02i_image_path", c + 1); p = ini_section_get_string(cat, temp, ""); + + sprintf(temp, "zip_%02i_writeprot", c + 1); + rdisk_drives[c].read_only = ini_section_get_int(cat, temp, 0); + ini_section_delete_var(cat, temp); if (!strcmp(p, usr_path)) p[0] = 0x00; if (p[0] != 0x00) { - if (path_abs(p)) { - if (strlen(p) > 511) - fatal("Configuration: Length of zip_%02i_image_path is more than 511\n", c + 1); - 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); + if (load_image_file(rdisk_drives[c].image_path, p, &(rdisk_drives[c].read_only))) + fatal("Configuration: Length of zip_%02i_image_path is more than 511\n", c + 1); } 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)); + rdisk_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("Configuration: Length of zip_%02i_image_history_%02i is more than %i\n", - c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); - else - snprintf(zip_drives[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s", p); - } else - snprintf(zip_drives[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path, - path_get_slash(usr_path), p); - path_normalize(zip_drives[c].image_history[i]); + if (load_image_file(rdisk_drives[c].image_history[i], p, NULL)) + fatal("Configuration: Length of zip_%02i_image_history_%02i is more than %i\n", + c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); } } - /* If the ZIP drive is disabled, delete all its variables. */ - if (zip_drives[c].bus_type == ZIP_BUS_DISABLED) { - sprintf(temp, "zip_%02i_parameters", c + 1); + sprintf(temp, "zip_%02i_parameters", c + 1); + ini_section_delete_var(cat, temp); + + sprintf(temp, "zip_%02i_ide_channel", c + 1); + ini_section_delete_var(cat, temp); + + sprintf(temp, "zip_%02i_scsi_location", c + 1); + ini_section_delete_var(cat, temp); + + sprintf(temp, "zip_%02i_image_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); + } + } + + if (legacy_zip_drives > 0) + goto go_to_mo; + + memset(temp, 0x00, sizeof(temp)); + for (c = 0; c < RDISK_NUM; c++) { + sprintf(temp, "rdisk_%02i_parameters", c + 1); + p = ini_section_get_string(cat, temp, NULL); + if (p != NULL) { + sscanf(p, "%01u, %s", &rdisk_drives[c].type, s); + legacy_zip_drives++; + } else + sscanf("0, none", "%01u, %s", &rdisk_drives[c].type, s); + rdisk_drives[c].bus_type = hdd_string_to_bus(s, 1); + + /* Default values, needed for proper operation of the Settings dialog. */ + rdisk_drives[c].ide_channel = rdisk_drives[c].scsi_device_id = c + 2; + + if (rdisk_drives[c].bus_type == RDISK_BUS_ATAPI) { + sprintf(temp, "rdisk_%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; + rdisk_drives[c].ide_channel = (board << 1) + dev; + + if (rdisk_drives[c].ide_channel > 7) + rdisk_drives[c].ide_channel = 7; + } else if (rdisk_drives[c].bus_type == RDISK_BUS_SCSI) { + sprintf(temp, "rdisk_%02i_scsi_location", c + 1); + sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2); + p = ini_section_get_string(cat, temp, tmp2); + sscanf(p, "%01u:%02u", &board, &dev); + if (board >= SCSI_BUS_MAX) { + /* Invalid bus - check legacy ID */ + sprintf(temp, "rdisk_%02i_scsi_id", c + 1); + rdisk_drives[c].scsi_device_id = ini_section_get_int(cat, temp, c + 2); + + if (rdisk_drives[c].scsi_device_id > 15) + rdisk_drives[c].scsi_device_id = 15; + } else { + board %= SCSI_BUS_MAX; + dev &= 15; + rdisk_drives[c].scsi_device_id = (board << 4) + dev; + } + } + + if (rdisk_drives[c].bus_type != RDISK_BUS_ATAPI) { + sprintf(temp, "rdisk_%02i_ide_channel", c + 1); + ini_section_delete_var(cat, temp); + } + + if (rdisk_drives[c].bus_type != RDISK_BUS_SCSI) { + sprintf(temp, "rdisk_%02i_scsi_location", c + 1); + ini_section_delete_var(cat, temp); + } + + sprintf(temp, "rdisk_%02i_scsi_id", c + 1); + ini_section_delete_var(cat, temp); + + sprintf(temp, "rdisk_%02i_image_path", c + 1); + p = ini_section_get_string(cat, temp, ""); + + sprintf(temp, "rdisk_%02i_writeprot", c + 1); + rdisk_drives[c].read_only = ini_section_get_int(cat, temp, 0); + ini_section_delete_var(cat, temp); + + if (!strcmp(p, usr_path)) + p[0] = 0x00; + + if (p[0] != 0x00) { + if (load_image_file(rdisk_drives[c].image_path, p, &(rdisk_drives[c].read_only))) + fatal("Configuration: Length of rdisk_%02i_image_path is more than 511\n", c + 1); + } + + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + rdisk_drives[c].image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char)); + sprintf(temp, "rdisk_%02i_image_history_%02i", c + 1, i + 1); + p = ini_section_get_string(cat, temp, NULL); + if (p) { + if (load_image_file(rdisk_drives[c].image_history[i], p, NULL)) + fatal("Configuration: Length of rdisk_%02i_image_history_%02i is more than %i\n", + c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); + } + } + + /* If the removable disk drive is disabled, delete all its variables. */ + if (rdisk_drives[c].bus_type == RDISK_BUS_DISABLED) { + sprintf(temp, "rdisk_%02i_parameters", c + 1); ini_section_delete_var(cat, temp); - sprintf(temp, "zip_%02i_ide_channel", c + 1); + sprintf(temp, "rdisk_%02i_ide_channel", c + 1); ini_section_delete_var(cat, temp); - sprintf(temp, "zip_%02i_scsi_location", c + 1); + sprintf(temp, "rdisk_%02i_scsi_location", c + 1); ini_section_delete_var(cat, temp); - sprintf(temp, "zip_%02i_image_path", c + 1); + sprintf(temp, "rdisk_%02i_image_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); + sprintf(temp, "rdisk_%02i_image_history_%02i", c + 1, i + 1); ini_section_delete_var(cat, temp); } } } +go_to_mo: memset(temp, 0x00, sizeof(temp)); for (c = 0; c < MO_NUM; c++) { sprintf(temp, "mo_%02i_parameters", c + 1); @@ -1630,18 +1805,16 @@ load_other_removable_devices(void) sprintf(temp, "mo_%02i_image_path", c + 1); p = ini_section_get_string(cat, temp, ""); + sprintf(temp, "mo_%02i_writeprot", c + 1); + mo_drives[c].read_only = ini_section_get_int(cat, temp, 0); + ini_section_delete_var(cat, temp); + if (!strcmp(p, usr_path)) p[0] = 0x00; if (p[0] != 0x00) { - if (path_abs(p)) { - if (strlen(p) > 511) - fatal("Configuration: Length of mo_%02i_image_path is more than 511\n", c + 1); - 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); + if (load_image_file(mo_drives[c].image_path, p, &(mo_drives[c].read_only))) + fatal("Configuration: Length of mo_%02i_image_path is more than 511\n", c + 1); } for (int i = 0; i < MAX_PREV_IMAGES; i++) { @@ -1649,16 +1822,9 @@ load_other_removable_devices(void) 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("Configuration: Length of mo_%02i_image_history_%02i is more than %i\n", - c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); - else - snprintf(mo_drives[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s", p); - } else - snprintf(mo_drives[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path, - path_get_slash(usr_path), p); - path_normalize(mo_drives[c].image_history[i]); + if (load_image_file(mo_drives[c].image_history[i], p, NULL)) + fatal("Configuration: Length of mo_%02i_image_history_%02i is more than %i\n", + c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); } } @@ -1709,6 +1875,7 @@ load_other_peripherals(void) if (!novell_keycard_enabled) ini_section_delete_var(cat, "novell_keycard_enabled"); + // ISA RAM Boards for (uint8_t c = 0; c < ISAMEM_MAX; c++) { sprintf(temp, "isamem%d_type", c); @@ -1719,6 +1886,28 @@ load_other_peripherals(void) ini_section_delete_var(cat, temp); } + // ISA ROM Boards + for (uint8_t c = 0; c < ISAROM_MAX; c++) { + sprintf(temp, "isarom%d_type", c); + + p = ini_section_get_string(cat, temp, "none"); + isarom_type[c] = isarom_get_from_internal_name(p); + + if (!strcmp(p, "none")) + ini_section_delete_var(cat, temp); + } + + /* Backwards compatibility for standalone LBA Enhancer from v4.2 and older. */ + if (ini_section_get_int(ini_find_section(config, "Storage controllers"), "lba_enhancer_enabled", 0) == 1) { + /* Migrate to the first available ISA ROM slot. */ + for (uint8_t c = 0; c < ISAROM_MAX; c++) { + if (!isarom_type[c]) { + isarom_type[c] = isarom_get_from_internal_name("lba_enhancer"); + break; + } + } + } + p = ini_section_get_string(cat, "isartc_type", "none"); isartc_type = isartc_get_from_internal_name(p); @@ -1829,7 +2018,7 @@ config_load(void) #ifdef USE_IOCTL memset(cdrom_ioctl, 0, sizeof(cdrom_ioctl_t) * CDROM_NUM); #endif - memset(zip_drives, 0, sizeof(zip_drive_t)); + memset(rdisk_drives, 0, sizeof(rdisk_drive_t)); config = ini_read(cfg_path); @@ -1853,10 +2042,13 @@ config_load(void) gfxcard[0] = video_get_video_from_internal_name("cga"); vid_api = plat_vidapi("default"); vid_resize = 0; - video_fullscreen_first = 1; video_fullscreen_scale = 1; time_sync = TIME_SYNC_ENABLED; - hdc_current[0] = hdc_get_from_internal_name("none"); + + keyboard_type = KEYBOARD_TYPE_PC_XT; + + for (int i = 0; i < HDC_MAX; i++) + hdc_current[i] = hdc_get_from_internal_name("none"); com_ports[0].enabled = 1; com_ports[1].enabled = 1; @@ -1882,6 +2074,8 @@ config_load(void) cdrom[0].sound_on = 1; mem_size = 64; isartc_type = 0; + for (i = 0; i < ISAROM_MAX; i++) + isarom_type[i] = 0; for (i = 0; i < ISAMEM_MAX; i++) isamem_type[i] = 0; @@ -1975,11 +2169,6 @@ save_global(void) else ini_section_delete_var(cat, "confirm_save"); - if (video_fullscreen_first == 1) - ini_section_delete_var(cat, "video_fullscreen_first"); - else - ini_section_set_int(cat, "video_fullscreen_first", video_fullscreen_first); - if (inhibit_multimedia_keys == 1) ini_section_set_int(cat, "inhibit_multimedia_keys", inhibit_multimedia_keys); else @@ -2000,6 +2189,10 @@ save_general(void) const char *va_name; + ini_section_set_int(cat, "force_10ms", force_10ms); + if (force_10ms == 0) + ini_section_delete_var(cat, "force_10ms"); + ini_section_set_int(cat, "sound_muted", sound_muted); if (sound_muted == 0) ini_section_delete_var(cat, "sound_muted"); @@ -2286,6 +2479,8 @@ save_input_devices(void) char temp[512]; char tmp2[512]; + ini_section_set_string(cat, "keyboard_type", keyboard_get_internal_name(keyboard_type)); + ini_section_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type)); if (!joystick_type) { @@ -2453,7 +2648,15 @@ save_network(void) case NET_TYPE_VDE: ini_section_set_string(cat, temp, "vde"); break; - + case NET_TYPE_TAP: + ini_section_set_string(cat, temp, "tap"); + break; + case NET_TYPE_NMSWITCH: + ini_section_set_string(cat, temp, "nmswitch"); + break; + case NET_TYPE_NRSWITCH: + ini_section_set_string(cat, temp, "nrswitch"); + break; default: break; } @@ -2474,6 +2677,28 @@ save_network(void) ini_section_delete_var(cat, temp); else ini_section_set_int(cat, temp, nc->link_state); + + sprintf(temp, "net_%02i_switch_group", c + 1); + if (nc->device_num == 0) + ini_section_delete_var(cat, temp); + else + ini_section_set_int(cat, temp, net_cards_conf[c].switch_group); + + sprintf(temp, "net_%02i_promisc", c + 1); + if (nc->device_num == 0) + ini_section_delete_var(cat, temp); + else + ini_section_set_int(cat, temp, net_cards_conf[c].promisc_mode); + + sprintf(temp, "net_%02i_nrs_host", c + 1); + if (nc->device_num == 0) + ini_section_delete_var(cat, temp); + else { + if (nc->nrs_hostname[0] != '\0') + ini_section_set_string(cat, temp, net_cards_conf[c].nrs_hostname); + else + ini_section_delete_var(cat, temp); + } } ini_delete_section_if_empty(config, cat); @@ -2512,8 +2737,7 @@ save_ports(void) if (lpt_ports[c].device == 0) ini_section_delete_var(cat, temp); else - ini_section_set_string(cat, temp, - lpt_device_get_internal_name(lpt_ports[c].device)); + ini_section_set_string(cat, temp, lpt_device_get_internal_name(lpt_ports[c].device)); } #if 0 @@ -2567,6 +2791,27 @@ save_keybinds(void) ini_delete_section_if_empty(config, cat); } +static void +save_image_file(char *cat, char *var, char *src) +{ + char temp[2048] = { 0 }; + char *prefix = ""; + + path_normalize(src); + + if (strstr(src, "wp://") == src) { + src += 5; + prefix = "wp://"; + } + + if (!strnicmp(src, usr_path, strlen(usr_path))) + sprintf(temp, "%s%s", prefix, &src[strlen(usr_path)]); + else + sprintf(temp, "%s%s", prefix, src); + + ini_section_set_string(cat, var, temp); +} + /* Save "Storage Controllers" section. */ static void save_storage_controllers(void) @@ -2594,16 +2839,39 @@ save_storage_controllers(void) ini_section_set_string(cat, "fdc", fdc_card_get_internal_name(fdc_current[0])); - if (machine_has_flags(machine, MACHINE_HDC)) - def_hdc = "internal"; - else - def_hdc = "none"; + ini_section_delete_var(cat, "hdc"); - if (!strcmp(hdc_get_internal_name(hdc_current[0]), def_hdc)) - ini_section_delete_var(cat, "hdc"); - else - ini_section_set_string(cat, "hdc", - hdc_get_internal_name(hdc_current[0])); + for (c = 0; c < HDC_MAX; c++) { + sprintf(temp, "hdc_%d", c + 1); + + if ((c == 0) && machine_has_flags(machine, MACHINE_HDC)) + def_hdc = "internal"; + else + def_hdc = "none"; + + if (!strcmp(hdc_get_internal_name(hdc_current[c]), def_hdc)) + ini_section_delete_var(cat, temp); + else + ini_section_set_string(cat, temp, + hdc_get_internal_name(hdc_current[c])); + } + + /* Downgrade compatibility for standalone tertiary/quaternary IDE from v4.2 and older. */ + const char *legacy_cards[] = { "ide_ter", "ide_qua" }; + for (int i = 0; i < (sizeof(legacy_cards) / sizeof(legacy_cards[0])); i++) { + int card_id = hdc_get_from_internal_name(legacy_cards[i]); + for (int j = 0; j < (sizeof(sound_card_current) / sizeof(sound_card_current[0])); j++) { + if (hdc_current[j] == card_id) { + /* A special value of 2 still enables the cards on older versions, + but lets newer versions know that they've already been migrated. */ + ini_section_set_int(cat, legacy_cards[i], 2); + card_id = 0; /* mark as found */ + break; + } + } + if (card_id > 0) /* not found */ + ini_section_delete_var(cat, legacy_cards[i]); + } if (cdrom_interface_current == 0) ini_section_delete_var(cat, "cdrom_interface"); @@ -2611,16 +2879,6 @@ save_storage_controllers(void) ini_section_set_string(cat, "cdrom_interface", cdrom_interface_get_internal_name(cdrom_interface_current)); - if (ide_ter_enabled == 0) - ini_section_delete_var(cat, "ide_ter"); - else - ini_section_set_int(cat, "ide_ter", ide_ter_enabled); - - if (ide_qua_enabled == 0) - ini_section_delete_var(cat, "ide_qua"); - else - ini_section_set_int(cat, "ide_qua", ide_qua_enabled); - if (cassette_enable == 0) ini_section_delete_var(cat, "cassette_enabled"); else @@ -2628,13 +2886,8 @@ save_storage_controllers(void) if (strlen(cassette_fname) == 0) ini_section_delete_var(cat, "cassette_file"); - else { - path_normalize(cassette_fname); - if (!strnicmp(cassette_fname, usr_path, strlen(usr_path))) - ini_section_set_string(cat, "cassette_file", &cassette_fname[strlen(usr_path)]); - else - ini_section_set_string(cat, "cassette_file", cassette_fname); - } + else + save_image_file(cat, "cassette_file", cassette_fname); if (!strcmp(cassette_mode, "load")) ini_section_delete_var(cat, "cassette_mode"); @@ -2645,13 +2898,8 @@ save_storage_controllers(void) sprintf(temp, "cassette_image_history_%02i", i + 1); if ((cassette_image_history[i] == 0) || strlen(cassette_image_history[i]) == 0) ini_section_delete_var(cat, temp); - else { - path_normalize(cassette_image_history[i]); - if (!strnicmp(cassette_image_history[i], usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &cassette_image_history[i][strlen(usr_path)]); - else - ini_section_set_string(cat, temp, cassette_image_history[i]); - } + else + save_image_file(cat, temp, cassette_image_history[i]); } if (cassette_pos == 0) @@ -2674,10 +2922,7 @@ save_storage_controllers(void) else ini_section_set_int(cat, "cassette_pcm", cassette_pcm); - if (cassette_ui_writeprot == 0) - ini_section_delete_var(cat, "cassette_writeprot"); - else - ini_section_set_int(cat, "cassette_writeprot", cassette_ui_writeprot); + ini_section_delete_var(cat, "cassette_writeprot"); for (c = 0; c < 2; c++) { sprintf(temp, "cartridge_%02i_fn", c + 1); @@ -2706,10 +2951,19 @@ save_storage_controllers(void) } } - if (lba_enhancer_enabled == 0) + /* Downgrade compatibility for standalone LBA Enhancer from v4.2 and older. */ + int card_id = isarom_get_from_internal_name("lba_enhancer"); + for (c = 0; c < ISAROM_MAX; c++) { + if (isarom_type[c] == card_id) { + /* A special value of 2 still enables the cards on older versions, + but lets newer versions know that they've already been migrated. */ + ini_section_set_int(cat, "lba_enhancer_enabled", 2); + card_id = 0; /* mark as found */ + break; + } + } + if (card_id > 0) /* not found */ ini_section_delete_var(cat, "lba_enhancer_enabled"); - else - ini_section_set_int(cat, "lba_enhancer_enabled", 1); ini_delete_section_if_empty(config, cat); } @@ -2741,6 +2995,7 @@ save_other_peripherals(void) else ini_section_set_int(cat, "novell_keycard_enabled", novell_keycard_enabled); + // ISA RAM Boards for (uint8_t c = 0; c < ISAMEM_MAX; c++) { sprintf(temp, "isamem%d_type", c); if (isamem_type[c] == 0) @@ -2750,6 +3005,16 @@ save_other_peripherals(void) isamem_get_internal_name(isamem_type[c])); } + // ISA ROM Boards + for (uint8_t c = 0; c < ISAROM_MAX; c++) { + sprintf(temp, "isarom%d_type", c); + if (isarom_type[c] == 0) + ini_section_delete_var(cat, temp); + else + ini_section_set_string(cat, temp, + isarom_get_internal_name(isarom_type[c])); + } + if (isartc_type == 0) ini_section_delete_var(cat, "isartc_type"); else @@ -2912,19 +3177,11 @@ save_floppy_and_cdrom_drives(void) sprintf(temp, "fdd_%02i_writeprot", c + 1); ini_section_delete_var(cat, temp); - } else { - 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]); - } + } else + save_image_file(cat, temp, floppyfns[c]); sprintf(temp, "fdd_%02i_writeprot", c + 1); - if (ui_writeprot[c] == 0) - ini_section_delete_var(cat, temp); - else - ini_section_set_int(cat, temp, ui_writeprot[c]); + ini_section_delete_var(cat, temp); sprintf(temp, "fdd_%02i_turbo", c + 1); if (fdd_get_turbo(c) == 0) @@ -2942,13 +3199,8 @@ save_floppy_and_cdrom_drives(void) 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) ini_section_delete_var(cat, temp); - 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]); - } + else + save_image_file(cat, temp, fdd_image_history[c][i]); } } @@ -2964,8 +3216,7 @@ save_floppy_and_cdrom_drives(void) sprintf(temp, "cdrom_%02i_type", c + 1); char *tn = cdrom_get_internal_name(cdrom_get_type(c)); - if ((cdrom[c].bus_type == 0) || (cdrom[c].bus_type == CDROM_BUS_MITSUMI) || - !strcmp(tn, "86cd")) + if ((cdrom[c].bus_type == 0) || (cdrom[c].bus_type == CDROM_BUS_MITSUMI) || !strcmp(tn, "86cd")) ini_section_delete_var(cat, temp); else ini_section_set_string(cat, temp, tn); @@ -2984,6 +3235,13 @@ save_floppy_and_cdrom_drives(void) ini_section_set_string(cat, temp, tmp2); } + sprintf(temp, "cdrom_%02i_mke_channel", c + 1); + if (cdrom[c].bus_type != CDROM_BUS_MKE) + ini_section_delete_var(cat, temp); + else { + ini_section_set_int(cat, temp, cdrom[c].mke_channel); + } + sprintf(temp, "cdrom_%02i_ide_channel", c + 1); if (cdrom[c].bus_type != CDROM_BUS_ATAPI) ini_section_delete_var(cat, temp); @@ -3042,59 +3300,52 @@ save_other_removable_devices(void) char tmp2[512]; int c; - for (c = 0; c < ZIP_NUM; c++) { - sprintf(temp, "zip_%02i_parameters", c + 1); - if (zip_drives[c].bus_type == 0) { + for (c = 0; c < RDISK_NUM; c++) { + sprintf(temp, "rdisk_%02i_parameters", c + 1); + if (rdisk_drives[c].bus_type == 0) { ini_section_delete_var(cat, temp); } else { - sprintf(tmp2, "%u, %s", zip_drives[c].is_250, - hdd_bus_to_string(zip_drives[c].bus_type, 1)); + sprintf(tmp2, "%u, %s", rdisk_drives[c].type, + hdd_bus_to_string(rdisk_drives[c].bus_type, 1)); ini_section_set_string(cat, temp, tmp2); } - sprintf(temp, "zip_%02i_ide_channel", c + 1); - if (zip_drives[c].bus_type != ZIP_BUS_ATAPI) + sprintf(temp, "rdisk_%02i_ide_channel", c + 1); + if (rdisk_drives[c].bus_type != RDISK_BUS_ATAPI) ini_section_delete_var(cat, temp); else { - sprintf(tmp2, "%01u:%01u", zip_drives[c].ide_channel >> 1, - zip_drives[c].ide_channel & 1); + sprintf(tmp2, "%01u:%01u", rdisk_drives[c].ide_channel >> 1, + rdisk_drives[c].ide_channel & 1); ini_section_set_string(cat, temp, tmp2); } - sprintf(temp, "zip_%02i_scsi_id", c + 1); + sprintf(temp, "rdisk_%02i_scsi_id", c + 1); ini_section_delete_var(cat, temp); - sprintf(temp, "zip_%02i_scsi_location", c + 1); - if (zip_drives[c].bus_type != ZIP_BUS_SCSI) + sprintf(temp, "rdisk_%02i_writeprot", c + 1); + ini_section_delete_var(cat, temp); + + sprintf(temp, "rdisk_%02i_scsi_location", c + 1); + if (rdisk_drives[c].bus_type != RDISK_BUS_SCSI) ini_section_delete_var(cat, temp); else { - sprintf(tmp2, "%01u:%02u", zip_drives[c].scsi_device_id >> 4, - zip_drives[c].scsi_device_id & 15); + sprintf(tmp2, "%01u:%02u", rdisk_drives[c].scsi_device_id >> 4, + rdisk_drives[c].scsi_device_id & 15); ini_section_set_string(cat, temp, tmp2); } - sprintf(temp, "zip_%02i_image_path", c + 1); - if ((zip_drives[c].bus_type == 0) || (strlen(zip_drives[c].image_path) == 0)) + sprintf(temp, "rdisk_%02i_image_path", c + 1); + if ((rdisk_drives[c].bus_type == 0) || (strlen(rdisk_drives[c].image_path) == 0)) ini_section_delete_var(cat, temp); - 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); - } + else + save_image_file(cat, temp, rdisk_drives[c].image_path); for (int i = 0; i < MAX_PREV_IMAGES; i++) { - sprintf(temp, "zip_%02i_image_history_%02i", c + 1, i + 1); - if ((zip_drives[c].image_history[i] == 0) || strlen(zip_drives[c].image_history[i]) == 0) + sprintf(temp, "rdisk_%02i_image_history_%02i", c + 1, i + 1); + if ((rdisk_drives[c].image_history[i] == 0) || strlen(rdisk_drives[c].image_history[i]) == 0) ini_section_delete_var(cat, temp); - else { - path_normalize(zip_drives[c].image_history[i]); - if (!strnicmp(zip_drives[c].image_history[i], usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &zip_drives[c].image_history[i][strlen(usr_path)]); - else - ini_section_set_string(cat, temp, zip_drives[c].image_history[i]); - } + else + save_image_file(cat, temp, rdisk_drives[c].image_history[i]); } } @@ -3120,6 +3371,9 @@ save_other_removable_devices(void) sprintf(temp, "mo_%02i_scsi_id", c + 1); ini_section_delete_var(cat, temp); + sprintf(temp, "mo_%02i_writeprot", c + 1); + ini_section_delete_var(cat, temp); + sprintf(temp, "mo_%02i_scsi_location", c + 1); if (mo_drives[c].bus_type != MO_BUS_SCSI) ini_section_delete_var(cat, temp); @@ -3132,25 +3386,15 @@ 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)) ini_section_delete_var(cat, temp); - 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); - } + else + save_image_file(cat, temp, mo_drives[c].image_path); for (int i = 0; i < MAX_PREV_IMAGES; i++) { sprintf(temp, "mo_%02i_image_history_%02i", c + 1, i + 1); if ((mo_drives[c].image_history[i] == 0) || strlen(mo_drives[c].image_history[i]) == 0) ini_section_delete_var(cat, temp); - else { - path_normalize(mo_drives[c].image_history[i]); - if (!strnicmp(mo_drives[c].image_history[i], usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &mo_drives[c].image_history[i][strlen(usr_path)]); - else - ini_section_set_string(cat, temp, mo_drives[c].image_history[i]); - } + else + save_image_file(cat, temp, mo_drives[c].image_history[i]); } } diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index fd6285057..23f3f1e35 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -739,7 +739,7 @@ exec386_dynarec(int32_t cycs) uint64_t oldtsc; uint64_t delta; - int32_t cyc_period = cycs / 2000; /*5us*/ + int32_t cyc_period = cycs / (force_10ms ? 2000 : 200); /*5us*/ # ifdef USE_ACYCS acycs = 0; diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 5113ca817..73626acd2 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -264,6 +264,7 @@ opVPCEXT(uint32_t fetchdat) uint8_t b2; uint16_t cent; time_t now; + struct tm tm_buf; struct tm *tm = NULL; if (!is_vpc) /* only emulate this on Virtual PC machines */ @@ -282,7 +283,16 @@ opVPCEXT(uint32_t fetchdat) /* 0f 3f 03 xx opcodes are mostly related to the host clock, so fetch it now */ if (b1 == 0x03) { (void) time(&now); - tm = localtime(&now); + +#ifdef _WIN32 + if (localtime_s(&tm_buf, &now) == 0) + tm = &tm_buf; +#else + tm = localtime_r(&now, &tm_buf); +#endif + + if (!tm) + fatal("localtime() failed for host clock\n"); } if ((b1 == 0x07) && (b2 == 0x0b)) { diff --git a/src/cpu/808x.c b/src/cpu/808x.c index dda688ee1..14e56f23a 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -90,44 +90,44 @@ static bool cpu_md_write_disable = 1; #define fetch_ea_32(val) #define PREFETCH_RUN(a, b, c, d, e, f, g, h) -#define CYCLES(val) \ - { \ - wait(val, 0); \ +#define CYCLES(val) \ + { \ + wait_cycs(val, 0); \ } #define CLOCK_CYCLES_ALWAYS(val) \ { \ - wait(val, 0); \ + wait_cycs(val, 0); \ } #if 0 # define CLOCK_CYCLES_FPU(val) \ { \ - wait(val, 0); \ + wait_cycs(val, 0); \ } -# define CLOCK_CYCLES(val) \ - { \ - if (fpu_cycles > 0) { \ - fpu_cycles -= (val); \ - if (fpu_cycles < 0) { \ - wait(val, 0); \ - } \ - } else { \ - wait(val, 0); \ - } \ +# define CLOCK_CYCLES(val) \ + { \ + if (fpu_cycles > 0) { \ + fpu_cycles -= (val); \ + if (fpu_cycles < 0) { \ + wait_cycs(val, 0); \ + } \ + } else { \ + wait_cycs(val, 0); \ + } \ } # define CONCURRENCY_CYCLES(c) fpu_cycles = (c) #else -# define CLOCK_CYCLES(val) \ - { \ - wait(val, 0); \ +# define CLOCK_CYCLES(val) \ + { \ + wait_cycs(val, 0); \ } # define CLOCK_CYCLES_FPU(val) \ { \ - wait(val, 0); \ + wait_cycs(val, 0); \ } # define CONCURRENCY_CYCLES(c) @@ -298,7 +298,7 @@ fetch_and_bus(int c, int bus) } static void -wait(int c, int bus) +wait_cycs(int c, int bus) { cycles -= c; fetch_and_bus(c, bus); @@ -340,13 +340,13 @@ cpu_io(int bits, int out, uint16_t port) int old_cycles = cycles; if (out) { - wait(is_mazovia ? 5 : 4, 1); + wait_cycs(is_mazovia ? 5 : 4, 1); if (bits == 16) { if (is8086 && !(port & 1)) { old_cycles = cycles; outw(port, AX); } else { - wait(is_mazovia ? 5 : 4, 1); + wait_cycs(is_mazovia ? 5 : 4, 1); old_cycles = cycles; outb(port++, AL); outb(port, AH); @@ -356,13 +356,13 @@ cpu_io(int bits, int out, uint16_t port) outb(port, AL); } } else { - wait(is_mazovia ? 5 : 4, 1); + wait_cycs(is_mazovia ? 5 : 4, 1); if (bits == 16) { if (is8086 && !(port & 1)) { old_cycles = cycles; AX = inw(port); } else { - wait(is_mazovia ? 5 : 4, 1); + wait_cycs(is_mazovia ? 5 : 4, 1); old_cycles = cycles; AL = inb(port++); AH = inb(port); @@ -382,7 +382,7 @@ readmemb(uint32_t a) { uint8_t ret; - wait(4, 1); + wait_cycs(4, 1); ret = read_mem_b(a); return ret; @@ -406,11 +406,11 @@ readmemw(uint32_t s, uint16_t a) { uint16_t ret; - wait(4, 1); + wait_cycs(4, 1); if (is8086 && !(a & 1)) ret = read_mem_w(s + a); else { - wait(4, 1); + wait_cycs(4, 1); ret = read_mem_b(s + a); ret |= read_mem_b(s + ((is186 && !is_nec) ? (a + 1) : (a + 1) & 0xffff)) << 8; } @@ -465,7 +465,7 @@ writememb(uint32_t s, uint32_t a, uint8_t v) { uint32_t addr = s + a; - wait(4, 1); + wait_cycs(4, 1); write_mem_b(addr, v); if ((addr >= 0xf0000) && (addr <= 0xfffff)) @@ -478,12 +478,12 @@ writememw(uint32_t s, uint32_t a, uint16_t v) { uint32_t addr = s + a; - wait(4, 1); + wait_cycs(4, 1); if (is8086 && !(a & 1)) write_mem_w(addr, v); else { write_mem_b(addr, v & 0xff); - wait(4, 1); + wait_cycs(4, 1); addr = s + ((is186 && !is_nec) ? (a + 1) : ((a + 1) & 0xffff)); write_mem_b(addr, v >> 8); } @@ -539,10 +539,9 @@ pfq_write(void) static uint8_t pfq_read(void) { - uint8_t temp, i; + uint8_t temp = pfq[0]; - temp = pfq[0]; - for (i = 0; i < (pfq_size - 1); i++) + for (int i = 0; i < (pfq_size - 1); i++) pfq[i] = pfq[i + 1]; pfq_pos--; cpu_state.pc = (cpu_state.pc + 1) & 0xffff; @@ -560,7 +559,7 @@ pfq_fetchb_common(void) /* Reset prefetch queue internal position. */ pfq_ip = cpu_state.pc; /* Fill the queue. */ - wait(4 - (biu_cycles & 3), 0); + wait_cycs(4 - (biu_cycles & 3), 0); } /* Fetch. */ @@ -574,7 +573,7 @@ pfq_fetchb(void) uint8_t ret; ret = pfq_fetchb_common(); - wait(1, 0); + wait_cycs(1, 0); return ret; } @@ -586,7 +585,7 @@ pfq_fetchw(void) uint16_t temp; temp = pfq_fetchb_common(); - wait(1, 0); + wait_cycs(1, 0); temp |= (pfq_fetchb_common() << 8); return temp; @@ -760,38 +759,38 @@ do_mod_rm(void) if (cpu_mod == 3) return; - wait(1, 0); + wait_cycs(1, 0); if ((rmdat & 0xc7) == 0x06) { - wait(1, 0); + wait_cycs(1, 0); cpu_state.eaaddr = pfq_fetchw(); easeg = ovr_seg ? *ovr_seg : ds; - wait(1, 0); + wait_cycs(1, 0); return; } else switch (cpu_rm) { case 0: case 3: - wait(2, 0); + wait_cycs(2, 0); break; case 1: case 2: - wait(3, 0); + wait_cycs(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(3, 0); + wait_cycs(3, 0); cpu_state.eaaddr += sign_extend(pfq_fetchb()); break; case 0x80: - wait(3, 0); + wait_cycs(3, 0); cpu_state.eaaddr += pfq_fetchw(); break; } cpu_state.eaaddr &= 0xffff; - wait(2, 0); + wait_cycs(2, 0); } #undef getr8 @@ -983,7 +982,7 @@ access(int num, UNUSED(int bits)) case 62: case 66: case 68: - wait(1, 0); + wait_cycs(1, 0); break; case 3: case 11: @@ -999,7 +998,7 @@ access(int num, UNUSED(int bits)) case 52: case 53: case 54: - wait(2, 0); + wait_cycs(2, 0); break; case 16: case 18: @@ -1008,7 +1007,7 @@ access(int num, UNUSED(int bits)) case 32: case 37: case 42: - wait(3, 0); + wait_cycs(3, 0); break; case 10: case 12: @@ -1021,59 +1020,59 @@ access(int num, UNUSED(int bits)) case 39: case 41: case 60: - wait(4, 0); + wait_cycs(4, 0); break; case 4: case 70: - wait(5, 0); + wait_cycs(5, 0); break; case 31: case 38: case 40: - wait(6, 0); + wait_cycs(6, 0); break; case 5: if (opcode == 0xcc) - wait(7, 0); + wait_cycs(7, 0); else - wait(4, 0); + wait_cycs(4, 0); break; case 36: - wait(1, 0); + wait_cycs(1, 0); pfq_clear(); - wait(1, 0); + wait_cycs(1, 0); if (cpu_mod != 3) - wait(1, 0); - wait(3, 0); + wait_cycs(1, 0); + wait_cycs(3, 0); break; case 43: - wait(2, 0); + wait_cycs(2, 0); pfq_clear(); - wait(1, 0); + wait_cycs(1, 0); break; case 57: if (cpu_mod != 3) - wait(2, 0); - wait(4, 0); + wait_cycs(2, 0); + wait_cycs(4, 0); break; case 58: if (cpu_mod != 3) - wait(1, 0); - wait(4, 0); + wait_cycs(1, 0); + wait_cycs(4, 0); break; case 59: - wait(2, 0); + wait_cycs(2, 0); pfq_clear(); if (cpu_mod != 3) - wait(1, 0); - wait(3, 0); + wait_cycs(1, 0); + wait_cycs(3, 0); break; case 65: - wait(1, 0); + wait_cycs(1, 0); pfq_clear(); - wait(2, 0); + wait_cycs(2, 0); if (cpu_mod != 3) - wait(1, 0); + wait_cycs(1, 0); break; } } @@ -1096,7 +1095,7 @@ interrupt(uint16_t addr) old_cs = CS; access(5, 16); new_ip = readmemw(0, cpu_state.eaaddr); - wait(1, 0); + wait_cycs(1, 0); cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; access(6, 16); new_cs = readmemw(0, cpu_state.eaaddr); @@ -1132,7 +1131,7 @@ interrupt_brkem(uint16_t addr) old_cs = CS; access(5, 16); new_ip = readmemw(0, cpu_state.eaaddr); - wait(1, 0); + wait_cycs(1, 0); cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; access(6, 16); new_cs = readmemw(0, cpu_state.eaaddr); @@ -1201,7 +1200,7 @@ custom_nmi(void) access(5, 16); (void) readmemw(0, cpu_state.eaaddr); new_ip = custom_nmi_vector & 0xffff; - wait(1, 0); + wait_cycs(1, 0); cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; access(6, 16); (void) readmemw(0, cpu_state.eaaddr); @@ -1226,22 +1225,24 @@ custom_nmi(void) } static int -irq_pending(void) +irq_pending(int nec_hlt) { uint8_t temp; + int i_flag = (cpu_state.flags & I_FLAG) || nec_hlt; - temp = (nmi && nmi_enable && nmi_mask) || ((cpu_state.flags & T_FLAG) && !noint) || ((cpu_state.flags & I_FLAG) && pic.int_pending && !noint); + temp = (nmi && nmi_enable && nmi_mask) || ((cpu_state.flags & T_FLAG) && !noint) || (i_flag && pic.int_pending && !noint); return temp; } static void -check_interrupts(void) +check_interrupts(int nec_hlt) { int temp; + int i_flag = (cpu_state.flags & I_FLAG) || nec_hlt; - if (irq_pending()) { - if ((cpu_state.flags & T_FLAG) && !noint) { + if (irq_pending(nec_hlt)) { + if ((cpu_state.flags & T_FLAG) && !(noint & 1)) { interrupt(1); return; } @@ -1256,24 +1257,24 @@ check_interrupts(void) #endif return; } - if ((cpu_state.flags & I_FLAG) && pic.int_pending && !noint) { + if (i_flag && pic.int_pending && !noint) { repeating = 0; completed = 1; ovr_seg = NULL; - wait(3, 0); + wait_cycs(3, 0); /* ACK to PIC */ temp = pic_irq_ack(); - wait(4, 1); - wait(1, 0); + wait_cycs(4, 1); + wait_cycs(1, 0); /* ACK to PIC */ temp = pic_irq_ack(); - wait(4, 1); - wait(1, 0); + wait_cycs(4, 1); + wait_cycs(1, 0); in_lock = 0; clear_lock = 0; - wait(1, 0); + wait_cycs(1, 0); /* Here is where temp should be filled, but we cheat. */ - wait(3, 0); + wait_cycs(3, 0); opcode = 0x00; interrupt(temp); } @@ -1287,9 +1288,9 @@ rep_action(int bits) if (in_rep == 0) return 0; - wait(2, 0); + wait_cycs(2, 0); t = CX; - if (irq_pending() && (repeating != 0)) { + if (irq_pending(0) && (repeating != 0)) { access(71, bits); pfq_clear(); if (is_nec && (ovr_seg != NULL)) @@ -1299,16 +1300,16 @@ rep_action(int bits) t = 0; } if (t == 0) { - wait(1, 0); + wait_cycs(1, 0); completed = 1; repeating = 0; return 1; } --CX; completed = 0; - wait(2, 0); + wait_cycs(2, 0); if (!repeating) - wait(2, 0); + wait_cycs(2, 0); return 0; } @@ -1318,7 +1319,7 @@ jump(uint16_t delta) uint16_t old_ip; access(67, 8); pfq_clear(); - wait(5, 0); + wait_cycs(5, 0); old_ip = cpu_state.pc; set_ip((cpu_state.pc + delta) & 0xffff); return old_ip; @@ -1342,9 +1343,9 @@ jcc(uint8_t opcode, int cond) { /* int8_t offset; */ - wait(1, 0); + wait_cycs(1, 0); cpu_data = pfq_fetchb(); - wait(1, 0); + wait_cycs(1, 0); if ((!cond) == !!(opcode & 0x01)) jump_short(); } @@ -1534,32 +1535,32 @@ mul(uint16_t a, uint16_t b) bit_count = 16; high_bit = 0x8000; } else - wait(8, 0); + wait_cycs(8, 0); size_mask = (1 << bit_count) - 1; if ((rmdat & 0x38) == 0x28) { if (!top_bit(a, bit_count)) { if (top_bit(b, bit_count)) { - wait(1, 0); + wait_cycs(1, 0); if ((b & size_mask) != ((opcode & 1) ? 0x8000 : 0x80)) - wait(1, 0); + wait_cycs(1, 0); b = ~b + 1; negate = 1; } } else { - wait(1, 0); + wait_cycs(1, 0); a = ~a + 1; negate = 1; if (top_bit(b, bit_count)) { b = ~b + 1; negate = 0; } else - wait(4, 0); + wait_cycs(4, 0); } - wait(10, 0); + wait_cycs(10, 0); } - wait(3, 0); + wait_cycs(3, 0); } c = 0; @@ -1567,13 +1568,13 @@ mul(uint16_t a, uint16_t b) carry = (a & 1) != 0; a >>= 1; for (i = 0; i < bit_count; ++i) { - wait(7, 0); + wait_cycs(7, 0); if (carry) { cpu_src = c; cpu_dest = b; add(bit_count); c = cpu_data & size_mask; - wait(1, 0); + wait_cycs(1, 0); carry = !!(cpu_state.flags & C_FLAG); } r = (c >> 1) + (carry ? high_bit : 0); @@ -1588,7 +1589,7 @@ mul(uint16_t a, uint16_t b) a = (~a + 1) & size_mask; if (a == 0) ++c; - wait(9, 0); + wait_cycs(9, 0); } cpu_data = a; cpu_dest = c; @@ -1633,7 +1634,7 @@ set_co_mul(UNUSED(int bits), int carry) set_of(carry); set_zf_ex(!carry); if (!carry) - wait(1, 0); + wait_cycs(1, 0); } /* Was div(), renamed to avoid conflicts with stdlib div(). */ @@ -1664,28 +1665,28 @@ x86_div(uint16_t l, uint16_t h) h &= size_mask; negative = 1; dividend_negative = 1; - wait(4, 0); + wait_cycs(4, 0); } if (top_bit(cpu_src, bit_count)) { cpu_src = ~cpu_src + 1; negative = !negative; } else - wait(1, 0); - wait(9, 0); + wait_cycs(1, 0); + wait_cycs(9, 0); } - wait(3, 0); + wait_cycs(3, 0); } - wait(8, 0); + wait_cycs(8, 0); cpu_src &= size_mask; if (h >= cpu_src) { if (opcode != 0xd4) - wait(1, 0); + wait_cycs(1, 0); interrupt(0); return 0; } if (opcode != 0xd4) - wait(1, 0); - wait(2, 0); + wait_cycs(1, 0); + wait_cycs(2, 0); carry = 1; for (b = 0; b < bit_count; ++b) { r = (l << 1) + (carry ? 1 : 0); @@ -1694,32 +1695,32 @@ x86_div(uint16_t l, uint16_t h) r = (h << 1) + (carry ? 1 : 0); carry = top_bit(h, bit_count); h = r; - wait(8, 0); + wait_cycs(8, 0); if (carry) { carry = 0; h -= cpu_src; if (b == bit_count - 1) - wait(2, 0); + wait_cycs(2, 0); } else { carry = cpu_src > h; if (!carry) { h -= cpu_src; - wait(1, 0); + wait_cycs(1, 0); if (b == bit_count - 1) - wait(2, 0); + wait_cycs(2, 0); } } } l = ~((l << 1) + (carry ? 1 : 0)); if (opcode != 0xd4 && (rmdat & 0x38) == 0x38) { - wait(4, 0); + wait_cycs(4, 0); if (top_bit(l, bit_count)) { if (cpu_mod == 3) - wait(1, 0); + wait_cycs(1, 0); interrupt(0); return 0; } - wait(7, 0); + wait_cycs(7, 0); if (negative) l = ~l + 1; if (dividend_negative) @@ -1778,7 +1779,7 @@ aa(void) { set_pzs(8); AL = cpu_data & 0x0f; - wait(6, 0); + wait_cycs(6, 0); } static void @@ -1848,7 +1849,7 @@ cpu_inb(uint16_t port) int old_cycles = cycles; uint8_t ret; - wait(is_mazovia ? 5 : 4, 1); + wait_cycs(is_mazovia ? 5 : 4, 1); old_cycles = cycles; ret = inb(port); @@ -1864,12 +1865,12 @@ cpu_inw(uint16_t port) int old_cycles = cycles; uint16_t ret; - wait(is_mazovia ? 5 : 4, 1); + wait_cycs(is_mazovia ? 5 : 4, 1); if (is8086 && !(port & 1)) { old_cycles = cycles; ret = inw(port); } else { - wait(is_mazovia ? 5 : 4, 1); + wait_cycs(is_mazovia ? 5 : 4, 1); old_cycles = cycles; ret = inb(port++); ret |= (inb(port) << 8); @@ -1885,7 +1886,7 @@ cpu_outb(uint16_t port, uint16_t val) { int old_cycles = cycles; - wait(is_mazovia ? 5 : 4, 1); + wait_cycs(is_mazovia ? 5 : 4, 1); old_cycles = cycles; outb(port, val); @@ -1898,13 +1899,13 @@ cpu_outw(uint16_t port, uint16_t val) { int old_cycles = cycles; - wait(is_mazovia ? 5 : 4, 1); + wait_cycs(is_mazovia ? 5 : 4, 1); if (is8086 && !(port & 1)) { old_cycles = cycles; outw(port, val); } else { - wait(is_mazovia ? 5 : 4, 1); + wait_cycs(is_mazovia ? 5 : 4, 1); old_cycles = cycles; outb(port++, val); outb(port, val >> 8); @@ -1954,7 +1955,7 @@ execx86(int cycs) in_lock = 0; clear_lock = 0; } - wait(1, 0); + wait_cycs(1, 0); } completed = 1; @@ -1963,7 +1964,7 @@ execx86(int cycs) switch (opcode) { case 0x60: /*PUSHA/PUSH R*/ orig_sp = SP; - wait(1, 0); + wait_cycs(1, 0); push(&AX); push(&CX); push(&DX); @@ -1975,7 +1976,7 @@ execx86(int cycs) handled = 1; break; case 0x61: /*POPA/POP R*/ - wait(9, 0); + wait_cycs(9, 0); DI = pop(); SI = pop(); BP = pop(); @@ -2007,7 +2008,7 @@ execx86(int cycs) case 0x65: if (is_nec) { /* REPC/REPNC */ - wait(1, 0); + wait_cycs(1, 0); in_rep = (opcode == 0x64 ? 1 : 2); rep_c_flag = 1; completed = 0; @@ -2017,7 +2018,7 @@ execx86(int cycs) case 0x68: wordtopush = pfq_fetchw(); - wait(1, 0); + wait_cycs(1, 0); push(&wordtopush); handled = 1; break; @@ -2057,12 +2058,12 @@ execx86(int cycs) bits = 8 << (opcode & 1); handled = 1; if (!repeating) - wait(2, 0); + wait_cycs(2, 0); if (rep_action(bits)) break; else if (!repeating) - wait(7, 0); + wait_cycs(7, 0); if (bits == 16) { writememw(es, DI, cpu_inw(DX)); @@ -2085,12 +2086,12 @@ execx86(int cycs) bits = 8 << (opcode & 1); handled = 1; if (!repeating) - wait(2, 0); + wait_cycs(2, 0); if (rep_action(bits)) break; else if (!repeating) - wait(7, 0); + wait_cycs(7, 0); if (bits == 16) { cpu_outw(DX, readmemw(dest_seg, SI)); @@ -2133,12 +2134,12 @@ execx86(int cycs) bits = 8 << (opcode & 1); do_mod_rm(); if (cpu_mod == 3) - wait(1, 0); + wait_cycs(1, 0); access(53, bits); cpu_data = get_ea(); cpu_src = pfq_fetchb(); - wait((cpu_mod != 3) ? 9 : 6, 0); + wait_cycs((cpu_mod != 3) ? 9 : 6, 0); if (!is_nec) cpu_src &= 0x1F; @@ -2210,7 +2211,7 @@ execx86(int cycs) break; } if ((opcode & 2) != 0) - wait(4, 0); + wait_cycs(4, 0); --cpu_src; } access(17, bits); @@ -2244,7 +2245,7 @@ execx86(int cycs) switch (opcode) { case 0x28: /* ROL4 r/m */ do_mod_rm(); - wait(21, 0); + wait_cycs(21, 0); temp_val = geteab(); temp_al = AL; @@ -2262,7 +2263,7 @@ execx86(int cycs) case 0x2a: /* ROR4 r/m */ do_mod_rm(); - wait(21, 0); + wait_cycs(21, 0); temp_val = geteab(); temp_al = AL; @@ -2281,7 +2282,7 @@ execx86(int cycs) case 0x19: /* TEST1 r16/m16, imm4 */ bits = 8 << (opcode & 0x1); do_mod_rm(); - wait(3, 0); + wait_cycs(3, 0); bit = (opcode & 0x8) ? (pfq_fetchb()) : (CL); bit &= ((1 << (3 + (opcode & 0x1))) - 1); @@ -2299,7 +2300,7 @@ execx86(int cycs) case 0x1f: /* NOT1 r16/m16, imm4 */ bits = 8 << (opcode & 0x1); do_mod_rm(); - wait(3, 0); + wait_cycs(3, 0); bit = (opcode & 0x8) ? (pfq_fetchb()) : (CL); bit &= ((1 << (3 + (opcode & 0x1))) - 1); @@ -2319,7 +2320,7 @@ execx86(int cycs) case 0x1d: /* SET1 r16/m16, imm4 */ bits = 8 << (opcode & 0x1); do_mod_rm(); - wait(3, 0); + wait_cycs(3, 0); bit = (opcode & 0x8) ? (pfq_fetchb()) : (CL); bit &= ((1 << (3 + (opcode & 0x1))) - 1); @@ -2339,7 +2340,7 @@ execx86(int cycs) case 0x1b: /* CLR1 r16/m16, imm4 */ bits = 8 << (opcode & 0x1); do_mod_rm(); - wait(3, 0); + wait_cycs(3, 0); bit = (opcode & 0x8) ? (pfq_fetchb()) : (CL); bit &= ((1 << (3 + (opcode & 0x1))) - 1); @@ -2362,9 +2363,9 @@ execx86(int cycs) nibble = 0; srcseg = ovr_seg ? *ovr_seg : ds; - wait(5, 0); + wait_cycs(5, 0); for (i = 0; i < ((nibbles_count / 2) + odd); i++) { - wait(19, 0); + wait_cycs(19, 0); destcmp = read_mem_b((es) + DI + i); for (nibble = 0; nibble < 2; nibble++) { destbyte = destcmp >> (nibble ? 4 : 0); @@ -2397,9 +2398,9 @@ execx86(int cycs) nibble = 0; srcseg = ovr_seg ? *ovr_seg : ds; - wait(5, 0); + wait_cycs(5, 0); for (i = 0; i < ((nibbles_count / 2) + odd); i++) { - wait(19, 0); + wait_cycs(19, 0); destcmp = read_mem_b((es) + DI + i); for (nibble = 0; nibble < 2; nibble++) { destbyte = destcmp >> (nibble ? 4 : 0); @@ -2432,9 +2433,9 @@ execx86(int cycs) nibble = 0; srcseg = ovr_seg ? *ovr_seg : ds; - wait(5, 0); + wait_cycs(5, 0); for (i = 0; i < ((nibbles_count / 2) + odd); i++) { - wait(19, 0); + wait_cycs(19, 0); destcmp = read_mem_b((es) + DI + i); for (nibble = 0; nibble < 2; nibble++) { destbyte = destcmp >> (nibble ? 4 : 0); @@ -2460,7 +2461,7 @@ execx86(int cycs) case 0x31: /* INS reg1, reg2 */ case 0x39: /* INS reg8, imm4 */ do_mod_rm(); - wait(1, 0); + wait_cycs(1, 0); bit_length = ((opcode & 0x8) ? (pfq_fetchb() & 0xF) : (getr8(cpu_reg) & 0xF)) + 1; bit_offset = getr8(cpu_rm) & 0xF; @@ -2489,7 +2490,7 @@ execx86(int cycs) case 0x33: /* EXT reg1, reg2 */ case 0x3b: /* EXT reg8, imm4 */ do_mod_rm(); - wait(1, 0); + wait_cycs(1, 0); bit_length = ((opcode & 0x8) ? (pfq_fetchb() & 0xF) : (getr8(cpu_reg) & 0xF)) + 1; bit_offset = getr8(cpu_rm) & 0xF; @@ -2537,7 +2538,7 @@ execx86(int cycs) pfq_pos = 0; } else load_seg(pop(), _opseg[(opcode >> 3) & 0x03]); - wait(1, 0); + wait_cycs(1, 0); /* All POP segment instructions suppress interrupts for one instruction. */ noint = 1; break; @@ -2546,7 +2547,7 @@ execx86(int cycs) case 0x2E: /*CS:*/ case 0x36: /*SS:*/ case 0x3E: /*DS:*/ - wait(1, 0); + wait_cycs(1, 0); ovr_seg = opseg[(opcode >> 3) & 0x03]; completed = 0; break; @@ -2597,21 +2598,21 @@ execx86(int cycs) cpu_src = tempw; } if (cpu_mod != 3) - wait(2, 0); - wait(1, 0); + wait_cycs(2, 0); + wait_cycs(1, 0); alu_op(bits); if (cpu_alu_op != 7) { if ((opcode & 2) == 0) { access(10, bits); set_ea(cpu_data); if (cpu_mod == 3) - wait(1, 0); + wait_cycs(1, 0); } else { set_reg(cpu_reg, cpu_data); - wait(1, 0); + wait_cycs(1, 0); } } else - wait(1, 0); + wait_cycs(1, 0); break; case 0x04: @@ -2632,7 +2633,7 @@ execx86(int cycs) case 0x3d: /* alu A, imm */ bits = 8 << (opcode & 1); - wait(1, 0); + wait_cycs(1, 0); cpu_data = pfq_fetch(); cpu_dest = get_accum(bits); /* AX/AL */ cpu_src = cpu_data; @@ -2640,7 +2641,7 @@ execx86(int cycs) alu_op(bits); if (cpu_alu_op != 7) set_accum(bits, cpu_data); - wait(1, 0); + wait_cycs(1, 0); break; case 0x27: /*DAA*/ @@ -2663,7 +2664,7 @@ execx86(int cycs) } AL = cpu_dest; set_pzs(8); - wait(3, 0); + wait_cycs(3, 0); break; case 0x2F: /*DAS*/ cpu_dest = AL; @@ -2685,10 +2686,10 @@ execx86(int cycs) } AL = cpu_dest; set_pzs(8); - wait(3, 0); + wait_cycs(3, 0); break; case 0x37: /*AAA*/ - wait(1, 0); + wait_cycs(1, 0); if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { cpu_src = 6; ++AH; @@ -2696,7 +2697,7 @@ execx86(int cycs) } else { cpu_src = 0; clear_ca(); - wait(1, 0); + wait_cycs(1, 0); } cpu_dest = AL; cpu_data = cpu_dest + cpu_src; @@ -2704,7 +2705,7 @@ execx86(int cycs) aa(); break; case 0x3F: /*AAS*/ - wait(1, 0); + wait_cycs(1, 0); if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { cpu_src = 6; --AH; @@ -2712,7 +2713,7 @@ execx86(int cycs) } else { cpu_src = 0; clear_ca(); - wait(1, 0); + wait_cycs(1, 0); } cpu_dest = AL; cpu_data = cpu_dest - cpu_src; @@ -2737,7 +2738,7 @@ execx86(int cycs) case 0x4E: case 0x4F: /* INCDEC rw */ - wait(1, 0); + wait_cycs(1, 0); cpu_dest = cpu_state.regs[opcode & 7].w; cpu_src = 1; bits = 16; @@ -2774,7 +2775,7 @@ execx86(int cycs) case 0x5F: access(23, 16); cpu_state.regs[opcode & 0x07].w = pop(); - wait(1, 0); + wait_cycs(1, 0); break; case 0x60: /*JO alias*/ @@ -2841,20 +2842,20 @@ execx86(int cycs) cpu_data = get_ea(); cpu_dest = cpu_data; if (cpu_mod != 3) - wait(3, 0); + wait_cycs(3, 0); if (opcode == 0x81) { if (cpu_mod == 3) - wait(1, 0); + wait_cycs(1, 0); cpu_src = pfq_fetchw(); } else { if (cpu_mod == 3) - wait(1, 0); + wait_cycs(1, 0); if (opcode == 0x83) cpu_src = sign_extend(pfq_fetchb()); else cpu_src = pfq_fetchb() | 0xff00; } - wait(1, 0); + wait_cycs(1, 0); cpu_alu_op = (rmdat & 0x38) >> 3; alu_op(bits); if (cpu_alu_op != 7) { @@ -2862,7 +2863,7 @@ execx86(int cycs) set_ea(cpu_data); } else { if (cpu_mod != 3) - wait(1, 0); + wait_cycs(1, 0); } break; @@ -2875,8 +2876,8 @@ execx86(int cycs) cpu_data = get_ea(); test(bits, cpu_data, get_reg(cpu_reg)); if (cpu_mod == 3) - wait(2, 0); - wait(2, 0); + wait_cycs(2, 0); + wait_cycs(2, 0); break; case 0x86: case 0x87: @@ -2887,7 +2888,7 @@ execx86(int cycs) cpu_data = get_ea(); cpu_src = get_reg(cpu_reg); set_reg(cpu_reg, cpu_data); - wait(3, 0); + wait_cycs(3, 0); access(12, bits); set_ea(cpu_src); break; @@ -2897,7 +2898,7 @@ execx86(int cycs) /* MOV rm, reg */ bits = 8 << (opcode & 1); do_mod_rm(); - wait(1, 0); + wait_cycs(1, 0); access(13, bits); set_ea(get_reg(cpu_reg)); break; @@ -2908,15 +2909,15 @@ execx86(int cycs) do_mod_rm(); access(50, bits); set_reg(cpu_reg, get_ea()); - wait(1, 0); + wait_cycs(1, 0); if (cpu_mod != 3) - wait(2, 0); + wait_cycs(2, 0); break; case 0x8C: /*MOV w,sreg*/ do_mod_rm(); if (cpu_mod == 3) - wait(1, 0); + wait_cycs(1, 0); access(14, 16); seteaw(_opseg[(rmdat & 0x18) >> 3]->seg); break; @@ -2924,9 +2925,9 @@ execx86(int cycs) case 0x8D: /*LEA*/ do_mod_rm(); cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; - wait(1, 0); + wait_cycs(1, 0); if (cpu_mod != 3) - wait(2, 0); + wait_cycs(2, 0); break; case 0x8E: /*MOV sreg,w*/ @@ -2938,23 +2939,23 @@ execx86(int cycs) pfq_pos = 0; } else load_seg(tempw, _opseg[(rmdat & 0x18) >> 3]); - wait(1, 0); + wait_cycs(1, 0); if (cpu_mod != 3) - wait(2, 0); + wait_cycs(2, 0); if (((rmdat & 0x18) >> 3) == 2) noint = 1; break; case 0x8F: /*POPW*/ do_mod_rm(); - wait(1, 0); + wait_cycs(1, 0); cpu_src = cpu_state.eaaddr; access(24, 16); if (cpu_mod != 3) - wait(2, 0); + wait_cycs(2, 0); cpu_data = pop(); cpu_state.eaaddr = cpu_src; - wait(2, 0); + wait_cycs(2, 0); access(15, 16); seteaw(cpu_data); break; @@ -2968,30 +2969,30 @@ execx86(int cycs) case 0x96: case 0x97: /* XCHG AX, rw */ - wait(1, 0); + wait_cycs(1, 0); cpu_data = cpu_state.regs[opcode & 7].w; cpu_state.regs[opcode & 7].w = AX; AX = cpu_data; - wait(1, 0); + wait_cycs(1, 0); break; case 0x98: /*CBW*/ - wait(1, 0); + wait_cycs(1, 0); AX = sign_extend(AL); break; case 0x99: /*CWD*/ - wait(4, 0); + wait_cycs(4, 0); if (!top_bit(AX, 16)) DX = 0; else { - wait(1, 0); + wait_cycs(1, 0); DX = 0xffff; } break; case 0x9A: /*CALL FAR*/ - wait(1, 0); + wait_cycs(1, 0); new_ip = pfq_fetchw(); - wait(1, 0); + wait_cycs(1, 0); new_cs = pfq_fetchw(); pfq_clear(); access(31, 16); @@ -3005,20 +3006,20 @@ execx86(int cycs) break; case 0x9B: /*WAIT*/ if (!repeating) - wait(2, 0); - wait(5, 0); + wait_cycs(2, 0); + wait_cycs(5, 0); #ifdef NO_HACK - if (irq_pending()) { - wait(7, 0); - check_interrupts(); + if (irq_pending(0)) { + wait_cycs(7, 0); + check_interrupts(0); } else { repeating = 1; completed = 0; clock_end(); } #else - wait(7, 0); - check_interrupts(); + wait_cycs(7, 0); + check_interrupts(0); #endif break; case 0x9C: /*PUSHF*/ @@ -3029,22 +3030,25 @@ execx86(int cycs) tempw = (cpu_state.flags & 0x0fd7) | 0xf000; push(&tempw); break; - case 0x9D: /*POPF*/ + case 0x9D: { /*POPF*/ + uint16_t old_flags = cpu_state.flags; access(25, 16); if (is_nec && cpu_md_write_disable) cpu_state.flags = pop() | 0x8002; else cpu_state.flags = pop() | 0x0002; - wait(1, 0); + wait_cycs(1, 0); + if ((old_flags ^ cpu_state.flags) & T_FLAG) + noint = 1; sync_to_i8080(); break; - case 0x9E: /*SAHF*/ - wait(1, 0); + } case 0x9E: /*SAHF*/ + wait_cycs(1, 0); cpu_state.flags = (cpu_state.flags & 0xff02) | AH; - wait(2, 0); + wait_cycs(2, 0); break; case 0x9F: /*LAHF*/ - wait(1, 0); + wait_cycs(1, 0); AH = cpu_state.flags & 0xd7; break; @@ -3052,17 +3056,17 @@ execx86(int cycs) case 0xA1: /* MOV A, [iw] */ bits = 8 << (opcode & 1); - wait(1, 0); + wait_cycs(1, 0); cpu_state.eaaddr = pfq_fetchw(); access(1, bits); set_accum(bits, readmem((ovr_seg ? *ovr_seg : ds))); - wait(1, 0); + wait_cycs(1, 0); break; case 0xA2: case 0xA3: /* MOV [iw], A */ bits = 8 << (opcode & 1); - wait(1, 0); + wait_cycs(1, 0); cpu_state.eaaddr = pfq_fetchw(); access(7, bits); writemem((ovr_seg ? *ovr_seg : ds), get_accum(bits)); @@ -3074,18 +3078,18 @@ execx86(int cycs) case 0xAD: /* LODS */ bits = 8 << (opcode & 1); if (!repeating) { - wait(1, 0); + wait_cycs(1, 0); if ((opcode & 8) == 0 && in_rep != 0) - wait(1, 0); + wait_cycs(1, 0); } if (rep_action(bits)) { - wait(1, 0); + wait_cycs(1, 0); if ((opcode & 8) != 0) - wait(1, 0); + wait_cycs(1, 0); break; } if (in_rep != 0 && (opcode & 8) != 0) - wait(1, 0); + wait_cycs(1, 0); access(20, bits); lods(bits); if ((opcode & 8) == 0) { @@ -3094,12 +3098,12 @@ execx86(int cycs) } else { set_accum(bits, cpu_data); if (in_rep != 0) - wait(2, 0); + wait_cycs(2, 0); } if (in_rep == 0) { - wait(3, 0); + wait_cycs(3, 0); if ((opcode & 8) != 0) - wait(1, 0); + wait_cycs(1, 0); break; } repeating = 1; @@ -3112,19 +3116,19 @@ execx86(int cycs) case 0xAF: /* SCAS */ bits = 8 << (opcode & 1); if (!repeating) - wait(1, 0); + wait_cycs(1, 0); if (rep_action(bits)) { - wait(2, 0); + wait_cycs(2, 0); break; } if (in_rep != 0) - wait(1, 0); - wait(1, 0); + wait_cycs(1, 0); + wait_cycs(1, 0); cpu_dest = get_accum(bits); if ((opcode & 8) == 0) { access(21, bits); lods(bits); - wait(1, 0); + wait_cycs(1, 0); cpu_dest = cpu_data; } access(2, bits); @@ -3133,14 +3137,14 @@ execx86(int cycs) DI = string_increment(bits); cpu_src = cpu_data; sub(bits); - wait(2, 0); + wait_cycs(2, 0); if (in_rep == 0) { - wait(3, 0); + wait_cycs(3, 0); break; } if ((!!(cpu_state.flags & (rep_c_flag ? C_FLAG : Z_FLAG))) == (in_rep == 1)) { completed = 1; - wait(4, 0); + wait_cycs(4, 0); break; } repeating = 1; @@ -3151,29 +3155,29 @@ execx86(int cycs) case 0xA9: /* TEST A, imm */ bits = 8 << (opcode & 1); - wait(1, 0); + wait_cycs(1, 0); cpu_data = pfq_fetch(); test(bits, get_accum(bits), cpu_data); - wait(1, 0); + wait_cycs(1, 0); break; case 0xAA: case 0xAB: /* STOS */ bits = 8 << (opcode & 1); if (!repeating) { - wait(1, 0); + wait_cycs(1, 0); if (in_rep != 0) - wait(1, 0); + wait_cycs(1, 0); } if (rep_action(bits)) { - wait(1, 0); + wait_cycs(1, 0); break; } cpu_data = AX; access(28, bits); stos(bits); if (in_rep == 0) { - wait(3, 0); + wait_cycs(3, 0); break; } repeating = 1; @@ -3188,12 +3192,12 @@ execx86(int cycs) case 0xB5: case 0xB6: case 0xB7: - wait(1, 0); + wait_cycs(1, 0); if (opcode & 0x04) cpu_state.regs[opcode & 0x03].b.h = pfq_fetchb(); else cpu_state.regs[opcode & 0x03].b.l = pfq_fetchb(); - wait(1, 0); + wait_cycs(1, 0); break; case 0xB8: @@ -3204,9 +3208,9 @@ execx86(int cycs) case 0xBD: case 0xBE: case 0xBF: - wait(1, 0); + wait_cycs(1, 0); cpu_state.regs[opcode & 0x07].w = pfq_fetchw(); - wait(1, 0); + wait_cycs(1, 0); break; case 0xC0: @@ -3220,28 +3224,28 @@ execx86(int cycs) /* RET */ bits = 8 + (opcode & 0x08); if ((opcode & 9) != 1) - wait(1, 0); + wait_cycs(1, 0); if (!(opcode & 1)) { cpu_src = pfq_fetchw(); - wait(1, 0); + wait_cycs(1, 0); } if ((opcode & 9) == 9) - wait(1, 0); + wait_cycs(1, 0); pfq_clear(); access(26, bits); new_ip = pop(); - wait(2, 0); + wait_cycs(2, 0); if ((opcode & 8) == 0) new_cs = CS; else { access(42, bits); new_cs = pop(); if (opcode & 1) - wait(1, 0); + wait_cycs(1, 0); } if (!(opcode & 1)) { SP += cpu_src; - wait(1, 0); + wait_cycs(1, 0); } load_cs(new_cs); access(72, bits); @@ -3259,7 +3263,7 @@ execx86(int cycs) access(57, bits); read_ea2(bits); load_seg(cpu_data, (opcode & 0x01) ? &cpu_state.seg_ds : &cpu_state.seg_es); - wait(1, 0); + wait_cycs(1, 0); break; case 0xC6: @@ -3267,12 +3271,12 @@ execx86(int cycs) /* MOV rm, imm */ bits = 8 << (opcode & 1); do_mod_rm(); - wait(1, 0); + wait_cycs(1, 0); if (cpu_mod != 3) - wait(2, 0); + wait_cycs(2, 0); cpu_data = pfq_fetch(); if (cpu_mod == 3) - wait(1, 0); + wait_cycs(1, 0); access(16, bits); set_ea(cpu_data); break; @@ -3281,13 +3285,13 @@ execx86(int cycs) interrupt(3); break; case 0xCD: /*INT*/ - wait(1, 0); + wait_cycs(1, 0); interrupt(pfq_fetchb()); break; case 0xCE: /*INTO*/ - wait(3, 0); + wait_cycs(3, 0); if (cpu_state.flags & V_FLAG) { - wait(2, 0); + wait_cycs(2, 0); interrupt(4); } break; @@ -3295,7 +3299,7 @@ execx86(int cycs) case 0xCF: /*IRET*/ access(43, 8); new_ip = pop(); - wait(3, 0); + wait_cycs(3, 0); access(44, 8); new_cs = pop(); load_cs(new_cs); @@ -3306,8 +3310,8 @@ execx86(int cycs) cpu_state.flags = pop() | 0x8002; else cpu_state.flags = pop() | 0x0002; - wait(5, 0); - noint = 1; + wait_cycs(5, 0); + noint = 2; nmi_enable = 1; if (is_nec && !(cpu_state.flags & MD_FLAG)) sync_to_i8080(); @@ -3321,15 +3325,15 @@ execx86(int cycs) bits = 8 << (opcode & 1); do_mod_rm(); if (cpu_mod == 3) - wait(1, 0); + wait_cycs(1, 0); access(53, bits); cpu_data = get_ea(); if ((opcode & 2) == 0) { cpu_src = 1; - wait((cpu_mod != 3) ? 4 : 0, 0); + wait_cycs((cpu_mod != 3) ? 4 : 0, 0); } else { cpu_src = CL; - wait((cpu_mod != 3) ? 9 : 6, 0); + wait_cycs((cpu_mod != 3) ? 9 : 6, 0); } if (is186 && !is_nec) cpu_src &= 0x1F; @@ -3401,7 +3405,7 @@ execx86(int cycs) break; } if ((opcode & 2) != 0) - wait(4, 0); + wait_cycs(4, 0); --cpu_src; } access(17, bits); @@ -3409,7 +3413,7 @@ execx86(int cycs) break; case 0xD4: /*AAM*/ - wait(1, 0); + wait_cycs(1, 0); #ifdef NO_VARIANT_ON_NEC if (is_nec) { (void) pfq_fetchb(); @@ -3425,7 +3429,7 @@ execx86(int cycs) } break; case 0xD5: /*AAD*/ - wait(1, 0); + wait_cycs(1, 0); if (is_nec) { (void) pfq_fetchb(); mul(10, AH); @@ -3440,9 +3444,9 @@ execx86(int cycs) break; case 0xD6: /*SALC*/ if (!is_nec) { - wait(1, 0); + wait_cycs(1, 0); AL = (cpu_state.flags & C_FLAG) ? 0xff : 0x00; - wait(1, 0); + wait_cycs(1, 0); break; } fallthrough; @@ -3450,7 +3454,7 @@ execx86(int cycs) cpu_state.eaaddr = (BX + AL) & 0xffff; access(4, 8); AL = readmemb((ovr_seg ? *ovr_seg : ds) + cpu_state.eaaddr); - wait(1, 0); + wait_cycs(1, 0); break; case 0xD8: @@ -3531,9 +3535,9 @@ execx86(int cycs) } 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); + wait_cycs(1, 0); if (cpu_mod != 3) - wait(2, 0); + wait_cycs(2, 0); break; case 0xE0: @@ -3541,10 +3545,10 @@ execx86(int cycs) case 0xE2: case 0xE3: /* LOOP */ - wait(3, 0); + wait_cycs(3, 0); cpu_data = pfq_fetchb(); if (opcode != 0xe2) - wait(1, 0); + wait_cycs(1, 0); if (opcode != 0xe3) { --CX; oldc = (CX != 0); @@ -3574,7 +3578,7 @@ execx86(int cycs) case 0xEF: bits = 8 << (opcode & 1); if ((opcode & 0x0e) != 0x0c) - wait(1, 0); + wait_cycs(1, 0); if ((opcode & 8) == 0) cpu_data = pfq_fetchb(); else @@ -3586,7 +3590,7 @@ execx86(int cycs) cpu_io(16, 0, cpu_data); else cpu_io(8, 0, cpu_data); - wait(1, 0); + wait_cycs(1, 0); } else { if ((opcode & 8) == 0) access(8, bits); @@ -3600,19 +3604,19 @@ execx86(int cycs) break; case 0xE8: /*CALL rel 16*/ - wait(1, 0); + wait_cycs(1, 0); cpu_state.oldpc = jump_near(); access(34, 8); push((uint16_t *) &(cpu_state.oldpc)); break; case 0xE9: /*JMP rel 16*/ - wait(1, 0); + wait_cycs(1, 0); jump_near(); break; case 0xEA: /*JMP far*/ - wait(1, 0); + wait_cycs(1, 0); addr = pfq_fetchw(); - wait(1, 0); + wait_cycs(1, 0); tempw = pfq_fetchw(); load_cs(tempw); access(70, 8); @@ -3620,22 +3624,22 @@ execx86(int cycs) set_ip(addr); break; case 0xEB: /*JMP rel*/ - wait(1, 0); + wait_cycs(1, 0); cpu_data = (int8_t) pfq_fetchb(); jump_short(); - wait(1, 0); + wait_cycs(1, 0); break; case 0xF0: case 0xF1: /*LOCK - F1 is alias*/ in_lock = 1; - wait(1, 0); + wait_cycs(1, 0); completed = 0; break; case 0xF2: /*REPNE*/ case 0xF3: /*REPE*/ - wait(1, 0); + wait_cycs(1, 0); in_rep = (opcode == 0xf2 ? 1 : 2); completed = 0; rep_c_flag = 0; @@ -3643,13 +3647,13 @@ execx86(int cycs) case 0xF4: /*HLT*/ if (!repeating) { - wait(1, 0); + wait_cycs(1, 0); pfq_clear(); } - wait(1, 0); - if (irq_pending()) { - wait(cycles & 1, 0); - check_interrupts(); + wait_cycs(1, 0); + if (irq_pending(is_nec)) { + wait_cycs(cycles & 1, 0); + check_interrupts(is_nec); } else { repeating = 1; completed = 0; @@ -3657,7 +3661,7 @@ execx86(int cycs) } break; case 0xF5: /*CMC*/ - wait(1, 0); + wait_cycs(1, 0); cpu_state.flags ^= C_FLAG; break; @@ -3671,18 +3675,18 @@ execx86(int cycs) case 0x00: case 0x08: /* TEST */ - wait(2, 0); + wait_cycs(2, 0); if (cpu_mod != 3) - wait(1, 0); + wait_cycs(1, 0); cpu_src = pfq_fetch(); - wait(1, 0); + wait_cycs(1, 0); test(bits, cpu_data, cpu_src); if (cpu_mod != 3) - wait(1, 0); + wait_cycs(1, 0); break; case 0x10: /* NOT */ case 0x18: /* NEG */ - wait(2, 0); + wait_cycs(2, 0); if ((rmdat & 0x38) == 0x10) cpu_data = ~cpu_data; else { @@ -3696,7 +3700,7 @@ execx86(int cycs) case 0x20: /* MUL */ case 0x28: /* IMUL */ old_flags = cpu_state.flags; - wait(1, 0); + wait_cycs(1, 0); mul(get_accum(bits), cpu_data); if (opcode & 1) { AX = cpu_data; @@ -3713,7 +3717,7 @@ execx86(int cycs) set_sf(bits); set_pf(); if (cpu_mod != 3) - wait(1, 0); + wait_cycs(1, 0); /* NOTE: When implementing the V20, care should be taken to not change the zero flag. */ if (is_nec) @@ -3722,10 +3726,10 @@ execx86(int cycs) case 0x30: /* DIV */ case 0x38: /* IDIV */ if (cpu_mod != 3) - wait(1, 0); + wait_cycs(1, 0); cpu_src = cpu_data; if (x86_div(AL, AH)) - wait(1, 0); + wait_cycs(1, 0); break; } break; @@ -3733,19 +3737,19 @@ execx86(int cycs) case 0xF8: case 0xF9: /* CLCSTC */ - wait(1, 0); + wait_cycs(1, 0); set_cf(opcode & 1); break; case 0xFA: case 0xFB: /* CLISTI */ - wait(1, 0); + wait_cycs(1, 0); set_if(opcode & 1); break; case 0xFC: case 0xFD: /* CLDSTD */ - wait(1, 0); + wait_cycs(1, 0); set_df(opcode & 1); break; @@ -3770,22 +3774,22 @@ execx86(int cycs) } do_af(); set_pzs(bits); - wait(2, 0); + wait_cycs(2, 0); access(19, bits); set_ea(cpu_data); break; case 0x10: /* CALL rm */ cpu_data_opff_rm(); access(63, bits); - wait(1, 0); + wait_cycs(1, 0); pfq_clear(); - wait(4, 0); + wait_cycs(4, 0); if (cpu_mod != 3) - wait(1, 0); - wait(1, 0); /* Wait. */ + wait_cycs(1, 0); + wait_cycs(1, 0); /* Wait. */ cpu_state.oldpc = cpu_state.pc; set_ip(cpu_data); - wait(2, 0); + wait_cycs(2, 0); access(35, bits); push((uint16_t *) &(cpu_state.oldpc)); break; @@ -3799,7 +3803,7 @@ execx86(int cycs) access(36, bits); push(&(CS)); access(64, bits); - wait(4, 0); + wait_cycs(4, 0); cpu_state.oldpc = cpu_state.pc; load_cs(new_cs); set_ip(new_ip); @@ -3825,7 +3829,7 @@ execx86(int cycs) case 0x30: /* PUSH rm */ case 0x38: if (cpu_mod != 3) - wait(1, 0); + wait_cycs(1, 0); access(38, bits); push((uint16_t *) &(cpu_data)); break; @@ -3835,7 +3839,7 @@ execx86(int cycs) default: x808x_log("Illegal opcode: %02X\n", opcode); pfq_fetchb(); - wait(8, 0); + wait_cycs(8, 0); break; } } @@ -3848,7 +3852,7 @@ exec_completed: if (in_lock) clear_lock = 1; clock_end(); - check_interrupts(); + check_interrupts(0); if (noint) noint = 0; diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index d13dfe041..ec026d95e 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -4264,7 +4264,7 @@ cpu_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) cyrix_addr = val; else if (addr < 0xf1) switch (cyrix_addr) { default: - if (cyrix_addr >= 0xc0) + if ((cyrix_addr >= 0xc0) && (cyrix_addr != 0xff)) fatal("Writing unimplemented Cyrix register %02X\n", cyrix_addr); break; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index b6f5f593c..47f3e7f5c 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -381,7 +381,7 @@ typedef struct { MMX_REG MM[8]; #ifdef USE_NEW_DYNAREC -# if defined(__APPLE__) && defined(__aarch64__) +# if (defined(__APPLE__) && defined(__aarch64__)) || defined(__aarch64__) uint64_t old_fp_control; uint64_t new_fp_control; # else diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 8524306dc..db8c89ebb 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -688,6 +688,23 @@ const cpu_family_t cpu_families[] = { .cache_write_cycles = 0, .atclk_div = 1 }, + { + .name = "8", + .cpu_type = CPU_V20, + .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 = "10", .cpu_type = CPU_V20, @@ -911,10 +928,10 @@ const cpu_family_t cpu_families[] = { .internal_name = "necv30", .cpus = (const CPU[]) { { - .name = "5", + .name = "7.16", .cpu_type = CPU_V30, .fpus = fpus_80186, - .rspeed = 5000000, + .rspeed = 7159092, .multi = 1, .voltage = 5000, .edx_reset = 0, @@ -944,6 +961,23 @@ const cpu_family_t cpu_families[] = { .cache_write_cycles = 0, .atclk_div = 1 }, + { + .name = "9.54", + .cpu_type = CPU_V30, + .fpus = fpus_80186, + .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 = "10", .cpu_type = CPU_V30, diff --git a/src/cpu/softfloat3e/s_shiftRightJam256M.c b/src/cpu/softfloat3e/s_shiftRightJam256M.c index 654e01234..c92204c4d 100644 --- a/src/cpu/softfloat3e/s_shiftRightJam256M.c +++ b/src/cpu/softfloat3e/s_shiftRightJam256M.c @@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================*/ +#include #include #include "primitiveTypes.h" @@ -64,7 +65,7 @@ void softfloat_shiftRightJam256M(const uint64_t *aPtr, uint32_t dist, uint64_t * { uint64_t wordJam; uint32_t wordDist; - uint64_t *ptr; + uint64_t *ptr = NULL; uint8_t i, innerDist; wordJam = 0; @@ -89,7 +90,7 @@ void softfloat_shiftRightJam256M(const uint64_t *aPtr, uint32_t dist, uint64_t * aPtr, innerDist, zPtr + indexMultiwordLoBut(4, wordDist) - ); + ); if (! wordDist) goto wordJam; } else { aPtr += indexWordLo(4 - wordDist); diff --git a/src/cpu/x86.c b/src/cpu/x86.c index a8ab9d866..1b0de661b 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -326,7 +326,6 @@ reset_common(int hard) resetreadlookup(); makemod1table(); cpu_set_edx(); - mmu_perm = 4; } x86seg_reset(); #ifdef USE_DYNAREC diff --git a/src/cpu/x86_ops_flag.h b/src/cpu/x86_ops_flag.h index a0fa612a8..7e7324341 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu/x86_ops_flag.h @@ -121,6 +121,7 @@ opPUSHF(UNUSED(uint32_t fetchdat)) temp = (cpu_state.flags & ~I_FLAG) | 0x3000; if (cpu_state.eflags & VIF_FLAG) temp |= I_FLAG; + temp = (temp & 0x7fd5) | 2; PUSH_W(temp); } else { x86gpf(NULL, 0); @@ -128,6 +129,7 @@ opPUSHF(UNUSED(uint32_t fetchdat)) } } else { flags_rebuild(); + cpu_state.flags = (cpu_state.flags & 0x7fd5) | 2; PUSH_W(cpu_state.flags); } CLOCK_CYCLES(4); @@ -149,6 +151,7 @@ opPUSHFD(UNUSED(uint32_t fetchdat)) else tempw = cpu_state.eflags & 4; flags_rebuild(); + cpu_state.flags = (cpu_state.flags & 0x7fd5) | 2; PUSH_L(cpu_state.flags | (tempw << 16)); CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); @@ -160,23 +163,11 @@ opPOPF_186(UNUSED(uint32_t fetchdat)) { uint16_t tempw; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { - x86gpf(NULL, 0); - return 1; - } - tempw = POP_W(); if (cpu_state.abrt) return 1; - if (!(msw & 1)) - cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; - else if (!(CPL)) - cpu_state.flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) - cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; - else - cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; flags_extract(); #ifdef USE_DEBUG_REGS_486 rf_flag_no_clear = 1; diff --git a/src/cpu/x86_ops_flag_2386.h b/src/cpu/x86_ops_flag_2386.h index c9a2d5ab2..787b268dc 100644 --- a/src/cpu/x86_ops_flag_2386.h +++ b/src/cpu/x86_ops_flag_2386.h @@ -121,6 +121,7 @@ opPUSHF(UNUSED(uint32_t fetchdat)) temp = (cpu_state.flags & ~I_FLAG) | 0x3000; if (cpu_state.eflags & VIF_FLAG) temp |= I_FLAG; + temp = (temp & 0x7fd5) | 2; PUSH_W(temp); } else { x86gpf(NULL, 0); @@ -128,6 +129,7 @@ opPUSHF(UNUSED(uint32_t fetchdat)) } } else { flags_rebuild(); + cpu_state.flags = (cpu_state.flags & 0x7fd5) | 2; PUSH_W(cpu_state.flags); } CLOCK_CYCLES(4); @@ -149,6 +151,7 @@ opPUSHFD(UNUSED(uint32_t fetchdat)) else tempw = cpu_state.eflags & 4; flags_rebuild(); + cpu_state.flags = (cpu_state.flags & 0x7fd5) | 2; PUSH_L(cpu_state.flags | (tempw << 16)); CLOCK_CYCLES(4); PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); @@ -160,23 +163,11 @@ opPOPF_186(UNUSED(uint32_t fetchdat)) { uint16_t tempw; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { - x86gpf(NULL, 0); - return 1; - } - tempw = POP_W(); if (cpu_state.abrt) return 1; - if (!(msw & 1)) - cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; - else if (!(CPL)) - cpu_state.flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) - cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; - else - cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; flags_extract(); rf_flag_no_clear = 1; diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index ffc79f0e8..5ae28abc4 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -753,7 +753,7 @@ opLOCK(uint32_t fetchdat) return 0; cpu_state.pc++; - ILLEGAL_ON((fetchdat & 0xff) == 0x90); + ILLEGAL_ON(((fetchdat & 0xff) == 0x90) || ((fetchdat & 0xff) == 0xec)); CLOCK_CYCLES(4); PREFETCH_PREFIX(); diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu/x86_ops_mmx.h index 338948af5..9a2d797a8 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu/x86_ops_mmx.h @@ -22,12 +22,12 @@ } #define MMX_ENTER() \ - if (!cpu_has_feature(CPU_FEATURE_MMX)) { \ + if (!cpu_has_feature(CPU_FEATURE_MMX) || (cr0 & 0x4)) { \ cpu_state.pc = cpu_state.oldpc; \ x86illegal(); \ return 1; \ } \ - if (cr0 & 0xc) { \ + if (cr0 & 0x8) { \ x86_int(7); \ return 1; \ } \ diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index 253dc059e..3f5d6a4d7 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -201,8 +201,6 @@ opMOV_CRx_r_a16(uint32_t fetchdat) cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm = 4; if (hascache && !(cr0 & (1 << 30))) cpu_cache_int_enabled = 1; else @@ -267,8 +265,6 @@ opMOV_CRx_r_a32(uint32_t fetchdat) cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm = 4; if (hascache && !(cr0 & (1 << 30))) cpu_cache_int_enabled = 1; else diff --git a/src/cpu/x86_ops_mov_ctrl_2386.h b/src/cpu/x86_ops_mov_ctrl_2386.h index 8827d29b2..0d13cc833 100644 --- a/src/cpu/x86_ops_mov_ctrl_2386.h +++ b/src/cpu/x86_ops_mov_ctrl_2386.h @@ -193,8 +193,6 @@ opMOV_CRx_r_a16(uint32_t fetchdat) cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm = 4; if (hascache && !(cr0 & (1 << 30))) cpu_cache_int_enabled = 1; else @@ -255,8 +253,6 @@ opMOV_CRx_r_a32(uint32_t fetchdat) cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm = 4; if (hascache && !(cr0 & (1 << 30))) cpu_cache_int_enabled = 1; else diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index 0bd8209e1..1e4504949 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -22,6 +22,20 @@ */ #include #include +#if defined(_MSC_VER) && !defined(__clang__) +# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 +# define X87_INLINE_ASM +# endif +#else +# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__ +# define X87_INLINE_ASM +# endif +#endif + +#ifdef X87_INLINE_ASM +#include +#endif + #include "x87_timings.h" #ifdef _MSC_VER # include @@ -38,7 +52,9 @@ extern void fpu_log(const char *fmt, ...); extern double exp_pow_table[0x800]; +#ifndef X87_INLINE_ASM static int rounding_modes[4] = { FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO }; +#endif #define ST(x) cpu_state.ST[((cpu_state.TOP + (x)) & 7)] @@ -64,16 +80,6 @@ typedef union { }; } double_decompose_t; -#if defined(_MSC_VER) && !defined(__clang__) -# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -# define X87_INLINE_ASM -# endif -#else -# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__ -# define X87_INLINE_ASM -# endif -#endif - #ifdef FPU_8087 # define x87_div(dst, src1, src2) \ do { \ @@ -575,7 +581,7 @@ static int FPU_ILLEGAL_a16(UNUSED(uint32_t fetchdat)) { geteaw(); - wait(timing_rr, 0); + wait_cycs(timing_rr, 0); return 0; } #else diff --git a/src/cpu/x87_ops_arith.h b/src/cpu/x87_ops_arith.h index 8d0c02167..bf3fbf253 100644 --- a/src/cpu/x87_ops_arith.h +++ b/src/cpu/x87_ops_arith.h @@ -1,3 +1,46 @@ + +#ifdef X87_INLINE_ASM +static inline double float_add(double src, double val, int round) +{ + int rounding_mode_orig; + + __m128d xmm_src = _mm_load_sd(&src); + __m128d xmm_dst = _mm_load_sd(&val); + __m128d xmm_res; + + rounding_mode_orig = _MM_GET_ROUNDING_MODE(); + if (round == 0) _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST); + if (round == 1) _MM_SET_ROUNDING_MODE(_MM_ROUND_DOWN); + if (round == 2) _MM_SET_ROUNDING_MODE(_MM_ROUND_UP); + if (round == 3) _MM_SET_ROUNDING_MODE(_MM_ROUND_TOWARD_ZERO); + + xmm_res = _mm_add_sd(xmm_src, xmm_dst); + + _MM_SET_ROUNDING_MODE(rounding_mode_orig); + + return _mm_cvtsd_f64(xmm_res); +} + +#define DO_FADD(use_var) \ + do \ + { \ + ST(0) = float_add(ST(0), use_var, (cpu_state.npxc >> 10) & 3); \ + } \ + while (0) + +#else +#define DO_FADD(use_var) \ + do \ + { \ + if ((cpu_state.npxc >> 10) & 3) \ + fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \ + ST(0) += use_var; \ + if ((cpu_state.npxc >> 10) & 3) \ + fesetround(FE_TONEAREST); \ + } \ + while (0) +#endif + #define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \ static int opFADD##name##_a##a_size(UNUSED(uint32_t fetchdat)) \ { \ @@ -8,11 +51,7 @@ load_var = get(); \ if (cpu_state.abrt) \ return 1; \ - if ((cpu_state.npxc >> 10) & 3) \ - fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \ - ST(0) += use_var; \ - if ((cpu_state.npxc >> 10) & 3) \ - fesetround(FE_TONEAREST); \ + DO_FADD(use_var); \ FP_TAG_VALID; \ 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)); \ diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index 9a01f7496..417beea62 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -7,7 +7,7 @@ opFI(uint32_t fetchdat) cpu_state.npxc &= ~0x80; if (rmdat == 0xe1) cpu_state.npxc |= 0x80; - wait(3, 0); + wait_cycs(3, 0); return 0; } #else diff --git a/src/cpu/x87_ops_sf.h b/src/cpu/x87_ops_sf.h index 0d4fee81a..adbaa2003 100644 --- a/src/cpu/x87_ops_sf.h +++ b/src/cpu/x87_ops_sf.h @@ -354,7 +354,7 @@ sf_FI(uint32_t fetchdat) fpu_state.cwd &= ~FPU_SW_Summary; if (rmdat == 0xe1) fpu_state.cwd |= FPU_SW_Summary; - wait(3, 0); + wait_cycs(3, 0); return 0; } #else diff --git a/src/device.c b/src/device.c index 25f0b55de..07e193ead 100644 --- a/src/device.c +++ b/src/device.c @@ -349,12 +349,6 @@ device_reset_all(uint32_t match_flags) devices[c]->reset(device_priv[c]); } } - -#ifdef UNCOMMENT_LATER - /* TODO: Actually convert the LPT devices to device_t's. */ - if ((match_flags == DEVICE_ALL) || (match_flags == DEVICE_PCI)) - lpt_reset(); -#endif } void * @@ -390,42 +384,18 @@ device_get_priv(const device_t *dev) int device_available(const device_t *dev) { - if (dev != NULL) { - const device_config_t *config = dev->config; - if (config != NULL) { - while (config->type != CONFIG_END) { - if (config->type == CONFIG_BIOS) { - int roms_present = 0; - const device_config_bios_t *bios = (const device_config_bios_t *) config->bios; - - /* Go through the ROM's in the device configuration. */ - while ((bios != NULL) && - (bios->name != NULL) && - (bios->internal_name != NULL) && - (bios->files_no != 0)) { - int i = 0; - for (uint8_t bf = 0; bf < bios->files_no; bf++) - i += !!rom_present(bios->files[bf]); - if (i == bios->files_no) - roms_present++; - bios++; - } - - return (roms_present ? -1 : 0); - } - config++; - } - } + int ret = machine_device_available(dev); + if (ret == 0) { /* No CONFIG_BIOS field present, use the classic available(). */ if (dev->available != NULL) - return (dev->available()); + ret = (dev->available()); else - return 1; - } + ret = (dev != NULL); + } else + ret = (ret == -1); - /* A NULL device is never available. */ - return 0; + return ret; } uint8_t @@ -493,7 +463,6 @@ device_get_bios_local(const device_t *dev, const char *internal_name) (bios->name != NULL) && (bios->internal_name != NULL) && (bios->files_no != 0)) { - printf("Internal name was: %s", internal_name); if (!strcmp(internal_name, bios->internal_name)) return bios->local; bios++; @@ -690,9 +659,9 @@ device_get_name(const device_t *dev, int bus, char *name) fbus = strstr(tname, sbus); if (fbus == tname) strcat(name, tname + strlen(sbus) + 1); - /* Special case to not strip the "oPCI" from "Ensoniq AudioPCI" or - the "-ISA" from "AMD PCnet-ISA". */ - else if ((fbus == NULL) || (*(fbus - 1) == 'o') || (*(fbus - 1) == '-') || (*(fbus - 2) == 'r')) + /* Special case to not strip the "oPCI" from "Ensoniq AudioPCI", + the "-ISA" from "AMD PCnet-ISA" or the " PCI" from "CMD PCI-064x". */ + else if ((fbus == NULL) || (*(fbus - 1) == 'o') || (*(fbus - 1) == '-') || (*(fbus - 2) == 'r') || ((fbus[0] == 'P') && (fbus[1] == 'C') && (fbus[2] == 'I') && (fbus[3] == '-'))) strcat(name, tname); else { strncat(name, tname, fbus - tname - 1); @@ -921,8 +890,14 @@ device_is_valid(const device_t *device, int mch) { int ret = 1; - if ((device != NULL) && ((device->flags & DEVICE_BUS) != 0)) - ret = machine_has_bus(mch, device->flags & DEVICE_BUS); + if ((device != NULL) && ((device->flags & DEVICE_BUS) != 0)) { + /* Hide PCI devices on machines with only an internal PCI bus. */ + if ((device->flags & DEVICE_PCI) && + machine_has_flags(mch, MACHINE_PCI_INTERNAL)) + ret = 0; + else + ret = machine_has_bus(mch, device->flags & DEVICE_BUS); + } return ret; } @@ -969,6 +944,36 @@ machine_get_config_string(char *str) return ret; } +int +machine_device_available(const device_t *dev) +{ + if (dev != NULL) { + const device_config_t *config = dev->config; + if ((config != NULL) && (config->type == CONFIG_BIOS)) { + int roms_present = 0; + const device_config_bios_t *bios = (const device_config_bios_t *) config->bios; + + /* Go through the ROM's in the device configuration. */ + while ((bios != NULL) && + (bios->name != NULL) && + (bios->internal_name != NULL) && + (bios->files_no != 0)) { + int i = 0; + for (uint8_t bf = 0; bf < bios->files_no; bf++) + i += !!rom_present(bios->files[bf]); + if (i == bios->files_no) + roms_present++; + bios++; + } + + return (roms_present ? -1 : -2); + } + } + + /* NULL device or no CONFIG_BIOS field, return 0. */ + return 0; +} + const device_t * device_context_get_device(void) { diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index bbbab22fd..abaf87d2f 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -22,6 +22,7 @@ add_library(dev OBJECT cartridge.c cassette.c clock_ics9xxx.c + dell_jumper.c hasp.c hwm.c hwm_gl518sm.c @@ -32,19 +33,22 @@ add_library(dev OBJECT i2c_gpio.c ibm_5161.c isamem.c + isarom.c isartc.c isapnp.c kbc_at.c kbc_at_dev.c + kbc_xt.c keyboard.c keyboard_at.c keyboard_xt.c - ../lpt.c + lpt.c mouse.c mouse_bus.c mouse_microtouch_touchscreen.c mouse_ps2.c mouse_serial.c + mouse_upc.c nec_mate_unk.c novell_cardkey.c pci_bridge.c @@ -55,6 +59,7 @@ add_library(dev OBJECT smbus_ali7101.c smbus_piix4.c smbus_sis5595.c + tulip_jumper.c unittester.c ) diff --git a/src/device/cassette.c b/src/device/cassette.c index 5cde2fbd0..0577ae06f 100644 --- a/src/device/cassette.c +++ b/src/device/cassette.c @@ -152,10 +152,11 @@ pc_cas_del(pc_cassette_t *cas) } int -pc_cas_set_fname(pc_cassette_t *cas, const char *fname) +pc_cas_set_fname(pc_cassette_t *cas, char *fname) { unsigned n; const char *ext; + int offs = 0; if (cas->close) fclose(cas->fp); @@ -176,6 +177,13 @@ pc_cas_set_fname(pc_cassette_t *cas, const char *fname) return 0; } + if (strstr(fname, "wp://") == fname) { + offs = 5; + cassette_ui_writeprot = 1; + } + + fname += offs; + cas->fp = plat_fopen(fname, "r+b"); if (cas->fp == NULL) @@ -197,10 +205,10 @@ pc_cas_set_fname(pc_cassette_t *cas, const char *fname) n = strlen(fname); - cas->fname = malloc((n + 1) * sizeof(char)); + cas->fname = malloc((n + offs + 1) * sizeof(char)); if (cas->fname != NULL) - memcpy(cas->fname, fname, (n + 1) * sizeof(char)); + memcpy(cas->fname, fname - offs, (n + offs + 1) * sizeof(char)); if (n > 4) { ext = fname + (n - 4); @@ -216,6 +224,8 @@ pc_cas_set_fname(pc_cassette_t *cas, const char *fname) pc_cas_set_pcm(cas, 0); } + ui_sb_update_icon_wp(SB_CASSETTE, cassette_ui_writeprot); + return 0; } diff --git a/src/device/dell_jumper.c b/src/device/dell_jumper.c new file mode 100644 index 000000000..12fc3d13b --- /dev/null +++ b/src/device/dell_jumper.c @@ -0,0 +1,175 @@ +/* + * 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 Dell 486 and 586 Jumper Readout. + * + * Register 0x02: + * - Bit 0: ATX power: 1 = off, 0 = on. + * + * Register 0x05: + * - Appears to be: 0x02 = On-board audio enabled; + * 0x07 = On-board audio disabled. + * + * Register 0x07: + * - Bit 0: On-board NIC: 1 = present, 0 = absent; + * - Bit 1: On-board audio: 1 = present, 0 = absent; + * - Bits 4-2: + * - 0, 0, 0 = GXL; + * - 0, 0, 1 = GL+; + * - 0, 1, 0 = GXMT; + * - 0, 1, 1 = GMT+; + * - 1, 0, 0 = GXM; + * - 1, 0, 1 = GM+; + * - 1, 1, 0 = WS; + * - 1, 1, 1 = GWS+. + * + * Authors: Miran Grca, + * + * Copyright 2025 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/machine.h> +#include <86box/sound.h> +#include <86box/chipset.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> + +typedef struct dell_jumper_t { + uint8_t index; + uint8_t regs[256]; +} dell_jumper_t; + +#ifdef ENABLE_DELL_JUMPER_LOG +int dell_jumper_do_log = ENABLE_DELL_JUMPER_LOG; + +static void +dell_jumper_log(const char *fmt, ...) +{ + va_list ap; + + if (dell_jumper_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define dell_jumper_log(fmt, ...) +#endif + +static void +dell_jumper_write(uint16_t addr, uint8_t val, void *priv) +{ + dell_jumper_t *dev = (dell_jumper_t *) priv; + + dell_jumper_log("Dell Jumper: Write %02x\n", val); + + if (addr & 1) switch (dev->index) { + default: + dev->regs[dev->index] = val; + break; + case 0x02: + dev->regs[dev->index] = val; + if (val & 0x04) + /* Soft power off. */ + plat_power_off(); + break; + case 0x05: + dev->regs[dev->index] = (dev->regs[dev->index] & 0x02) | (val & 0xfd); + if (machine_snd != NULL) switch (val & 0x05) { + default: + case 0x05: + sb_vibra16s_onboard_relocate_base(0x0000, machine_snd); + break; + case 0x00: + sb_vibra16s_onboard_relocate_base(0x0220, machine_snd); + break; + } + break; + case 0x07: + break; + } else + dev->index = val; +} + +static uint8_t +dell_jumper_read(uint16_t addr, void *priv) +{ + const dell_jumper_t *dev = (dell_jumper_t *) priv; + uint8_t ret = 0xff; + + dell_jumper_log("Dell Jumper: Read %02x\n", dev->jumper); + + if (addr & 1) + ret = dev->regs[dev->index]; + else + ret = dev->index; + + return ret; +} + +static void +dell_jumper_reset(void *priv) +{ + dell_jumper_t *dev = (dell_jumper_t *) priv; + + dev->index = 0x00; + memset(dev->regs, 0x00, 256); + + if (sound_card_current[0] == SOUND_INTERNAL) + /* GXL, on-board audio present, on-board NIC absent. */ + dev->regs[0x07] = 0x02; + else + /* GXL, on-board audio absent, on-board NIC absent. */ + dev->regs[0x07] = 0x00; +} + +static void +dell_jumper_close(void *priv) +{ + dell_jumper_t *dev = (dell_jumper_t *) priv; + + free(dev); +} + +static void * +dell_jumper_init(const device_t *info) +{ + dell_jumper_t *dev = (dell_jumper_t *) calloc(1, sizeof(dell_jumper_t)); + + dell_jumper_reset(dev); + + io_sethandler(0x00e8, 0x0002, dell_jumper_read, NULL, NULL, dell_jumper_write, NULL, NULL, dev); + + return dev; +} + +const device_t dell_jumper_device = { + .name = "Dell Jumper Readout", + .internal_name = "dell_jumper", + .flags = 0, + .local = 0, + .init = dell_jumper_init, + .close = dell_jumper_close, + .reset = dell_jumper_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/device/hasp.c b/src/device/hasp.c index 3834af4cd..12dc6f2d1 100644 --- a/src/device/hasp.c +++ b/src/device/hasp.c @@ -27,8 +27,9 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> -#include <86box/lpt.h> +#include <86box/timer.h> #include <86box/device.h> +#include <86box/lpt.h> #define HASP_BYTEARRAY(...) \ { \ @@ -334,13 +335,16 @@ hasp_close(void *priv) } const lpt_device_t lpt_hasp_savquest_device = { - .name = "Protection Dongle for Savage Quest", - .internal_name = "dongle_savquest", - .init = hasp_init_savquest, - .close = hasp_close, - .write_data = hasp_write_data, - .write_ctrl = NULL, - .read_data = NULL, - .read_status = hasp_read_status, - .read_ctrl = NULL + .name = "Protection Dongle for Savage Quest", + .internal_name = "dongle_savquest", + .init = hasp_init_savquest, + .close = hasp_close, + .write_data = hasp_write_data, + .write_ctrl = NULL, + .autofeed = NULL, + .strobe = NULL, + .read_status = hasp_read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL }; diff --git a/src/device/isamem.c b/src/device/isamem.c index 62fb96f5d..1e2e92470 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -107,6 +107,7 @@ #define ISAMEM_BRAT_CARD 14 #define ISAMEM_EV165A_CARD 15 #define ISAMEM_LOTECH_EMS_CARD 16 +#define ISAMEM_MPLUS2_CARD 17 #define ISAMEM_DEBUG 0 @@ -495,6 +496,7 @@ isamem_init(const device_t *info) case ISAMEM_SYSTEMCARD_CARD: /* Microsoft SystemCard */ case ISAMEM_P5PAK_CARD: /* Paradise Systems 5-PAK */ case ISAMEM_A6PAK_CARD: /* AST SixPakPlus */ + case ISAMEM_MPLUS2_CARD: /* AST MegaPlus II */ dev->total_size = device_get_config_int("size"); dev->start_addr = device_get_config_int("start"); tot = dev->total_size; @@ -1391,10 +1393,10 @@ static const device_config_t ems5150_config[] = { .spinner = { 0 }, .selection = { { .description = "Disabled", .value = 0x0000 }, - { .description = "Board 1", .value = 0x0208 }, - { .description = "Board 2", .value = 0x020a }, - { .description = "Board 3", .value = 0x020c }, - { .description = "Board 4", .value = 0x020e }, + { .description = "208H", .value = 0x0208 }, + { .description = "20AH", .value = 0x020a }, + { .description = "20CH", .value = 0x020c }, + { .description = "20EH", .value = 0x020e }, { .description = "" } }, .bios = { { 0 } } @@ -2094,6 +2096,54 @@ static const device_t iab_device = { }; #endif /* USE_ISAMEM_IAB */ +static const device_config_t mplus2_config[] = { + // clang-format off + { + .name = "size", + .description = "Memory Size", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 64, + .file_filter = "", + .spinner = { + .min = 0, + .max = 512, + .step = 64 + }, + .selection = { { 0 } } + }, + { + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = "", + .default_int = 256, + .file_filter = "", + .spinner = { + .min = 64, + .max = 576, + .step = 64 + }, + .selection = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +static const device_t mplus2_device = { + .name = "AST MegaPlus II", + .internal_name = "mplus2", + .flags = DEVICE_ISA, + .local = ISAMEM_MPLUS2_CARD, + .init = isamem_init, + .close = isamem_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = mplus2_config +}; + static const struct { const device_t *dev; } boards[] = { @@ -2127,6 +2177,7 @@ static const struct { { &iab_device }, #endif /* USE_ISAMEM_IAB */ { &lotech_ems_device }, + { &mplus2_device }, { NULL } // clang-format on }; @@ -2165,12 +2216,12 @@ isamem_get_internal_name(int board) } int -isamem_get_from_internal_name(const char *s) +isamem_get_from_internal_name(const char *str) { int c = 0; while (boards[c].dev != NULL) { - if (!strcmp(boards[c].dev->internal_name, s)) + if (!strcmp(boards[c].dev->internal_name, str)) return c; c++; } diff --git a/src/device/isarom.c b/src/device/isarom.c new file mode 100644 index 000000000..bfdaecacf --- /dev/null +++ b/src/device/isarom.c @@ -0,0 +1,706 @@ +/* + * 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 ISA ROM card Expansions. + * + * Authors: Jasmine Iwanek, + * + * Copyright 2025 Jasmine Iwanek. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/nvr.h> +#include <86box/isarom.h> + +enum { + ISAROM_CARD = 0, + ISAROM_CARD_DUAL, + ISAROM_CARD_QUAD, + ISAROM_CARD_LBA_ENHANCER +}; + +#define BIOS_LBA_ENHANCER "roms/hdd/misc/lbaenhancer.bin" + +#ifdef ENABLE_ISAROM_LOG +int isarom_do_log = ENABLE_ISAROM_LOG; + +static void +isarom_log(const char *fmt, ...) +{ + va_list ap; + + if (isarom_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define isarom_log(fmt, ...) +#endif + +typedef struct isarom_t { + struct { + rom_t rom; + uint32_t addr; + const char *fn; + uint32_t size; + uint32_t len; + char nvr_path[64]; + uint8_t writable; + } socket[4]; + uint8_t inst; + uint8_t type; +} isarom_t; + +static inline uint8_t +get_limit(uint8_t type) +{ + switch (type) { + case ISAROM_CARD_DUAL: + return 2; + case ISAROM_CARD_QUAD: + return 4; + default: + return 1; + } +} + +static inline void +isarom_save_nvr(char *path, uint8_t *data, size_t size) +{ + if (path[0] == 0x00) + return; + + FILE *fp = nvr_fopen(path, "wb"); + if (fp) { + fwrite(data, 1, size, fp); + fclose(fp); + } +} + +void +isarom_close(void *priv) +{ + isarom_t *dev = (isarom_t *) priv; + if (!priv) + return; + + for (uint8_t i = 0; i < get_limit(dev->type); i++) { + if (dev->socket[i].writable) { + isarom_log("isarom[%u]: saving NVR for socket %u -> %s (%u bytes)\n", + dev->inst, i, dev->socket[i].nvr_path, dev->socket[i].size); + isarom_save_nvr(dev->socket[i].nvr_path, dev->socket[i].rom.rom, dev->socket[i].size); + } + } + + free(dev); +} + +static void * +isarom_init(const device_t *info) +{ + isarom_t *dev = (isarom_t *) calloc(1, sizeof(isarom_t)); + if (!dev) + return NULL; + + dev->inst = device_get_instance(); + dev->type = (uint8_t) info->local; + + isarom_log("isarom[%u]: initializing device (type=%u)\n", dev->inst, dev->type); + + for (uint8_t i = 0; i < get_limit(dev->type); i++) { + char str[22]; + char suffix[4] = ""; + if (i > 0) + snprintf(suffix, sizeof(suffix), "%d", i + 1); + + snprintf(str, sizeof(str), "bios_addr%s", suffix); + dev->socket[i].addr = device_get_config_hex20(str); + + switch (dev->type) { + case ISAROM_CARD_LBA_ENHANCER: + dev->socket[i].fn = BIOS_LBA_ENHANCER; + dev->socket[i].size = 0x4000; + break; + + default: + snprintf(str, sizeof(str), "bios_fn%s", suffix); + dev->socket[i].fn = device_get_config_string(str); + + snprintf(str, sizeof(str), "bios_size%s", suffix); + dev->socket[i].size = device_get_config_int(str); + + snprintf(str, sizeof(str), "rom_writes_enabled%s", suffix); + if (device_get_config_int(str)) + dev->socket[i].writable = 1; + break; + } + + /* Note: 2K is the smallest ROM I've found, but 86Box's memory granularity is 4K, the number + below is fine as we'll end up allocating no less than 4K due to the device config limits. */ + dev->socket[i].len = (dev->socket[i].size > 0) ? ((dev->socket[i].size - 1) | MEM_GRANULARITY_MASK) : 0; + + isarom_log("isarom[%u]: socket %u: addr=0x%05X size=%u writable=%u fn=%s\n", + dev->inst, i, dev->socket[i].addr, dev->socket[i].size, + dev->socket[i].writable, dev->socket[i].fn ? dev->socket[i].fn : "(null)"); + + if ((dev->socket[i].addr != 0) && (dev->socket[i].fn != NULL)) { + rom_init(&dev->socket[i].rom, + dev->socket[i].fn, + dev->socket[i].addr, + dev->socket[i].size, + dev->socket[i].len, + 0, + MEM_MAPPING_EXTERNAL); + + isarom_log("isarom[%u]: ROM initialized for socket %u\n", dev->inst, i); + + if (dev->socket[i].writable) { + mem_mapping_set_write_handler(&dev->socket[i].rom.mapping, rom_write, rom_writew, rom_writel); + snprintf(dev->socket[i].nvr_path, sizeof(dev->socket[i].nvr_path), "isarom_%i_%i.nvr", dev->inst, i + 1); + FILE *fp = nvr_fopen(dev->socket[i].nvr_path, "rb"); + if (fp != NULL) { + (void) !fread(dev->socket[i].rom.rom, 1, dev->socket[i].size, fp); + fclose(fp); + isarom_log("isarom[%u]: loaded %zu bytes from %s\n", dev->inst, read_bytes, dev->socket[i].nvr_path); + } else + isarom_log("isarom[%u]: NVR not found, skipping load (%s)\n", dev->inst, dev->socket[i].nvr_path); + } + } + } + + return dev; +} + +static int +isarom_lba_enhancer_available(void) +{ + return rom_present(BIOS_LBA_ENHANCER); +} + +#define BIOS_FILE_FILTER "ROM files (*.bin *.rom)|*.bin,*.rom" + +#define BIOS_ADDR_SELECTION { \ + { "Disabled", 0x00000 }, \ + { "C000H", 0xc0000 }, \ + { "C200H", 0xc2000 }, \ + { "C400H", 0xc4000 }, \ + { "C600H", 0xc6000 }, \ + { "C800H", 0xc8000 }, \ + { "CA00H", 0xca000 }, \ + { "CC00H", 0xcc000 }, \ + { "CE00H", 0xce000 }, \ + { "D000H", 0xd0000 }, \ + { "D200H", 0xd2000 }, \ + { "D400H", 0xd4000 }, \ + { "D600H", 0xd6000 }, \ + { "D800H", 0xd8000 }, \ + { "DA00H", 0xda000 }, \ + { "DC00H", 0xdc000 }, \ + { "DE00H", 0xde000 }, \ + { "E000H", 0xe0000 }, \ + { "E200H", 0xe2000 }, \ + { "E400H", 0xe4000 }, \ + { "E600H", 0xe6000 }, \ + { "E800H", 0xe8000 }, \ + { "EA00H", 0xea000 }, \ + { "EC00H", 0xec000 }, \ + { "EE00H", 0xee000 }, \ + { "", 0 } \ +} + +#define BIOS_SIZE_SELECTION { \ + { "4K", 4096 }, \ + { "8K", 8192 }, \ + { "16K", 16384 }, \ + { "32K", 32768 }, \ + { "64K", 65536 }, \ + { "", 0 } \ +} + +// clang-format off +static const device_config_t isarom_config[] = { + { + .name = "bios_fn", + .description = "BIOS file", + .type = CONFIG_FNAME, + .default_string = NULL, + .default_int = 0, + .file_filter = BIOS_FILE_FILTER, + .spinner = { 0 }, + .selection = { }, + .bios = { { 0 } } + }, + { + .name = "bios_addr", + .description = "BIOS address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0x00000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_ADDR_SELECTION, + .bios = { { 0 } } + }, + { + .name = "bios_size", + .description = "BIOS size", + .type = CONFIG_INT, + .default_string = NULL, + .default_int = 8192, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_SIZE_SELECTION, + .bios = { { 0 } } + }, + { + .name = "rom_writes_enabled", + .description = "Enable BIOS extension ROM Writes", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t isarom_dual_config[] = { + { + .name = "bios_fn", + .description = "BIOS file (ROM #1)", + .type = CONFIG_FNAME, + .default_string = NULL, + .default_int = 0, + .file_filter = BIOS_FILE_FILTER, + .spinner = { 0 }, + .selection = { }, + .bios = { { 0 } } + }, + { + .name = "bios_addr", + .description = "BIOS address (ROM #1)", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0x00000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_ADDR_SELECTION, + .bios = { { 0 } } + }, + { + .name = "bios_size", + .description = "BIOS size (ROM #1)", + .type = CONFIG_INT, + .default_string = NULL, + .default_int = 8192, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_SIZE_SELECTION, + .bios = { { 0 } } + }, + { + .name = "rom_writes_enabled", + .description = "Enable BIOS extension ROM Writes (ROM #1)", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "bios_fn2", + .description = "BIOS file (ROM #2)", + .type = CONFIG_FNAME, + .default_string = NULL, + .default_int = 0, + .file_filter = BIOS_FILE_FILTER, + .spinner = { 0 }, + .selection = { }, + .bios = { { 0 } } + }, + { + .name = "bios_addr2", + .description = "BIOS address (ROM #2)", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0x00000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_ADDR_SELECTION, + .bios = { { 0 } } + }, + { + .name = "bios_size2", + .description = "BIOS size (ROM #2)", + .type = CONFIG_INT, + .default_string = NULL, + .default_int = 8192, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_SIZE_SELECTION, + .bios = { { 0 } } + }, + { + .name = "rom_writes_enabled2", + .description = "Enable BIOS extension ROM Writes (ROM #2)", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t isarom_quad_config[] = { + { + .name = "bios_fn", + .description = "BIOS file (ROM #1)", + .type = CONFIG_FNAME, + .default_string = NULL, + .default_int = 0, + .file_filter = BIOS_FILE_FILTER, + .spinner = { 0 }, + .selection = { }, + .bios = { { 0 } } + }, + { + .name = "bios_addr", + .description = "BIOS address (ROM #1)", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0x00000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_ADDR_SELECTION, + .bios = { { 0 } } + }, + { + .name = "bios_size", + .description = "BIOS size (ROM #1)", + .type = CONFIG_INT, + .default_string = NULL, + .default_int = 8192, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_SIZE_SELECTION, + .bios = { { 0 } } + }, + { + .name = "rom_writes_enabled", + .description = "Enable BIOS extension ROM Writes (ROM #1)", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "bios_fn2", + .description = "BIOS file (ROM #2)", + .type = CONFIG_FNAME, + .default_string = NULL, + .default_int = 0, + .file_filter = BIOS_FILE_FILTER, + .spinner = { 0 }, + .selection = { }, + .bios = { { 0 } } + }, + { + .name = "bios_addr2", + .description = "BIOS address (ROM #2)", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0x00000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_ADDR_SELECTION, + .bios = { { 0 } } + }, + { + .name = "bios_size2", + .description = "BIOS size (ROM #2)", + .type = CONFIG_INT, + .default_string = NULL, + .default_int = 8192, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_SIZE_SELECTION, + .bios = { { 0 } } + }, + { + .name = "rom_writes_enabled2", + .description = "Enable BIOS extension ROM Writes (ROM #2)", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "bios_fn3", + .description = "BIOS file (ROM #3)", + .type = CONFIG_FNAME, + .default_string = NULL, + .default_int = 0, + .file_filter = BIOS_FILE_FILTER, + .spinner = { 0 }, + .selection = { }, + .bios = { { 0 } } + }, + { + .name = "bios_addr3", + .description = "BIOS address (ROM #3)", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0x00000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_ADDR_SELECTION, + .bios = { { 0 } } + }, + { + .name = "bios_size3", + .description = "BIOS size (ROM #3)", + .type = CONFIG_INT, + .default_string = NULL, + .default_int = 8192, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_SIZE_SELECTION, + .bios = { { 0 } } + }, + { + .name = "rom_writes_enabled3", + .description = "Enable BIOS extension ROM Writes (ROM #3)", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "bios_fn4", + .description = "BIOS file (ROM #4)", + .type = CONFIG_FNAME, + .default_string = NULL, + .default_int = 0, + .file_filter = BIOS_FILE_FILTER, + .spinner = { 0 }, + .selection = { }, + .bios = { { 0 } } + }, + { + .name = "bios_addr4", + .description = "BIOS address (ROM #4)", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0x00000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_ADDR_SELECTION, + .bios = { { 0 } } + }, + { + .name = "bios_size4", + .description = "BIOS size (ROM #4)", + .type = CONFIG_INT, + .default_string = NULL, + .default_int = 8192, + .file_filter = NULL, + .spinner = { 0 }, + .selection = BIOS_SIZE_SELECTION, + .bios = { { 0 } } + }, + { + .name = "rom_writes_enabled4", + .description = "Enable BIOS extension ROM Writes (ROM #4)", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t lba_enhancer_config[] = { + { + .name = "bios_addr", + .description = "BIOS address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xc8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "C800H", .value = 0xc8000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D400H", .value = 0xd4000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +static const device_t isarom_device = { + .name = "Generic ISA ROM Board", + .internal_name = "isarom", + .flags = DEVICE_ISA, + .local = ISAROM_CARD, + .init = isarom_init, + .close = isarom_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = isarom_config +}; + +static const device_t isarom_dual_device = { + .name = "Generic Dual ISA ROM Board", + .internal_name = "isarom_dual", + .flags = DEVICE_ISA, + .local = ISAROM_CARD_DUAL, + .init = isarom_init, + .close = isarom_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = isarom_dual_config +}; + +static const device_t isarom_quad_device = { + .name = "Generic Quad ISA ROM Board", + .internal_name = "isarom_quad", + .flags = DEVICE_ISA, + .local = ISAROM_CARD_QUAD, + .init = isarom_init, + .close = isarom_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = isarom_quad_config +}; + +static const device_t lba_enhancer_device = { + .name = "Vision Systems LBA Enhancer", + .internal_name = "lba_enhancer", + .flags = DEVICE_ISA, + .local = ISAROM_CARD_LBA_ENHANCER, + .init = isarom_init, + .close = isarom_close, + .reset = NULL, + .available = isarom_lba_enhancer_available, + .speed_changed = NULL, + .force_redraw = NULL, + .config = lba_enhancer_config +}; + +static const struct { + const device_t *dev; +} boards[] = { + // clang-format off + { &device_none }, + { &isarom_device }, + { &isarom_dual_device }, + { &isarom_quad_device }, + { &lba_enhancer_device }, + { NULL } + // clang-format on +}; + +void +isarom_reset(void) +{ + for (uint8_t i = 0; i < ISAROM_MAX; i++) { + if (isarom_type[i] == 0) + continue; + + /* Add the device instance to the system. */ + device_add_inst(boards[isarom_type[i]].dev, i + 1); + } +} + +const char * +isarom_get_name(int board) +{ + if (boards[board].dev == NULL) + return NULL; + + return (boards[board].dev->name); +} + +const char * +isarom_get_internal_name(int board) +{ + return device_get_internal_name(boards[board].dev); +} + +int +isarom_get_from_internal_name(const char *str) +{ + int c = 0; + + while (boards[c].dev != NULL) { + if (!strcmp(boards[c].dev->internal_name, str)) + return c; + c++; + } + + /* Not found. */ + return 0; +} + +const device_t * +isarom_get_device(int board) +{ + /* Add the device instance to the system. */ + return boards[board].dev; +} + +int +isarom_has_config(int board) +{ + if (boards[board].dev == NULL) + return 0; + + return (boards[board].dev->config ? 1 : 0); +} diff --git a/src/device/isartc.c b/src/device/isartc.c index 5d6b4aea4..664793db3 100644 --- a/src/device/isartc.c +++ b/src/device/isartc.c @@ -89,10 +89,11 @@ #define ISARTC_P5PAK 2 #define ISARTC_A6PAK 3 #define ISARTC_VENDEX 4 +#define ISARTC_MPLUS2 5 #define ISARTC_MM58167 10 -#define ISARTC_ROM_MM58167_1 "roms/rtc/glatick/GLaTICK_0.8.5_NS_RP.ROM" -#define ISARTC_ROM_MM58167_2 "roms/rtc/glatick/GLaTICK_0.8.5_86B.ROM" +#define ISARTC_ROM_MM58167_1 "roms/rtc/glatick/GLaTICK_0.8.8_NS_86B.ROM" /* Generic 58167, AST or EV-170 */ +#define ISARTC_ROM_MM58167_2 "roms/rtc/glatick/GLaTICK_0.8.8_NS_86B2.ROM" /* PII-147 */ #define ISARTC_DEBUG 0 @@ -409,6 +410,7 @@ mm67_read(uint16_t port, void *priv) break; case MM67_AL_MSEC: + case MM67_MSEC: ret = dev->nvr.regs[reg] & 0xf0; break; @@ -416,6 +418,10 @@ mm67_read(uint16_t port, void *priv) ret = dev->nvr.regs[reg] & 0x0f; break; + case MM67_DOW: + ret = dev->nvr.regs[reg] & 0x07; + break; + default: ret = dev->nvr.regs[reg]; break; @@ -532,8 +538,8 @@ isartc_init(const device_t *info) switch (dev->board) { case ISARTC_MM58167: /* Generic MM58167 RTC */ { - int rom_addr = device_get_config_hex20("bios_addr"); - if (rom_addr != -1) + uint32_t rom_addr = device_get_config_hex20("bios_addr"); + if (rom_addr != 0) rom_init(&dev->rom, ISARTC_ROM_MM58167_1, rom_addr, 0x0800, 0x7ff, 0, MEM_MAPPING_EXTERNAL); @@ -563,8 +569,9 @@ isartc_init(const device_t *info) dev->year = MM67_AL_HUNTEN; /* year, NON STANDARD */ break; - case ISARTC_P5PAK: /* Paradise Systems 5PAK */ - case ISARTC_A6PAK: /* AST SixPakPlus */ + case ISARTC_P5PAK: /* Paradise Systems 5PAK */ + case ISARTC_A6PAK: /* AST SixPakPlus */ + case ISARTC_MPLUS2: /* AST MegaPlus II */ dev->flags |= FLAG_YEAR80; dev->base_addr = 0x02c0; dev->base_addrsz = 32; @@ -786,6 +793,42 @@ static const device_t a6pak_device = { .config = a6pak_config }; +static const device_config_t mplus2_config[] = { + // clang-format off + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = -1, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { "Disabled", -1 }, + { "IRQ2", 2 }, + { "IRQ3", 3 }, + { "IRQ5", 5 }, + { "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +static const device_t mplus2_device = { + .name = "AST MegaPlus II", + .internal_name = "mplus2", + .flags = DEVICE_ISA, + .local = ISARTC_MPLUS2, + .init = isartc_init, + .close = isartc_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = mplus2_config +}; + static const device_config_t mm58167_config[] = { // clang-format off { @@ -823,14 +866,14 @@ static const device_config_t mm58167_config[] = { }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xcc000, .file_filter = NULL, .spinner = { 0 }, .selection = { - { .description = "Disabled", .value = -1 }, + { .description = "Disabled", .value = 0x00000 }, { .description = "C800H", .value = 0xc8000 }, { .description = "CA00H", .value = 0xca000 }, { .description = "CC00H", .value = 0xcc000 }, @@ -897,6 +940,7 @@ static const struct { { &pii147_device }, { &p5pak_device }, { &a6pak_device }, + { &mplus2_device }, { &mm58167_device }, { NULL } // clang-format on @@ -919,12 +963,12 @@ isartc_get_internal_name(int board) } int -isartc_get_from_internal_name(char *s) +isartc_get_from_internal_name(const char *str) { int c = 0; while (boards[c].dev != NULL) { - if (!strcmp(boards[c].dev->internal_name, s)) + if (!strcmp(boards[c].dev->internal_name, str)) return c; c++; } diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 447c07780..540bf532a 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -8,13 +8,11 @@ * * Intel 8042 (AT keyboard controller) emulation. * - * - * * Authors: Miran Grca, * EngiNerd, * - * Copyright 2023 Miran Grca. - * Copyright 2023 EngiNerd. + * Copyright 2023-2025 Miran Grca. + * Copyright 2023-2025 EngiNerd. */ #include #include @@ -29,24 +27,19 @@ #include <86box/timer.h> #include <86box/io.h> #include <86box/pic.h> -#include <86box/pit.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> -#include <86box/ppi.h> #include <86box/mem.h> #include <86box/device.h> +#include <86box/dma.h> #include <86box/machine.h> #include <86box/m_at_t3100e.h> #include <86box/fdd.h> #include <86box/fdc.h> -#include <86box/sound.h> -#include <86box/snd_speaker.h> +#include <86box/pci.h> #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 @@ -145,6 +138,11 @@ typedef struct atkbc_t { /* Internal FIFO for the purpose of commands with multi-byte output. */ uint8_t key_ctrl_queue[64]; + uint8_t handler_enable[2]; + + uint16_t base_addr[2]; + uint16_t irq[2]; + uint32_t flags; /* Main timers. */ @@ -157,8 +155,13 @@ 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 *priv, uint8_t val); - uint8_t (*write64_ven)(void *priv, uint8_t val); + struct { + uint8_t (*read)(uint16_t port, void *priv); + void (*write)(uint16_t port, uint8_t val, void *priv); + } handlers[2]; + + uint8_t (*write_cmd_data_ven)(void *priv, uint8_t val); + uint8_t (*write_cmd_ven)(void *priv, uint8_t val); } atkbc_t; /* Keyboard controller ports. */ @@ -167,8 +170,6 @@ kbc_at_port_t *kbc_at_ports[2] = { NULL, NULL }; static uint8_t kbc_ami_revision = '8'; static uint8_t kbc_award_revision = 0x42; -static uint8_t kbc_handler_set = 0; - static void (*kbc_at_do_poll)(atkbc_t *dev); /* Non-translated to translated scan codes. */ @@ -362,12 +363,19 @@ kbc_do_irq(atkbc_t *dev) if (dev->do_irq) { /* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly written to pulse its P2 IRQ bits, so they should be kept as as edge-triggered here. */ - picint_common(1 << 1, 0, 0, NULL); - picint_common(1 << 12, 0, 0, NULL); - if (dev->channel >= 2) - picint_common(1 << 12, 0, 1, NULL); - else - picint_common(1 << 1, 0, 1, NULL); + if (dev->irq[0] != 0xffff) + picint_common(1 << dev->irq[0], 0, 0, NULL); + + if (dev->irq[1] != 0xffff) + picint_common(1 << dev->irq[1], 0, 0, NULL); + + if (dev->channel >= 2) { + if (dev->irq[1] != 0xffff) + picint_common(1 << dev->irq[1], 0, 1, NULL); + } else { + if (dev->irq[0] != 0xffff) + picint_common(1 << dev->irq[0], 0, 1, NULL); + } dev->do_irq = 0; } @@ -404,7 +412,9 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi) } else if (dev->mem[0x20] & 0x01) kbc_set_do_irq(dev, channel); } else if (dev->mem[0x20] & 0x01) - picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ + /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */ + if (dev->irq[0] != 0xffff) + picintlevel(1 << dev->irq[0], &dev->irq_state); #ifdef WRONG_CONDITION if ((dev->channel > 0) || dev->is_asic || (kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM)) @@ -509,9 +519,6 @@ kbc_scan_kbd_at(atkbc_t *dev) } } -static void -write_p2(atkbc_t *dev, uint8_t val); - static void kbc_at_poll_at(atkbc_t *dev) { @@ -778,6 +785,7 @@ static void write_p2(atkbc_t *dev, uint8_t val) { uint8_t old = dev->p2; + kbc_at_log("ATkbc: write P2: %02X (old: %02X)\n", val, dev->p2); uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; @@ -786,10 +794,12 @@ 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, NULL); + if (dev->irq[1] != 0xffff) + picint_common(1 << dev->irq[1], 0, val & 0x20, NULL); /* IRQ 1 */ - picint_common(1 << 1, 0, val & 0x10, NULL); + if (dev->irq[0] != 0xffff) + picint_common(1 << dev->irq[0], 0, val & 0x10, NULL); } #endif @@ -813,7 +823,9 @@ write_p2(atkbc_t *dev, uint8_t val) softresetx86(); /* Pulse reset! */ cpu_set_edx(); flushmmucache(); - if ((kbc_ven == KBC_VEN_ALI) || !strcmp(machine_get_internal_name(), "spc7700plw")) + if ((kbc_ven == KBC_VEN_ALI) || + !strcmp(machine_get_internal_name(), "spc7700plw") || + !strcmp(machine_get_internal_name(), "pl4600c")) smbase = 0x00030000; /* Yes, this is a hack, but until someone gets ahold of the real PCD-2L @@ -851,6 +863,25 @@ write_p2(atkbc_t *dev, uint8_t val) } } +uint8_t +kbc_at_read_p(void *priv, uint8_t port, uint8_t mask) +{ + atkbc_t *dev = (atkbc_t *) priv; + uint8_t *p = (port == 2) ? &dev->p2 : &dev->p1; + uint8_t ret = *p & mask; + + return ret; +} + +void +kbc_at_write_p(void *priv, uint8_t port, uint8_t mask, uint8_t val) +{ + atkbc_t *dev = (atkbc_t *) priv; + uint8_t *p = (port == 2) ? &dev->p2 : &dev->p1; + + *p = (*p & mask) | val; +} + static void write_p2_fast_a20(atkbc_t *dev, uint8_t val) { @@ -915,224 +946,7 @@ pulse_poll(void *priv) } static uint8_t -write64_generic(void *priv, uint8_t val) -{ - atkbc_t *dev = (atkbc_t *) priv; - uint8_t current_drive; - uint8_t fixed_bits; - uint8_t kbc_ven = 0x0; - kbc_ven = dev->flags & KBC_VEN_MASK; - - switch (val) { - case 0xa4: /* check if password installed */ - if (dev->misc_flags & FLAG_PS2) { - kbc_at_log("ATkbc: check if password installed\n"); - kbc_delay_to_ob(dev, 0xf1, 0, 0x00); - return 0; - } - break; - - case 0xa5: /* load security */ - kbc_at_log("ATkbc: load security\n"); - dev->wantdata = 1; - dev->state = STATE_KBC_PARAM; - return 0; - - case 0xa7: /* disable auxiliary port */ - if (dev->misc_flags & FLAG_PS2) { - kbc_at_log("ATkbc: disable auxiliary port\n"); - set_enable_aux(dev, 0); - return 0; - } - break; - - case 0xa8: /* Enable auxiliary port */ - if (dev->misc_flags & FLAG_PS2) { - kbc_at_log("ATkbc: enable auxiliary port\n"); - set_enable_aux(dev, 1); - return 0; - } - break; - - case 0xa9: /* Test auxiliary port */ - kbc_at_log("ATkbc: test auxiliary port\n"); - if (dev->misc_flags & FLAG_PS2) { - kbc_delay_to_ob(dev, 0x00, 0, 0x00); /* no error, this is testing the channel 2 interface */ - return 0; - } - 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); - return 0; - - /* - P1 bits: 76543210 - ----------------- - IBM PS/1: xxxxxxxx - IBM PS/2 MCA: xxxxx1xx - Intel AMI Pentium BIOS'es with AMI MegaKey KB-5 keyboard controller: x1x1xxxx - Acer: xxxxx0xx - Packard Bell PB450: xxxxx1xx - P6RP4: xx1xx1xx - Epson Action Tower 2600: xxxx01xx - TriGem Hawk: xxxx11xx - - Machine input based on current code: 11111111 - Everything non-Green: Pull down bit 7 if not PS/2 and keyboard is inhibited. - Pull down bit 6 if primary display is CGA. - Xi8088: Pull down bit 6 if primary display is MDA. - Acer: Pull down bit 6 if primary display is MDA. - Pull down bit 2 always (must be so to enable CMOS Setup). - IBM PS/1: Pull down bit 6 if current floppy drive is 3.5". - Epson Action Tower 2600: Pull down bit 3 always (for Epson logo). - NCR: Pull down bit 5 always (power-on default speed = high). - Pull down bit 3 if there is no FPU. - Pull down bits 1 and 0 always? - Compaq: Pull down bit 6 if Compaq dual-scan display is in use. - Pull down bit 5 if system board DIP switch is ON. - Pull down bit 4 if CPU speed selected is auto. - Pull down bit 3 if CPU speed selected is slow (4 MHz). - Pull down bit 2 if FPU is present. - Pull down bits 1 and 0 always? - - Bit 7: AT KBC only - keyboard inhibited (often physical lock): 0 = yes, 1 = no (also Compaq); - 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"; - 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. - Bit 4: (Which board?): RAM on motherboard: 0 = 512 kB, 1 = 256 kB; - NCR: RAM on motherboard: 0 = unsupported, 1 = 512 kB; - Intel AMI MegaKey KB-5: Must be 1; - IBM PS/1: Ignored; - Compaq: 0 = Auto speed selected, 1 = High speed selected. - Bit 3: TriGem AMIKey: most significant bit of 2-bit OEM ID; - NCR: Coprocessor detect (1 = yes, 0 = no); - Compaq: 0 = Slow (4 MHz), 1 = Fast (8 MHz); - Sometimes configured for clock switching; - Bit 2: TriGem AMIKey: least significant bit of 2-bit OEM ID; - Bit 3, 2: - 1, 1: TriGem logo; - 1, 0: Garbled logo; - 0, 1: Epson logo; - 0, 0: Generic AMI logo. - NCR: Unused; - IBM PS/2: Keyboard power: 0 = no power (fuse error), 1 = OK - (for some reason, www.win.tue.nl has this in reverse); - Compaq: FPU: 0 = 80287, 1 = none; - Sometimes configured for clock switching; - Bit 1: PS/2: Auxiliary device data in; - Compaq: Reserved; - NCR: High/auto speed. - Bit 0: PS/2: Keyboard device data in; - Compaq: Reserved; - NCR: DMA mode. - */ - case 0xc0: /* read P1 */ - kbc_at_log("ATkbc: read P1\n"); - fixed_bits = 4; - /* The SMM handlers of Intel AMI Pentium BIOS'es expect bit 6 to be set. */ - if ((kbc_ven == KBC_VEN_AMI) && ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_GREEN)) - fixed_bits |= 0x40; - if (kbc_ven == KBC_VEN_IBM_PS1) { - current_drive = fdc_get_current_drive(); - /* (B0 or F0) | (fdd_is_525(current_drive) on bit 6) */ - kbc_delay_to_ob(dev, dev->p1 | fixed_bits | (fdd_is_525(current_drive) ? 0x40 : 0x00), - 0, 0x00); - } else if (kbc_ven == KBC_VEN_NCR) { - /* switch settings - * bit 7: keyboard disable - * bit 6: display type (0 color, 1 mono) - * bit 5: power-on default speed (0 high, 1 low) - * bit 4: sense RAM size (0 unsupported, 1 512k on system board) - * bit 3: coprocessor detect - * bit 2: unused - * bit 1: high/auto speed - * bit 0: dma mode - */ - /* (B0 or F0) | 0x04 | (display on bit 6) | (fpu on bit 3) */ - kbc_delay_to_ob(dev, (dev->p1 | fixed_bits | (video_is_mda() ? 0x40 : 0x00) | (hasfpu ? 0x08 : 0x00)) & 0xdf, - 0, 0x00); - } else if (kbc_ven == KBC_VEN_TRIGEM_AMI) { - /* Bit 3, 2: - 1, 1: TriGem logo; - 1, 0: Garbled logo; - 0, 1: Epson logo; - 0, 0: Generic AMI logo. */ - if (dev->misc_flags & FLAG_PCI) - fixed_bits |= 8; - /* (B0 or F0) | (0x04 or 0x0c) */ - kbc_delay_to_ob(dev, dev->p1 | fixed_bits, 0, 0x00); - } else if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_GREEN)) { - /* (B0 or F0) | (0x08 or 0x0c) */ - uint8_t p1_out = ((dev->p1 | fixed_bits) & 0xf0) | - (((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0x08 : 0x0c); - if (!strcmp(machine_get_internal_name(), "alfredo")) - p1_out &= 0xef; - kbc_delay_to_ob(dev, p1_out, 0, 0x00); - } else if (kbc_ven == KBC_VEN_COMPAQ) - kbc_delay_to_ob(dev, dev->p1 | (hasfpu ? 0x00 : 0x04), 0, 0x00); - else - /* (B0 or F0) | (0x04 or 0x44) */ - kbc_delay_to_ob(dev, dev->p1 | fixed_bits, 0, 0x00); - dev->p1 = ((dev->p1 + 1) & 3) | (dev->p1 & 0xfc); - return 0; - - case 0xc1: /*Copy bits 0 to 3 of P1 to status bits 4 to 7*/ - if (dev->misc_flags & FLAG_PS2) { - kbc_at_log("ATkbc: copy bits 0 to 3 of P1 to status bits 4 to 7\n"); - dev->status &= 0x0f; - dev->status |= (dev->p1 << 4); - return 0; - } - break; - - case 0xc2: /*Copy bits 4 to 7 of P1 to status bits 4 to 7*/ - if (dev->misc_flags & FLAG_PS2) { - kbc_at_log("ATkbc: copy bits 4 to 7 of P1 to status bits 4 to 7\n"); - dev->status &= 0x0f; - dev->status |= (dev->p1 & 0xf0); - return 0; - } - break; - - case 0xd3: /* write auxiliary output buffer */ - if (dev->misc_flags & FLAG_PS2) { - kbc_at_log("ATkbc: write auxiliary output buffer\n"); - dev->wantdata = 1; - dev->state = STATE_KBC_PARAM; - return 0; - } - break; - - case 0xd4: /* write to auxiliary port */ - kbc_at_log("ATkbc: write to auxiliary port\n"); - dev->wantdata = 1; - dev->state = STATE_KBC_PARAM; - return 0; - - case 0xf0 ... 0xff: - kbc_at_log("ATkbc: pulse %01X\n", val & 0x0f); - pulse_output(dev, val & 0x0f); - return 0; - - default: - break; - } - - kbc_at_log("ATkbc: bad command %02X\n", val); - return 1; -} - -static uint8_t -write60_ami(void *priv, uint8_t val) +write_cmd_data_ami(void *priv, uint8_t val) { atkbc_t *dev = (atkbc_t *) priv; @@ -1202,39 +1016,47 @@ kbc_at_set_ps2(void *priv, const uint8_t ps2) } static uint8_t -write64_ami(void *priv, uint8_t val) +write_cmd_ami(void *priv, uint8_t val) { atkbc_t *dev = (atkbc_t *) priv; uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; + uint8_t ret = 1; switch (val) { + default: + break; + case 0x00 ... 0x1f: kbc_at_log("ATkbc: AMI - alias read from %08X\n", val); kbc_delay_to_ob(dev, dev->mem[val + 0x20], 0, 0x00); - return 0; + ret = 0; + break; case 0x40 ... 0x5f: kbc_at_log("ATkbc: AMI - alias write to %08X\n", dev->command); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; + ret = 0; + break; case 0xa0: /* copyright message */ kbc_at_queue_add(dev, 0x28); kbc_at_queue_add(dev, 0x00); - return 0; + ret = 0; + break; case 0xa1: /* get controller version */ kbc_at_log("ATkbc: AMI - get controller version\n"); kbc_delay_to_ob(dev, kbc_ami_revision, 0, 0x00); - return 0; + ret = 0; + break; case 0xa2: /* clear keyboard controller lines P22/P23 */ if (!(dev->misc_flags & FLAG_PS2)) { kbc_at_log("ATkbc: AMI - clear KBC lines P22 and P23\n"); write_p2(dev, dev->p2 & 0xf3); kbc_delay_to_ob(dev, 0x00, 0, 0x00); - return 0; + ret = 0; } break; @@ -1243,7 +1065,7 @@ write64_ami(void *priv, uint8_t val) kbc_at_log("ATkbc: AMI - set KBC lines P22 and P23\n"); write_p2(dev, dev->p2 | 0x0c); kbc_delay_to_ob(dev, 0x00, 0, 0x00); - return 0; + ret = 0; } break; @@ -1251,7 +1073,7 @@ write64_ami(void *priv, uint8_t val) if (!(dev->misc_flags & FLAG_PS2)) { kbc_at_log("ATkbc: AMI - write clock = low\n"); dev->misc_flags &= ~FLAG_CLOCK; - return 0; + ret = 0; } break; @@ -1259,14 +1081,15 @@ write64_ami(void *priv, uint8_t val) if (!(dev->misc_flags & FLAG_PS2)) { kbc_at_log("ATkbc: AMI - write clock = high\n"); dev->misc_flags |= FLAG_CLOCK; - return 0; + ret = 0; } + break; case 0xa6: /* read clock */ if (!(dev->misc_flags & FLAG_PS2)) { kbc_at_log("ATkbc: AMI - read clock\n"); kbc_delay_to_ob(dev, (dev->misc_flags & FLAG_CLOCK) ? 0xff : 0x00, 0, 0x00); - return 0; + ret = 0; } break; @@ -1274,7 +1097,7 @@ write64_ami(void *priv, uint8_t val) if (!(dev->misc_flags & FLAG_PS2)) { kbc_at_log("ATkbc: AMI - write cache bad\n"); dev->misc_flags &= FLAG_CACHE; - return 0; + ret = 0; } break; @@ -1282,7 +1105,7 @@ write64_ami(void *priv, uint8_t val) if (!(dev->misc_flags & FLAG_PS2)) { kbc_at_log("ATkbc: AMI - write cache good\n"); dev->misc_flags |= FLAG_CACHE; - return 0; + ret = 0; } break; @@ -1290,7 +1113,7 @@ write64_ami(void *priv, uint8_t val) if (!(dev->misc_flags & FLAG_PS2)) { kbc_at_log("ATkbc: AMI - read cache\n"); kbc_delay_to_ob(dev, (dev->misc_flags & FLAG_CACHE) ? 0xff : 0x00, 0, 0x00); - return 0; + ret = 0; } break; @@ -1300,7 +1123,7 @@ write64_ami(void *priv, uint8_t val) dev->wantdata = 1; dev->state = STATE_KBC_PARAM; dev->command_phase = 1; - return 0; + ret = 0; } break; @@ -1311,7 +1134,8 @@ write64_ami(void *priv, uint8_t val) dev->p1 &= ~(1 << (val & 0x03)); kbc_delay_to_ob(dev, dev->ob, 0, 0x00); dev->pending++; - return 0; + ret = 0; + break; /* TODO: The ICS SB486PV sends command B4 but expects to read *TWO* bytes. */ case 0xb4: case 0xb5: @@ -1319,9 +1143,13 @@ write64_ami(void *priv, uint8_t val) kbc_at_log("ATkbc: set KBC lines P22-P23 (P2 bits 2-3) low\n"); if (!(dev->flags & DEVICE_PCI)) write_p2(dev, dev->p2 & ~(4 << (val & 0x01))); - kbc_delay_to_ob(dev, dev->ob, 0, 0x00); + if (strstr(machine_get_internal_name(), "sb486pv") != NULL) + kbc_delay_to_ob(dev, 0x03, 0, 0x00); + else + kbc_delay_to_ob(dev, dev->ob, 0, 0x00); dev->pending++; - return 0; + ret = 0; + break; case 0xb8 ... 0xbb: /* set KBC lines P10-P13 (P1 bits 0-3) high */ @@ -1331,7 +1159,8 @@ write64_ami(void *priv, uint8_t val) kbc_delay_to_ob(dev, dev->ob, 0, 0x00); dev->pending++; } - return 0; + ret = 0; + break; case 0xbc: case 0xbd: /* set KBC lines P22-P23 (P2 bits 2-3) high */ @@ -1340,13 +1169,15 @@ write64_ami(void *priv, uint8_t val) write_p2(dev, dev->p2 | (4 << (val & 0x01))); kbc_delay_to_ob(dev, dev->ob, 0, 0x00); dev->pending++; - return 0; + ret = 0; + break; case 0xc1: /* write P1 */ kbc_at_log("ATkbc: AMI MegaKey - write P1\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; + ret = 0; + break; case 0xc4: /* set KBC line P14 low */ @@ -1354,14 +1185,16 @@ write64_ami(void *priv, uint8_t val) dev->p1 &= 0xef; kbc_delay_to_ob(dev, dev->ob, 0, 0x00); dev->pending++; - return 0; + ret = 0; + break; case 0xc5: /* set KBC line P15 low */ kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) low\n"); dev->p1 &= 0xdf; kbc_delay_to_ob(dev, dev->ob, 0, 0x00); dev->pending++; - return 0; + ret = 0; + break; case 0xc8: /* @@ -1370,7 +1203,8 @@ write64_ami(void *priv, uint8_t val) */ kbc_at_log("ATkbc: AMI - unblock KBC lines P22 and P23\n"); dev->ami_flags &= 0xfb; - return 0; + ret = 0; + break; case 0xc9: /* @@ -1379,7 +1213,15 @@ write64_ami(void *priv, uint8_t val) */ kbc_at_log("ATkbc: AMI - block KBC lines P22 and P23\n"); dev->ami_flags |= 0x04; - return 0; + ret = 0; + break; + + case 0xcb: /* set keyboard mode */ + kbc_at_log("ATkbc: AMI - set keyboard mode\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + ret = 0; + break; case 0xcc: /* set KBC line P14 high */ @@ -1387,32 +1229,36 @@ write64_ami(void *priv, uint8_t val) dev->p1 |= 0x10; kbc_delay_to_ob(dev, dev->ob, 0, 0x00); dev->pending++; - return 0; + ret = 0; + break; case 0xcd: /* set KBC line P15 high */ kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) high\n"); dev->p1 |= 0x20; kbc_delay_to_ob(dev, dev->ob, 0, 0x00); dev->pending++; - return 0; + ret = 0; + break; case 0xef: /* ??? - sent by AMI486 */ kbc_at_log("ATkbc: ??? - sent by AMI486\n"); - return 0; - - default: + ret = 0; break; } - return write64_generic(dev, val); + return ret; } static uint8_t -write60_phoenix(void *priv, uint8_t val) +write_cmd_data_phoenix(void *priv, uint8_t val) { atkbc_t *dev = (atkbc_t *) priv; + uint8_t ret = 1; switch (dev->command) { + default: + break; + /* TODO: Make this actually load the password. */ case 0xa3: /* Load Extended Password */ kbc_at_log("ATkbc: Phoenix - Load Extended Password\n"); @@ -1422,120 +1268,139 @@ write60_phoenix(void *priv, uint8_t val) dev->wantdata = 1; dev->state = STATE_KBC_PARAM; } - return 0; + ret = 0; + break; case 0xaf: /* Set Inactivity Timer */ kbc_at_log("ATkbc: Phoenix - Set Inactivity Timer\n"); dev->mem[0x3a] = val; dev->command_phase = 0; - return 0; + ret = 0; + break; case 0xb8: /* Set Extended Memory Access Index */ kbc_at_log("ATkbc: Phoenix - Set Extended Memory Access Index\n"); dev->mem_addr = val; dev->command_phase = 0; - return 0; + ret = 0; + break; case 0xbb: /* Set Extended Memory */ kbc_at_log("ATkbc: Phoenix - Set Extended Memory\n"); dev->mem[dev->mem_addr] = val; dev->command_phase = 0; - return 0; + ret = 0; + break; case 0xbd: /* Set MultiKey Variable */ kbc_at_log("ATkbc: Phoenix - Set MultiKey Variable\n"); if ((dev->mem_addr > 0) && (dev->mem_addr <= multikey_vars[0x00])) dev->mem[multikey_vars[dev->mem_addr]] = val; dev->command_phase = 0; - return 0; + ret = 0; + break; case 0xc7: /* Set Port1 bits */ kbc_at_log("ATkbc: Phoenix - Set Port1 bits\n"); dev->p1 |= val; dev->command_phase = 0; - return 0; + ret = 0; + break; case 0xc8: /* Clear Port1 bits */ kbc_at_log("ATkbc: Phoenix - Clear Port1 bits\n"); dev->p1 &= ~val; dev->command_phase = 0; - return 0; + ret = 0; + break; case 0xc9: /* Set Port2 bits */ kbc_at_log("ATkbc: Phoenix - Set Port2 bits\n"); write_p2(dev, dev->p2 | val); dev->command_phase = 0; - return 0; + ret = 0; + break; case 0xca: /* Clear Port2 bits */ kbc_at_log("ATkbc: Phoenix - Clear Port2 bits\n"); write_p2(dev, dev->p2 & ~val); dev->command_phase = 0; - return 0; - - default: + ret = 0; break; } - return 1; + return ret; } static uint8_t -write64_phoenix(void *priv, uint8_t val) +write_cmd_phoenix(void *priv, uint8_t val) { atkbc_t *dev = (atkbc_t *) priv; + uint8_t ret = 1; switch (val) { + default: + break; + case 0x00 ... 0x1f: kbc_at_log("ATkbc: Phoenix - alias read from %08X\n", val); kbc_delay_to_ob(dev, dev->mem[val + 0x20], 0, 0x00); - return 0; + ret = 0; + break; case 0x40 ... 0x5f: kbc_at_log("ATkbc: Phoenix - alias write to %08X\n", dev->command); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; + ret = 0; + break; case 0xa2: /* Test Extended Password */ kbc_at_log("ATkbc: Phoenix - Test Extended Password\n"); kbc_at_queue_add(dev, 0xf1); /* Extended Password not loaded */ - return 0; + ret = 0; + break; /* TODO: Make this actually load the password. */ case 0xa3: /* Load Extended Password */ kbc_at_log("ATkbc: Phoenix - Load Extended Password\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; + ret = 0; + break; case 0xaf: /* Set Inactivity Timer */ kbc_at_log("ATkbc: Phoenix - Set Inactivity Timer\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; + ret = 0; + break; case 0xb8: /* Set Extended Memory Access Index */ kbc_at_log("ATkbc: Phoenix - Set Extended Memory Access Index\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; + ret = 0; + break; case 0xb9: /* Get Extended Memory Access Index */ kbc_at_log("ATkbc: Phoenix - Get Extended Memory Access Index\n"); kbc_at_queue_add(dev, dev->mem_addr); - return 0; + ret = 0; + break; case 0xba: /* Get Extended Memory */ kbc_at_log("ATkbc: Phoenix - Get Extended Memory\n"); kbc_at_queue_add(dev, dev->mem[dev->mem_addr]); - return 0; + ret = 0; + break; case 0xbb: /* Set Extended Memory */ kbc_at_log("ATkbc: Phoenix - Set Extended Memory\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; + ret = 0; + break; case 0xbc: /* Get MultiKey Variable */ kbc_at_log("ATkbc: Phoenix - Get MultiKey Variable\n"); @@ -1545,37 +1410,43 @@ write64_phoenix(void *priv, uint8_t val) kbc_at_queue_add(dev, dev->mem[multikey_vars[dev->mem_addr]]); else kbc_at_queue_add(dev, 0xff); - return 0; + ret = 0; + break; case 0xbd: /* Set MultiKey Variable */ kbc_at_log("ATkbc: Phoenix - Set MultiKey Variable\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; + ret = 0; + break; case 0xc7: /* Set Port1 bits */ kbc_at_log("ATkbc: Phoenix - Set Port1 bits\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; + ret = 0; + break; case 0xc8: /* Clear Port1 bits */ kbc_at_log("ATkbc: Phoenix - Clear Port1 bits\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; + ret = 0; + break; case 0xc9: /* Set Port2 bits */ kbc_at_log("ATkbc: Phoenix - Set Port2 bits\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; + ret = 0; + break; case 0xca: /* Clear Port2 bits */ kbc_at_log("ATkbc: Phoenix - Clear Port2 bits\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; + ret = 0; + break; /* TODO: Handle these three commands properly - configurable revision level and proper CPU bits. */ @@ -1593,7 +1464,8 @@ write64_phoenix(void *priv, uint8_t val) kbc_at_queue_add(dev, 0x01); kbc_at_queue_add(dev, 0x29); } - return 0; + ret = 0; + break; case 0xd6: /* Read Version Information */ kbc_at_log("ATkbc: Phoenix - Read Version Information\n"); @@ -1602,7 +1474,8 @@ write64_phoenix(void *priv, uint8_t val) kbc_at_queue_add(dev, 0xac); else kbc_at_queue_add(dev, 0xaa); - return 0; + ret = 0; + break; case 0xd7: /* Read MultiKey model numbers */ kbc_at_log("ATkbc: Phoenix - Read MultiKey model numbers\n"); @@ -1621,71 +1494,63 @@ write64_phoenix(void *priv, uint8_t val) kbc_at_queue_add(dev, 0x88); kbc_at_queue_add(dev, 0xd0); } - return 0; - - default: + ret = 0; break; } - return write64_generic(dev, val); + return ret; } static uint8_t -write64_siemens(void *priv, uint8_t val) +write_cmd_siemens(void *priv, uint8_t val) { atkbc_t *dev = (atkbc_t *) priv; + uint8_t ret = 1; switch (val) { + default: + ret = write_cmd_ami(dev, val); + break; + case 0x92: /*Siemens Award - 92 sent by PCD-2L BIOS*/ kbc_at_log("Siemens Award - 92 sent by PCD-2L BIOS\n"); - return 0; + ret = 0; + break; case 0x94: /*Siemens Award - 94 sent by PCD-2L BIOS*/ kbc_at_log("Siemens Award - 94 sent by PCD-2L BIOS\n"); - return 0; + ret = 0; + break; case 0x9a: /*Siemens Award - 9A sent by PCD-2L BIOS*/ kbc_at_log("Siemens Award - 9A sent by PCD-2L BIOS\n"); - return 0; + ret = 0; + break; case 0x9c: /*Siemens Award - 9C sent by PCD-2L BIOS*/ kbc_at_log("Siemens Award - 9C sent by PCD-2L BIOS\n"); - return 0; + ret = 0; + break; case 0xa9: /*Siemens Award - A9 sent by PCD-2L BIOS*/ kbc_at_log("Siemens Award - A9 sent by PCD-2L BIOS\n"); - return 0; - - default: + ret = 0; break; } - return write64_ami(dev, val); + return ret; } static uint8_t -write60_quadtel(void *priv, UNUSED(uint8_t val)) -{ - const atkbc_t *dev = (atkbc_t *) priv; - - switch (dev->command) { - case 0xcf: /*??? - sent by MegaPC BIOS*/ - kbc_at_log("ATkbc: ??? - sent by MegaPC BIOS\n"); - return 0; - - default: - break; - } - - return 1; -} - -static uint8_t -write64_olivetti(void *priv, uint8_t val) +write_cmd_olivetti(void *priv, uint8_t val) { atkbc_t *dev = (atkbc_t *) priv; + uint8_t ret = 1; switch (val) { + default: + break; + case 0x80: /* Olivetti-specific command */ /* * bit 7: bus expansion board present (M300) / keyboard unlocked (M290) @@ -1696,101 +1561,133 @@ write64_olivetti(void *priv, uint8_t val) */ kbc_delay_to_ob(dev, (0x0c | (is386 ? 0x00 : 0x80)) & 0xdf, 0, 0x00); dev->p1 = ((dev->p1 + 1) & 3) | (dev->p1 & 0xfc); - return 0; - - default: + ret = 0; break; } - return write64_generic(dev, val); + return ret; } static uint8_t -write64_quadtel(void *priv, uint8_t val) +write_cmd_data_quadtel(void *priv, UNUSED(uint8_t val)) +{ + const atkbc_t *dev = (atkbc_t *) priv; + uint8_t ret = 1; + + switch (dev->command) { + default: + break; + + case 0xcf: /*??? - sent by MegaPC BIOS*/ + kbc_at_log("ATkbc: ??? - sent by MegaPC BIOS\n"); + ret = 0; + break; + } + + return ret; +} + +static uint8_t +write_cmd_quadtel(void *priv, uint8_t val) { atkbc_t *dev = (atkbc_t *) priv; + uint8_t ret = 1; switch (val) { + default: + break; + case 0xaf: kbc_at_log("ATkbc: bad KBC command AF\n"); - return 1; + break; case 0xcf: /*??? - sent by MegaPC BIOS*/ kbc_at_log("ATkbc: ??? - sent by MegaPC BIOS\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; - - default: + ret = 0; break; } - return write64_generic(dev, val); + return ret; } static uint8_t -write60_toshiba(void *priv, uint8_t val) +write_cmd_data_toshiba(void *priv, uint8_t val) { const atkbc_t *dev = (atkbc_t *) priv; + uint8_t ret = 1; switch (dev->command) { + default: + break; + case 0xb6: /* T3100e - set color/mono switch */ kbc_at_log("ATkbc: T3100e - set color/mono switch\n"); t3100e_mono_set(val); - return 0; - - default: + ret = 0; break; } - return 1; + return ret; } static uint8_t -write64_toshiba(void *priv, uint8_t val) +write_cmd_toshiba(void *priv, uint8_t val) { atkbc_t *dev = (atkbc_t *) priv; + uint8_t ret = 1; switch (val) { + default: + break; + case 0xaf: kbc_at_log("ATkbc: bad KBC command AF\n"); - return 1; + break; case 0xb0: /* T3100e: Turbo on */ kbc_at_log("ATkbc: T3100e: Turbo on\n"); t3100e_turbo_set(1); - return 0; + ret = 0; + break; case 0xb1: /* T3100e: Turbo off */ kbc_at_log("ATkbc: T3100e: Turbo off\n"); t3100e_turbo_set(0); - return 0; + ret = 0; + break; case 0xb2: /* T3100e: Select external display */ kbc_at_log("ATkbc: T3100e: Select external display\n"); t3100e_display_set(0x00); - return 0; + ret = 0; + break; case 0xb3: /* T3100e: Select internal display */ kbc_at_log("ATkbc: T3100e: Select internal display\n"); t3100e_display_set(0x01); - return 0; + ret = 0; + break; case 0xb4: /* T3100e: Get configuration / status */ kbc_at_log("ATkbc: T3100e: Get configuration / status\n"); kbc_delay_to_ob(dev, t3100e_config_get(), 0, 0x00); - return 0; + ret = 0; + break; case 0xb5: /* T3100e: Get colour / mono byte */ kbc_at_log("ATkbc: T3100e: Get colour / mono byte\n"); kbc_delay_to_ob(dev, t3100e_mono_get(), 0, 0x00); - return 0; + ret = 0; + break; case 0xb6: /* T3100e: Set colour / mono byte */ kbc_at_log("ATkbc: T3100e: Set colour / mono byte\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; - return 0; + ret = 0; + break; /* TODO: Toshiba KBC mode switching. */ case 0xb7: /* T3100e: Emulate PS/2 keyboard */ @@ -1804,7 +1701,8 @@ write64_toshiba(void *priv, uint8_t val) kbc_at_log("ATkbc: T3100e: Emulate AT keyboard\n"); kbc_at_do_poll = kbc_at_poll_at; } - return 0; + ret = 0; + break; case 0xbb: /* T3100e: Read 'Fn' key. Return it for right Ctrl and right Alt; on the real @@ -1816,12 +1714,14 @@ write64_toshiba(void *priv, uint8_t val) kbc_delay_to_ob(dev, 0x04, 0, 0x00); else kbc_delay_to_ob(dev, 0x00, 0, 0x00); - return 0; + ret = 0; + break; case 0xbc: /* T3100e: Reset Fn+Key notification */ kbc_at_log("ATkbc: T3100e: Reset Fn+Key notification\n"); t3100e_notify_set(0x00); - return 0; + ret = 0; + break; case 0xc0: /* Read P1 */ kbc_at_log("ATkbc: read P1\n"); @@ -1830,13 +1730,174 @@ write64_toshiba(void *priv, uint8_t val) * is set by t3100e_mono_set() */ dev->p1 = (t3100e_mono_get() & 1) ? 0xff : 0xbf; kbc_delay_to_ob(dev, dev->p1, 0, 0x00); - return 0; - - default: + ret = 0; break; } - return write64_generic(dev, val); + return ret; +} + +static uint8_t +read_p1(atkbc_t *dev) +{ + uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; + uint8_t ret = 0xff; + uint8_t current_drive; + uint8_t fixed_bits; + + /* + P1 bits: 76543210 + ----------------- + IBM PS/1: xxxxxxxx + IBM PS/2 MCA: xxxxx1xx + Intel AMI Pentium BIOS'es with AMI MegaKey KB-5 keyboard controller: x1x1xxxx + Acer: xxxxx0xx + Packard Bell PB450: xxxxx1xx + P6RP4: xx1xx1xx + Epson Action Tower 2600: xxxx01xx + TriGem Hawk: xxxx11xx + + Machine input based on current code: 11111111 + Everything non-Green: Pull down bit 7 if not PS/2 and keyboard is inhibited. + Pull down bit 6 if primary display is CGA. + Xi8088: Pull down bit 6 if primary display is MDA. + Acer: Pull down bit 6 if primary display is MDA. + Pull down bit 2 always (must be so to enable CMOS Setup). + IBM PS/1: Pull down bit 6 if current floppy drive is 3.5". + Epson Action Tower 2600: Pull down bit 3 always (for Epson logo). + NCR: Pull down bit 5 always (power-on default speed = high). + Pull down bit 3 if there is no FPU. + Pull down bits 1 and 0 always? + Compaq: Pull down bit 6 if Compaq dual-scan display is in use. + Pull down bit 5 if system board DIP switch is ON. + Pull down bit 4 if CPU speed selected is auto. + Pull down bit 3 if CPU speed selected is slow (4 MHz). + Pull down bit 2 if FPU is present. + Pull down bits 1 and 0 always? + + Bit 7: AT KBC only - keyboard inhibited (often physical lock): 0 = yes, 1 = no (also Compaq); + 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"; + 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. + Bit 4: (Which board?): RAM on motherboard: 0 = 512 kB, 1 = 256 kB; + NCR: RAM on motherboard: 0 = unsupported, 1 = 512 kB; + Intel AMI MegaKey KB-5: Must be 1; + IBM PS/1: Ignored; + Compaq: 0 = Auto speed selected, 1 = High speed selected. + Bit 3: TriGem AMIKey: most significant bit of 2-bit OEM ID; + NCR: Coprocessor detect (1 = yes, 0 = no); + Compaq: 0 = Slow (4 MHz), 1 = Fast (8 MHz); + Sometimes configured for clock switching; + Bit 2: TriGem AMIKey: least significant bit of 2-bit OEM ID; + Bit 3, 2: + 1, 1: TriGem logo; + 1, 0: Garbled logo; + 0, 1: Epson logo; + 0, 0: Generic AMI logo. + NCR: Unused; + IBM PS/2: Keyboard power: 0 = no power (fuse error), 1 = OK + (for some reason, www.win.tue.nl has this in reverse); + Compaq: FPU: 0 = 80287, 1 = none; + Sometimes configured for clock switching; + Bit 1: PS/2: Auxiliary device data in; + Compaq: Reserved; + NCR: High/auto speed. + Bit 0: PS/2: Keyboard device data in; + Compaq: Reserved; + NCR: DMA mode. + */ + fixed_bits = 4; + + /* The SMM handlers of Intel AMI Pentium BIOS'es expect bit 6 to be set. */ + if ((kbc_ven == KBC_VEN_AMI) && ((dev->flags & KBC_TYPE_MASK) == KBC_TYPE_GREEN)) + fixed_bits |= 0x40; + + if (!strcmp(machine_get_internal_name(), "dells333sl")) + /* + Dell System 333s/L: + - Bit 5: Stuck in reboot loop if clear. + */ + ret = 0x20 | (video_is_mda() ? 0x40 : 0x00); + else if (kbc_ven == KBC_VEN_IBM_PS1) { + current_drive = fdc_get_current_drive(); + /* (B0 or F0) | (fdd_is_525(current_drive) on bit 6) */ + ret = dev->p1 | fixed_bits | (fdd_is_525(current_drive) ? 0x40 : 0x00); + } else if (kbc_ven == KBC_VEN_NCR) { + /* Switch settings: + - Bit 7: Keyboard disable; + - Bit 6: Display type (0 color, 1 mono); + - Bit 5: Power-on default speed (0 high, 1 low); + - Bit 4: Sense RAM size (0 unsupported, 1 512k on system board); + - Bit 3: Coprocessor detect; + - Bit 2: Unused; + - Bit 1: High/Auto speed; + - Bit 0: DMA mode. + + (B0 or F0) | 0x04 | (display on bit 6) | (fpu on bit 3) + */ + ret = (dev->p1 | fixed_bits | (video_is_mda() ? 0x40 : 0x00) | + (hasfpu ? 0x08 : 0x00)) & 0xdf; + } else if (kbc_ven == KBC_VEN_TRIGEM_AMI) { + /* Switch settings: + - Bit 3, 2: + - 1, 1: TriGem logo; + - 1, 0: Garbled logo; + - 0, 1: Epson logo; + - 0, 0: Generic AMI logo. + */ + if (dev->misc_flags & FLAG_PCI) + fixed_bits |= 8; + + /* (B0 or F0) | (0x04 or 0x0c) */ + ret = dev->p1 | fixed_bits; + } else if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) && + ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_GREEN)) { + if (!strcmp(machine_get_internal_name(), "dell466np")) + /* + Dell 466/NP: + - Bit 2: Keyboard fuse (must be set); + - Bit 4: Password disable jumper (must be clear); + - Bit 5: Manufacturing jumper (must be set). + */ + ret = 0x24; + else if (!strcmp(machine_get_internal_name(), "optiplex_gxl")) + /* + Dell OptiPlex GXL/GXM: + - Bit 3: Password disable jumper (must be clear); + - Bit 4: Keyboard fuse (must be set); + - Bit 5: Manufacturing jumper (must be set). + */ + ret = 0x30; + else if (!strcmp(machine_get_internal_name(), "dellplato") || + !strcmp(machine_get_internal_name(), "dellhannibalp") || + !strcmp(machine_get_internal_name(), "dellxp60")) + /* + Dell Dimension XPS Pxxx & Pxxxa/Mxxxa: + - Bit 3: Password disable jumper (must be clear); + - Bit 4: Clear CMOS jumper (must be set). + */ + ret = 0x10; + else { + /* (B0 or F0) | (0x08 or 0x0c) */ + ret = ((dev->p1 | fixed_bits) & 0xf0) | + (((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0x08 : 0x0c); + + if (!strcmp(machine_get_internal_name(), "alfredo")) + ret &= 0xef; + } + } else if (kbc_ven == KBC_VEN_COMPAQ) + ret = dev->p1 | (hasfpu ? 0x00 : 0x04); + else + /* (B0 or F0) | (0x04 or 0x44) */ + ret = dev->p1 | fixed_bits; + + dev->p1 = ((dev->p1 + 1) & 3) | (dev->p1 & 0xfc); + + return ret; } static void @@ -1856,7 +1917,18 @@ kbc_at_process_cmd(void *priv) /* Clear the keyboard controller queue. */ kbc_at_queue_reset(dev); - switch (dev->ib) { + /* + If we have a vendor-specific handler, run that. Otherwise, or if + that handler fails, attempt to process it as a generic command. + */ + if (dev->write_cmd_ven) + bad = dev->write_cmd_ven(dev, dev->ib); + + if (bad) switch (dev->ib) { + default: + kbc_at_log(bad ? "ATkbc: bad controller command %02X\n" : "", dev->ib); + break; + /* Read data from KBC memory. */ case 0x20 ... 0x3f: kbc_delay_to_ob(dev, dev->mem[dev->ib], 0, 0x00); @@ -1870,18 +1942,70 @@ kbc_at_process_cmd(void *priv) dev->state = STATE_KBC_PARAM; break; + /* TODO: Are these undocmented VL82C113 commands? */ + case 0x80: /* Tulip command */ + kbc_at_log("ATkbc: Tulip command\n"); + kbc_delay_to_ob(dev, 0xff, 0, 0x00); + break; + + case 0x8c: /* Tulip reset command */ + kbc_at_log("ATkbc: Tulip reset command\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + break; + + case 0xa4: /* check if password installed */ + if (dev->misc_flags & FLAG_PS2) { + kbc_at_log("ATkbc: check if password installed\n"); + kbc_delay_to_ob(dev, 0xf1, 0, 0x00); + } + break; + + case 0xa5: /* load security */ + kbc_at_log("ATkbc: load security\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + break; + + case 0xa7: /* disable auxiliary port */ + if (dev->misc_flags & FLAG_PS2) { + kbc_at_log("ATkbc: disable auxiliary port\n"); + set_enable_aux(dev, 0); + } + break; + + case 0xa8: /* Enable auxiliary port */ + if (dev->misc_flags & FLAG_PS2) { + kbc_at_log("ATkbc: enable auxiliary port\n"); + set_enable_aux(dev, 1); + } + break; + + case 0xa9: /* Test auxiliary port */ + kbc_at_log("ATkbc: test auxiliary port\n"); + if (dev->misc_flags & FLAG_PS2) + kbc_delay_to_ob(dev, 0x00, 0, 0x00); /* no error, this is testing the channel 2 interface */ + break; + case 0xaa: /* self-test */ kbc_at_log("ATkbc: self-test\n"); if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) { if (dev->state != STATE_RESET) { kbc_at_log("ATkbc: self-test reinitialization\n"); - /* Yes, the firmware has an OR, but we need to make sure to keep any forcibly lowered bytes lowered. */ - /* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */ + /* + Yes, the firmware has an OR, but we need to make sure + to keep any forcibly lowered bytes lowered. + + TODO: Proper P1 implementation, with OR and AND flags + in the machine table. + */ dev->p1 = dev->p1 & 0xff; write_p2(dev, 0x4b); - picintc(0x1000); - picintc(0x0002); + if (dev->irq[1] != 0xffff) + picintc(1 << dev->irq[1]); + if (dev->irq[0] != 0xffff) + picintc(1 << dev->irq[0]); } dev->status = (dev->status & 0x0f) | 0x60; @@ -1896,11 +2020,17 @@ kbc_at_process_cmd(void *priv) } else { if (dev->state != STATE_RESET) { kbc_at_log("ATkbc: self-test reinitialization\n"); - /* Yes, the firmware has an OR, but we need to make sure to keep any forcibly lowered bytes lowered. */ - /* TODO: Proper P1 implementation, with OR and AND flags in the machine table. */ + /* + Yes, the firmware has an OR, but we need to make sure + to keep any forcibly lowered bytes lowered. + + TODO: Proper P1 implementation, with OR and AND flags + in the machine table. + */ dev->p1 = dev->p1 & 0xff; write_p2(dev, 0xcf); - picintclevel(0x0002, &dev->irq_state); + if (dev->irq[0] != 0xffff) + picintclevel(1 << dev->irq[0], &dev->irq_state); dev->irq_state = 0; } @@ -1934,12 +2064,13 @@ kbc_at_process_cmd(void *priv) break; case 0xac: /* diagnostic dump */ - if (dev->misc_flags & FLAG_PS2) { + if (!(dev->misc_flags & FLAG_PS2)) { kbc_at_log("ATkbc: diagnostic dump\n"); dev->mem[0x30] = (dev->p1 & 0xf0) | 0x80; dev->mem[0x31] = dev->p2; dev->mem[0x32] = 0x00; /* T0 and T1. */ - dev->mem[0x33] = 0x00; /* PSW - Program Status Word - always return 0x00 because we do not emulate this byte. */ + /* PSW - Program Status Word - always return 0x00 because we do not emulate this byte. */ + dev->mem[0x33] = 0x00; /* 20 bytes in high nibble in set 1, low nibble in set 1, set 1 space format = 60 bytes. */ for (uint8_t i = 0; i < 20; i++) { kbc_at_queue_add(dev, cmd_ac_conv[dev->mem[i + 0x20] >> 4]); @@ -1959,10 +2090,33 @@ kbc_at_process_cmd(void *priv) set_enable_kbd(dev, 1); break; - case 0xc7: /* set port1 bits */ - kbc_at_log("ATkbc: Phoenix - set port1 bits\n"); - dev->wantdata = 1; - dev->state = STATE_KBC_PARAM; + /* 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); + break; + + case 0xc0: /* read P1 */ + kbc_at_log("ATkbc: read P1\n"); + kbc_delay_to_ob(dev, read_p1(dev), 0, 0x00); + break; + + case 0xc1: /*Copy bits 0 to 3 of P1 to status bits 4 to 7*/ + if (dev->misc_flags & FLAG_PS2) { + kbc_at_log("ATkbc: copy bits 0 to 3 of P1 to status bits 4 to 7\n"); + dev->status &= 0x0f; + dev->status |= (dev->p1 << 4); + } + break; + + case 0xc2: /*Copy bits 4 to 7 of P1 to status bits 4 to 7*/ + if (dev->misc_flags & FLAG_PS2) { + kbc_at_log("ATkbc: copy bits 4 to 7 of P1 to status bits 4 to 7\n"); + dev->status &= 0x0f; + dev->status |= (dev->p1 & 0xf0); + } break; case 0xca: /* read keyboard mode */ @@ -1970,12 +2124,6 @@ kbc_at_process_cmd(void *priv) kbc_delay_to_ob(dev, dev->ami_flags, 0, 0x00); break; - case 0xcb: /* set keyboard mode */ - kbc_at_log("ATkbc: AMI - set keyboard mode\n"); - dev->wantdata = 1; - dev->state = STATE_KBC_PARAM; - break; - case 0xd0: /* read P2 */ kbc_at_log("ATkbc: read P2\n"); mask = 0xff; @@ -1996,6 +2144,22 @@ kbc_at_process_cmd(void *priv) dev->state = STATE_KBC_PARAM; break; + case 0xd3: /* write auxiliary output buffer */ + if (dev->misc_flags & FLAG_PS2) { + kbc_at_log("ATkbc: write auxiliary output buffer\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + } + break; + + case 0xd4: /* write to auxiliary port */ + if (dev->misc_flags & FLAG_PS2) { + kbc_at_log("ATkbc: write to auxiliary port\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + } + break; + case 0xdd: /* disable A20 address line */ case 0xdf: /* enable A20 address line */ kbc_at_log("ATkbc: %sable A20\n", (dev->ib == 0xdd) ? "dis" : "en"); @@ -2007,18 +2171,10 @@ kbc_at_process_cmd(void *priv) kbc_delay_to_ob(dev, 0x00, 0, 0x00); break; - default: - /* - * Unrecognized controller command. - * - * If we have a vendor-specific handler, run - * that. Otherwise, or if that handler fails, - * log a bad command. - */ - if (dev->write64_ven) - bad = dev->write64_ven(dev, dev->ib); - - kbc_at_log(bad ? "ATkbc: bad controller command %02X\n" : "", dev->ib); + case 0xf0 ... 0xff: /* pulse P2 */ + kbc_at_log("ATkbc: pulse %01X\n", dev->ib & 0x0f); + pulse_output(dev, dev->ib & 0x0f); + break; } /* If the command needs data, remember the command. */ @@ -2029,13 +2185,44 @@ kbc_at_process_cmd(void *priv) dev->wantdata = 0; dev->state = STATE_MAIN_IBF; - switch (dev->command) { + /* + Run the vendor-specific handler if we have one. Otherwise, or if it + returns an error, log a bad controller command. + */ + if (dev->write_cmd_data_ven) + bad = dev->write_cmd_data_ven(dev, dev->ib); + + if (bad) switch (dev->command) { + default: + kbc_at_log("ATkbc: bad controller command %02x data %02x\n", dev->command, dev->ib); + break; + case 0x60 ... 0x7f: dev->mem[(dev->command & 0x1f) + 0x20] = dev->ib; if (dev->command == 0x60) write_cmd(dev, dev->ib); break; + case 0x8c: /* Tulip reset command */ + kbc_at_log("ATkbc: Tulip rset command\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(); + break; + case 0xa5: /* load security */ if (dev->misc_flags & FLAG_PS2) { kbc_at_log("ATkbc: load security (%02X)\n", dev->ib); @@ -2047,11 +2234,6 @@ kbc_at_process_cmd(void *priv) } break; - case 0xc7: /* set port1 bits */ - kbc_at_log("ATkbc: Phoenix - set port1 bits\n"); - dev->p1 |= dev->ib; - break; - case 0xd1: /* write P2 */ kbc_at_log("ATkbc: write P2\n"); /* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no), @@ -2094,26 +2276,12 @@ kbc_at_process_cmd(void *priv) kbc_delay_to_ob(dev, 0xfe, 2, 0x40); } break; - - default: - /* - * Run the vendor-specific handler - * if we have one. Otherwise, or if - * it returns an error, log a bad - * controller command. - */ - if (dev->write60_ven) - bad = dev->write60_ven(dev, dev->ib); - - if (bad) { - kbc_at_log("ATkbc: bad controller command %02x data %02x\n", dev->command, dev->ib); - } } } } static void -kbc_at_write(uint16_t port, uint8_t val, void *priv) +kbc_at_port_1_write(uint16_t port, uint8_t val, void *priv) { atkbc_t *dev = (atkbc_t *) priv; uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; @@ -2121,46 +2289,89 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv) kbc_at_log("ATkbc: [%04X:%08X] write(%04X) = %02X\n", CS, cpu_state.pc, port, val); - switch (port) { - case 0x60: - dev->status &= ~STAT_CD; - if (fast_a20 && dev->wantdata && (dev->command == 0xd1)) { - kbc_at_log("ATkbc: write P2\n"); + dev->status &= ~STAT_CD; - /* Fast A20 - ignore all other bits. */ - write_p2_fast_a20(dev, (dev->p2 & 0xfd) | (val & 0x02)); + if (fast_a20 && dev->wantdata && (dev->command == 0xd1)) { + kbc_at_log("ATkbc: write P2\n"); - dev->wantdata = 0; - dev->state = STATE_MAIN_IBF; - return; - } - break; + /* Fast A20 - ignore all other bits. */ + write_p2_fast_a20(dev, (dev->p2 & 0xfd) | (val & 0x02)); - case 0x64: - dev->status |= STAT_CD; - if (fast_a20 && (val == 0xd1)) { - kbc_at_log("ATkbc: write P2\n"); - dev->wantdata = 1; - dev->state = STATE_KBC_PARAM; - dev->command = 0xd1; - return; - } else if (fast_reset && ((val & 0xf0) == 0xf0)) { - pulse_output(dev, val & 0x0f); + dev->wantdata = 0; + dev->state = STATE_MAIN_IBF; - dev->state = STATE_MAIN_IBF; - return; - } else if (val == 0xae) { - /* Fast track it because of the LG MultiNet. */ - kbc_at_log("ATkbc: enable keyboard\n"); - set_enable_kbd(dev, 1); + /* + Explicitly clear IBF so that any preceding + command is not executed. + */ + dev->status &= ~STAT_IFULL; + return; + } - dev->state = STATE_MAIN_IBF; - return; - } - break; + dev->ib = val; + dev->status |= STAT_IFULL; +} - default: - break; +static void +kbc_at_port_2_write(uint16_t port, uint8_t val, void *priv) +{ + atkbc_t *dev = (atkbc_t *) priv; + uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; + uint8_t fast_a20 = (kbc_ven != KBC_VEN_SIEMENS); + + kbc_at_log("ATkbc: [%04X:%08X] write(%04X) = %02X\n", CS, cpu_state.pc, port, val); + + dev->status |= STAT_CD; + + if (fast_a20 && (val == 0xd1)) { + kbc_at_log("ATkbc: write P2\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + dev->command = 0xd1; + + /* + Explicitly clear IBF so that any preceding + command is not executed. + */ + dev->status &= ~STAT_IFULL; + return; + } else if (fast_reset && ((val & 0xf0) == 0xf0)) { + pulse_output(dev, val & 0x0f); + + dev->state = STATE_MAIN_IBF; + + /* + Explicitly clear IBF so that any preceding + command is not executed. + */ + dev->status &= ~STAT_IFULL; + return; + } else if (val == 0xad) { + /* Fast track it because of the Bochs BIOS. */ + kbc_at_log("ATkbc: disable keyboard\n"); + set_enable_kbd(dev, 0); + + dev->state = STATE_MAIN_IBF; + + /* + Explicitly clear IBF so that any preceding + command is not executed. + */ + dev->status &= ~STAT_IFULL; + return; + } else if (val == 0xae) { + /* Fast track it because of the LG MultiNet. */ + kbc_at_log("ATkbc: enable keyboard\n"); + set_enable_kbd(dev, 1); + + dev->state = STATE_MAIN_IBF; + + /* + Explicitly clear IBF so that any preceding + command is not executed. + */ + dev->status &= ~STAT_IFULL; + return; } dev->ib = val; @@ -2168,7 +2379,7 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv) } static uint8_t -kbc_at_read(uint16_t port, void *priv) +kbc_at_port_1_read(uint16_t port, void *priv) { atkbc_t *dev = (atkbc_t *) priv; uint8_t ret = 0xff; @@ -2176,26 +2387,32 @@ kbc_at_read(uint16_t port, void *priv) if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) cycles -= ISA_CYCLES(8); - switch (port) { - case 0x60: - ret = dev->ob; - dev->status &= ~STAT_OFULL; - /* 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)) - picintclevel(1 << 1, &dev->irq_state); - if ((strstr(machine_get_internal_name(), "pb41") != NULL) && (cpu_override_dynarec == 1)) - cpu_override_dynarec = 0; - break; + ret = dev->ob; + dev->status &= ~STAT_OFULL; + /* + 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) && (dev->irq[0] != 0xffff)) + picintclevel(1 << dev->irq[0], &dev->irq_state); + if ((strstr(machine_get_internal_name(), "pb41") != NULL) && (cpu_override_dynarec == 1)) + cpu_override_dynarec = 0; - case 0x64: - ret = dev->status; - break; + kbc_at_log("ATkbc: [%04X:%08X] read (%04X) = %02X\n", CS, cpu_state.pc, port, ret); - default: - kbc_at_log("ATkbc: read(%04x) invalid!\n",port); - break; - } + return ret; +} + +static uint8_t +kbc_at_port_2_read(uint16_t port, void *priv) +{ + atkbc_t *dev = (atkbc_t *) priv; + uint8_t ret = 0xff; + + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) + cycles -= ISA_CYCLES(8); + + ret = dev->status; kbc_at_log("ATkbc: [%04X:%08X] read (%04X) = %02X\n", CS, cpu_state.pc, port, ret); @@ -2234,11 +2451,14 @@ 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; - picintc(0x1000); - picintc(0x0002); + if (dev->irq[1] != 0xffff) + picintc(1 << dev->irq[1]); + if (dev->irq[0] != 0xffff) + picintc(1 << dev->irq[0]); } else { kbc_at_do_poll = kbc_at_poll_at; - picintclevel(0x0002, &dev->irq_state); + if (dev->irq[0] != 0xffff) + picintclevel(1 << dev->irq[0], &dev->irq_state); dev->irq_state = 0; } @@ -2281,19 +2501,44 @@ kbc_at_close(void *priv) } void -kbc_at_handler(int set, void *priv) +kbc_at_port_handler(int num, int set, uint16_t port, void *priv) { - if (kbc_handler_set) { - io_removehandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); - io_removehandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); + atkbc_t *dev = (atkbc_t *) priv; + + if (dev->handler_enable[num] && (dev->base_addr[num] != 0x0000)) + io_removehandler(dev->base_addr[num], 1, + dev->handlers[num].read, NULL, NULL, + dev->handlers[num].write, NULL, NULL, priv); + + dev->handler_enable[num] = set; + dev->base_addr[num] = port; + + if (dev->handler_enable[num] && (dev->base_addr[num] != 0x0000)) + io_sethandler(dev->base_addr[num], 1, + dev->handlers[num].read, NULL, NULL, + dev->handlers[num].write, NULL, NULL, priv); +} + +void +kbc_at_handler(int set, uint16_t port, void *priv) +{ + kbc_at_port_handler(0, set, port, priv); + kbc_at_port_handler(1, set, port + 0x0004, priv); +} + +void +kbc_at_set_irq(int num, uint16_t irq, void *priv) +{ + atkbc_t *dev = (atkbc_t *) priv; + + if (dev->irq[num] != 0xffff) { + if ((num == 0) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_PS2_1)) + picintclevel(1 << dev->irq[num], &dev->irq_state); + else + picintc(1 << dev->irq[num]); } - kbc_handler_set = set; - - if (kbc_handler_set) { - io_sethandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); - io_sethandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv); - } + dev->irq[num] = irq; } static void * @@ -2314,52 +2559,51 @@ kbc_at_init(const device_t *info) if (info->flags & DEVICE_PCI) dev->misc_flags |= FLAG_PCI; - kbc_handler_set = 0; - kbc_at_handler(1, dev); + dev->handlers[0].read = kbc_at_port_1_read; + dev->handlers[0].write = kbc_at_port_1_write; + dev->handlers[1].read = kbc_at_port_2_read; + dev->handlers[1].write = kbc_at_port_2_write; + + dev->irq[0] = 1; + dev->irq[1] = 12; 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; + dev->write_cmd_data_ven = NULL; + dev->write_cmd_ven = NULL; kbc_ami_revision = '8'; kbc_award_revision = 0x42; switch (dev->flags & KBC_VEN_MASK) { + default: + break; + case KBC_VEN_SIEMENS: kbc_ami_revision = '8'; kbc_award_revision = 0x42; - dev->write60_ven = write60_ami; - dev->write64_ven = write64_siemens; - break; - - case KBC_VEN_ACER: - case KBC_VEN_GENERIC: - case KBC_VEN_NCR: - case KBC_VEN_IBM_PS1: - case KBC_VEN_IBM: - case KBC_VEN_COMPAQ: - dev->write64_ven = write64_generic; + dev->write_cmd_data_ven = write_cmd_data_ami; + dev->write_cmd_ven = write_cmd_siemens; break; case KBC_VEN_OLIVETTI: - dev->write64_ven = write64_olivetti; + dev->write_cmd_ven = write_cmd_olivetti; break; case KBC_VEN_ALI: kbc_ami_revision = 'F'; kbc_award_revision = 0x43; - dev->write60_ven = write60_ami; - dev->write64_ven = write64_ami; + dev->write_cmd_data_ven = write_cmd_data_ami; + dev->write_cmd_ven = write_cmd_ami; break; case KBC_VEN_TRIGEM_AMI: kbc_ami_revision = 'Z'; - dev->write60_ven = write60_ami; - dev->write64_ven = write64_ami; + dev->write_cmd_data_ven = write_cmd_data_ami; + dev->write_cmd_ven = write_cmd_ami; break; case KBC_VEN_AMI: @@ -2382,26 +2626,23 @@ kbc_at_init(const device_t *info) else kbc_ami_revision = 'F'; - dev->write60_ven = write60_ami; - dev->write64_ven = write64_ami; + dev->write_cmd_data_ven = write_cmd_data_ami; + dev->write_cmd_ven = write_cmd_ami; break; case KBC_VEN_PHOENIX: - dev->write60_ven = write60_phoenix; - dev->write64_ven = write64_phoenix; + dev->write_cmd_data_ven = write_cmd_data_phoenix; + dev->write_cmd_ven = write_cmd_phoenix; break; case KBC_VEN_QUADTEL: - dev->write60_ven = write60_quadtel; - dev->write64_ven = write64_quadtel; + dev->write_cmd_data_ven = write_cmd_data_quadtel; + dev->write_cmd_ven = write_cmd_quadtel; break; case KBC_VEN_TOSHIBA: - dev->write60_ven = write60_toshiba; - dev->write64_ven = write64_toshiba; - break; - - default: + dev->write_cmd_data_ven = write_cmd_data_toshiba; + dev->write_cmd_ven = write_cmd_toshiba; break; } @@ -2420,16 +2661,26 @@ kbc_at_init(const device_t *info) dev->ports[1] = kbc_at_ports[1]; /* The actual keyboard. */ - device_add(&keyboard_at_generic_device); + if (keyboard_type == KEYBOARD_TYPE_INTERNAL) { + if (machine_has_flags(machine, MACHINE_KEYBOARD_JIS)) + device_add(((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? &keyboard_ps55_device : + &keyboard_ax_device); + else + device_add_params(&keyboard_at_generic_device, (void *) (uintptr_t) + (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? FLAG_PS2_KBD : 0x00)); + } else + keyboard_add_device(); fast_reset = 0x00; + kbc_at_handler(1, 0x0060, dev); + return dev; } -const device_t keyboard_at_device = { - .name = "PC/AT Keyboard", - .internal_name = "keyboard_at", +const device_t kbc_at_device = { + .name = "PC/AT Keyboard Controller", + .internal_name = "kbc_at", .flags = DEVICE_KBC, .local = KBC_TYPE_ISA | KBC_VEN_GENERIC, .init = kbc_at_init, @@ -2441,9 +2692,9 @@ const device_t keyboard_at_device = { .config = NULL }; -const device_t keyboard_at_siemens_device = { - .name = "PC/AT Keyboard", - .internal_name = "keyboard_at", +const device_t kbc_at_siemens_device = { + .name = "PC/AT Keyboard Controller", + .internal_name = "kbc_at", .flags = DEVICE_KBC, .local = KBC_TYPE_ISA | KBC_VEN_SIEMENS, .init = kbc_at_init, @@ -2455,9 +2706,9 @@ const device_t keyboard_at_siemens_device = { .config = NULL }; -const device_t keyboard_at_ami_device = { - .name = "PC/AT Keyboard (AMI)", - .internal_name = "keyboard_at_ami", +const device_t kbc_at_ami_device = { + .name = "PC/AT Keyboard Controller (AMI)", + .internal_name = "kbc_at_ami", .flags = DEVICE_KBC, .local = KBC_TYPE_ISA | KBC_VEN_AMI, .init = kbc_at_init, @@ -2469,9 +2720,9 @@ const device_t keyboard_at_ami_device = { .config = NULL }; -const device_t keyboard_at_tg_ami_device = { - .name = "PC/AT Keyboard (TriGem AMI)", - .internal_name = "keyboard_at_tg_ami", +const device_t kbc_at_tg_ami_device = { + .name = "PC/AT Keyboard Controller (TriGem AMI)", + .internal_name = "kbc_at_tg_ami", .flags = DEVICE_KBC, .local = KBC_TYPE_ISA | KBC_VEN_TRIGEM_AMI, .init = kbc_at_init, @@ -2483,9 +2734,9 @@ const device_t keyboard_at_tg_ami_device = { .config = NULL }; -const device_t keyboard_at_toshiba_device = { - .name = "PC/AT Keyboard (Toshiba)", - .internal_name = "keyboard_at_toshiba", +const device_t kbc_at_toshiba_device = { + .name = "PC/AT Keyboard Controller (Toshiba)", + .internal_name = "kbc_at_toshiba", .flags = DEVICE_KBC, .local = KBC_TYPE_ISA | KBC_VEN_TOSHIBA, .init = kbc_at_init, @@ -2497,9 +2748,9 @@ const device_t keyboard_at_toshiba_device = { .config = NULL }; -const device_t keyboard_at_olivetti_device = { - .name = "PC/AT Keyboard (Olivetti)", - .internal_name = "keyboard_at_olivetti", +const device_t kbc_at_olivetti_device = { + .name = "PC/AT Keyboard Controller (Olivetti)", + .internal_name = "kbc_at_olivetti", .flags = DEVICE_KBC, .local = KBC_TYPE_ISA | KBC_VEN_OLIVETTI, .init = kbc_at_init, @@ -2511,9 +2762,9 @@ const device_t keyboard_at_olivetti_device = { .config = NULL }; -const device_t keyboard_at_ncr_device = { - .name = "PC/AT Keyboard (NCR)", - .internal_name = "keyboard_at_ncr", +const device_t kbc_at_ncr_device = { + .name = "PC/AT Keyboard Controller (NCR)", + .internal_name = "kbc_at_ncr", .flags = DEVICE_KBC, .local = KBC_TYPE_ISA | KBC_VEN_NCR, .init = kbc_at_init, @@ -2525,9 +2776,9 @@ const device_t keyboard_at_ncr_device = { .config = NULL }; -const device_t keyboard_at_compaq_device = { - .name = "PC/AT Keyboard (Compaq)", - .internal_name = "keyboard_at_compaq", +const device_t kbc_at_compaq_device = { + .name = "PC/AT Keyboard Controller (Compaq)", + .internal_name = "kbc_at_compaq", .flags = DEVICE_KBC, .local = KBC_TYPE_ISA | KBC_VEN_COMPAQ, .init = kbc_at_init, @@ -2539,9 +2790,9 @@ const device_t keyboard_at_compaq_device = { .config = NULL }; -const device_t keyboard_at_phoenix_device = { - .name = "PC/AT Keyboard (Phoenix)", - .internal_name = "keyboard_at_phoenix", +const device_t kbc_at_phoenix_device = { + .name = "PC/AT Keyboard Controller (Phoenix)", + .internal_name = "kbc_at_phoenix", .flags = DEVICE_KBC, .local = KBC_TYPE_ISA | KBC_VEN_PHOENIX, .init = kbc_at_init, @@ -2553,9 +2804,9 @@ const device_t keyboard_at_phoenix_device = { .config = NULL }; -const device_t keyboard_ps2_device = { - .name = "PS/2 Keyboard", - .internal_name = "keyboard_ps2", +const device_t kbc_ps2_device = { + .name = "PS/2 Keyboard Controller", + .internal_name = "kbc_ps2", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, .init = kbc_at_init, @@ -2567,9 +2818,9 @@ const device_t keyboard_ps2_device = { .config = NULL }; -const device_t keyboard_ps2_ps1_device = { - .name = "PS/2 Keyboard (IBM PS/1)", - .internal_name = "keyboard_ps2_ps1", +const device_t kbc_ps2_ps1_device = { + .name = "PS/2 Keyboard Controller (IBM PS/1)", + .internal_name = "kbc_ps2_ps1", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_1 | KBC_VEN_IBM_PS1, .init = kbc_at_init, @@ -2581,9 +2832,9 @@ const device_t keyboard_ps2_ps1_device = { .config = NULL }; -const device_t keyboard_ps2_ps1_pci_device = { - .name = "PS/2 Keyboard (IBM PS/1)", - .internal_name = "keyboard_ps2_ps1_pci", +const device_t kbc_ps2_ps1_pci_device = { + .name = "PS/2 Keyboard Controller (IBM PS/1)", + .internal_name = "kbc_ps2_ps1_pci", .flags = DEVICE_KBC | DEVICE_PCI, .local = KBC_TYPE_PS2_1 | KBC_VEN_IBM_PS1, .init = kbc_at_init, @@ -2595,9 +2846,9 @@ const device_t keyboard_ps2_ps1_pci_device = { .config = NULL }; -const device_t keyboard_ps2_xi8088_device = { - .name = "PS/2 Keyboard (Xi8088)", - .internal_name = "keyboard_ps2_xi8088", +const device_t kbc_ps2_xi8088_device = { + .name = "PS/2 Keyboard Controller (Xi8088)", + .internal_name = "kbc_ps2_xi8088", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, .init = kbc_at_init, @@ -2609,9 +2860,9 @@ const device_t keyboard_ps2_xi8088_device = { .config = NULL }; -const device_t keyboard_ps2_ami_device = { - .name = "PS/2 Keyboard (AMI)", - .internal_name = "keyboard_ps2_ami", +const device_t kbc_ps2_ami_device = { + .name = "PS/2 Keyboard Controller (AMI)", + .internal_name = "kbc_ps2_ami", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_1 | KBC_VEN_AMI, .init = kbc_at_init, @@ -2623,9 +2874,9 @@ const device_t keyboard_ps2_ami_device = { .config = NULL }; -const device_t keyboard_ps2_compaq_device = { - .name = "PS/2 Keyboard (Compaq)", - .internal_name = "keyboard_at_compaq", +const device_t kbc_ps2_compaq_device = { + .name = "PS/2 Keyboard Controller (Compaq)", + .internal_name = "kbc_at_compaq", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_1 | KBC_VEN_COMPAQ, .init = kbc_at_init, @@ -2637,9 +2888,9 @@ const device_t keyboard_ps2_compaq_device = { .config = NULL }; -const device_t keyboard_ps2_holtek_device = { - .name = "PS/2 Keyboard (Holtek)", - .internal_name = "keyboard_ps2_holtek", +const device_t kbc_ps2_holtek_device = { + .name = "PS/2 Keyboard Controller (Holtek)", + .internal_name = "kbc_ps2_holtek", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_1 | KBC_VEN_AMI | KBC_FLAG_IS_ASIC, .init = kbc_at_init, @@ -2651,9 +2902,9 @@ const device_t keyboard_ps2_holtek_device = { .config = NULL }; -const device_t keyboard_ps2_phoenix_device = { - .name = "PS/2 Keyboard (Phoenix)", - .internal_name = "keyboard_ps2_phoenix", +const device_t kbc_ps2_phoenix_device = { + .name = "PS/2 Keyboard Controller (Phoenix)", + .internal_name = "kbc_ps2_phoenix", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_1 | KBC_VEN_PHOENIX, .init = kbc_at_init, @@ -2665,9 +2916,9 @@ const device_t keyboard_ps2_phoenix_device = { .config = NULL }; -const device_t keyboard_ps2_tg_ami_device = { - .name = "PS/2 Keyboard (TriGem AMI)", - .internal_name = "keyboard_ps2_tg_ami", +const device_t kbc_ps2_tg_ami_device = { + .name = "PS/2 Keyboard Controller (TriGem AMI)", + .internal_name = "kbc_ps2_tg_ami", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_1 | KBC_VEN_TRIGEM_AMI, .init = kbc_at_init, @@ -2679,9 +2930,9 @@ const device_t keyboard_ps2_tg_ami_device = { .config = NULL }; -const device_t keyboard_ps2_mca_1_device = { - .name = "PS/2 Keyboard (IBM PS/2 MCA Type 1)", - .internal_name = "keyboard_ps2_mca_1", +const device_t kbc_ps2_mca_1_device = { + .name = "PS/2 Keyboard Controller (IBM PS/2 MCA Type 1)", + .internal_name = "kbc_ps2_mca_1", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_1 | KBC_VEN_IBM, .init = kbc_at_init, @@ -2693,9 +2944,9 @@ const device_t keyboard_ps2_mca_1_device = { .config = NULL }; -const device_t keyboard_ps2_mca_2_device = { - .name = "PS/2 Keyboard (IBM PS/2 MCA Type 2)", - .internal_name = "keyboard_ps2_mca_2", +const device_t kbc_ps2_mca_2_device = { + .name = "PS/2 Keyboard Controller (IBM PS/2 MCA Type 2)", + .internal_name = "kbc_ps2_mca_2", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_2 | KBC_VEN_IBM, .init = kbc_at_init, @@ -2707,9 +2958,9 @@ const device_t keyboard_ps2_mca_2_device = { .config = NULL }; -const device_t keyboard_ps2_quadtel_device = { - .name = "PS/2 Keyboard (Quadtel/MegaPC)", - .internal_name = "keyboard_ps2_quadtel", +const device_t kbc_ps2_quadtel_device = { + .name = "PS/2 Keyboard Controller (Quadtel/MegaPC)", + .internal_name = "kbc_ps2_quadtel", .flags = DEVICE_KBC, .local = KBC_TYPE_PS2_1 | KBC_VEN_QUADTEL, .init = kbc_at_init, @@ -2721,9 +2972,9 @@ const device_t keyboard_ps2_quadtel_device = { .config = NULL }; -const device_t keyboard_ps2_pci_device = { - .name = "PS/2 Keyboard", - .internal_name = "keyboard_ps2_pci", +const device_t kbc_ps2_pci_device = { + .name = "PS/2 Keyboard Controller (PCI)", + .internal_name = "kbc_ps2_pci", .flags = DEVICE_KBC | DEVICE_PCI, .local = KBC_TYPE_PS2_1 | KBC_VEN_GENERIC, .init = kbc_at_init, @@ -2735,9 +2986,9 @@ const device_t keyboard_ps2_pci_device = { .config = NULL }; -const device_t keyboard_ps2_ami_pci_device = { - .name = "PS/2 Keyboard (AMI)", - .internal_name = "keyboard_ps2_ami_pci", +const device_t kbc_ps2_ami_pci_device = { + .name = "PS/2 Keyboard Controller (PCI) (AMI)", + .internal_name = "kbc_ps2_ami_pci", .flags = DEVICE_KBC | DEVICE_PCI, .local = KBC_TYPE_PS2_1 | KBC_VEN_AMI, .init = kbc_at_init, @@ -2749,9 +3000,9 @@ const device_t keyboard_ps2_ami_pci_device = { .config = NULL }; -const device_t keyboard_ps2_ali_pci_device = { - .name = "PS/2 Keyboard (ALi M5123/M1543C)", - .internal_name = "keyboard_ps2_ali_pci", +const device_t kbc_ps2_ali_pci_device = { + .name = "PS/2 Keyboard Controller (PCI) (ALi M5123/M1543C)", + .internal_name = "kbc_ps2_ali_pci", .flags = DEVICE_KBC | DEVICE_PCI, .local = KBC_TYPE_PS2_1 | KBC_VEN_ALI, .init = kbc_at_init, @@ -2763,9 +3014,9 @@ const device_t keyboard_ps2_ali_pci_device = { .config = NULL }; -const device_t keyboard_ps2_intel_ami_pci_device = { - .name = "PS/2 Keyboard (AMI)", - .internal_name = "keyboard_ps2_intel_ami_pci", +const device_t kbc_ps2_intel_ami_pci_device = { + .name = "PS/2 Keyboard Controller (PCI) (AMI)", + .internal_name = "kbc_ps2_intel_ami_pci", .flags = DEVICE_KBC | DEVICE_PCI, .local = KBC_TYPE_GREEN | KBC_VEN_AMI, .init = kbc_at_init, @@ -2777,9 +3028,9 @@ const device_t keyboard_ps2_intel_ami_pci_device = { .config = NULL }; -const device_t keyboard_ps2_tg_ami_pci_device = { - .name = "PS/2 Keyboard (TriGem AMI)", - .internal_name = "keyboard_ps2_tg_ami_pci", +const device_t kbc_ps2_tg_ami_pci_device = { + .name = "PS/2 Keyboard Controller (PCI) (TriGem AMI)", + .internal_name = "kbc_ps2_tg_ami_pci", .flags = DEVICE_KBC | DEVICE_PCI, .local = KBC_TYPE_PS2_1 | KBC_VEN_TRIGEM_AMI, .init = kbc_at_init, @@ -2791,9 +3042,9 @@ const device_t keyboard_ps2_tg_ami_pci_device = { .config = NULL }; -const device_t keyboard_ps2_acer_pci_device = { - .name = "PS/2 Keyboard (Acer 90M002A)", - .internal_name = "keyboard_ps2_acer_pci", +const device_t kbc_ps2_acer_pci_device = { + .name = "PS/2 Keyboard Controller (PCI) (Acer 90M002A)", + .internal_name = "kbc_ps2_acer_pci", .flags = DEVICE_KBC | DEVICE_PCI, .local = KBC_TYPE_PS2_1 | KBC_VEN_ACER, .init = kbc_at_init, @@ -2805,9 +3056,9 @@ const device_t keyboard_ps2_acer_pci_device = { .config = NULL }; -const device_t keyboard_ps2_phoenix_pci_device = { - .name = "PS/2 Keyboard (Phoenix)", - .internal_name = "keyboard_ps2_phoenix_pci", +const device_t kbc_ps2_phoenix_pci_device = { + .name = "PS/2 Keyboard Controller (PCI) (Phoenix)", + .internal_name = "kbc_ps2_phoenix_pci", .flags = DEVICE_KBC | DEVICE_PCI, .local = KBC_TYPE_PS2_1 | KBC_VEN_PHOENIX, .init = kbc_at_init, diff --git a/src/device/kbc_at_dev.c b/src/device/kbc_at_dev.c index c1041e6e1..81ab0aee9 100644 --- a/src/device/kbc_at_dev.c +++ b/src/device/kbc_at_dev.c @@ -8,11 +8,9 @@ * * AT / PS/2 attached device emulation. * - * - * * Authors: Miran Grca, * - * Copyright 2023 Miran Grca. + * Copyright 2023-2025 Miran Grca. */ #include #include @@ -22,23 +20,9 @@ #define HAVE_STDARG_H #include #include <86box/86box.h> -#include "cpu.h" -#include <86box/timer.h> -#include <86box/io.h> -#include <86box/pic.h> -#include <86box/pit.h> -#include <86box/ppi.h> -#include <86box/mem.h> #include <86box/device.h> -#include <86box/machine.h> -#include <86box/m_at_t3100e.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/sound.h> -#include <86box/snd_speaker.h> -#include <86box/video.h> -#include <86box/keyboard.h> #include <86box/plat_fallthrough.h> +#include <86box/keyboard.h> #ifdef ENABLE_KBC_AT_DEV_LOG int kbc_at_dev_do_log = ENABLE_KBC_AT_DEV_LOG; @@ -58,7 +42,7 @@ kbc_at_dev_log(const char *fmt, ...) # define kbc_at_dev_log(fmt, ...) #endif -static void +void kbc_at_dev_queue_reset(atkbc_dev_t *dev, uint8_t reset_main) { if (reset_main) { @@ -95,10 +79,6 @@ kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main) dev->cmd_queue[dev->cmd_queue_end] = val; dev->cmd_queue_end = (dev->cmd_queue_end + 1) & 0xf; } - - /* TODO: This should be done on actual send to host. */ - if (val != 0xfe) - dev->last_scan_code = val; } static void @@ -123,6 +103,8 @@ kbc_at_dev_poll(void *priv) (dev->queue_start != dev->queue_end)) { kbc_at_dev_log("%s: %02X (DATA) on channel 1\n", dev->name, dev->queue[dev->queue_start]); dev->port->out_new = dev->queue[dev->queue_start]; + if (dev->port->out_new != 0xfe) + dev->last_scan_code = dev->port->out_new; dev->queue_start = (dev->queue_start + 1) & dev->fifo_mask; } if (dev->ignore || !(*dev->scan) || dev->port->wantcmd) @@ -143,6 +125,8 @@ kbc_at_dev_poll(void *priv) if ((dev->port->out_new == -1) && (dev->cmd_queue_start != dev->cmd_queue_end)) { kbc_at_dev_log("%s: %02X (CMD ) on channel 1\n", dev->name, dev->cmd_queue[dev->cmd_queue_start]); dev->port->out_new = dev->cmd_queue[dev->cmd_queue_start]; + if (dev->port->out_new != 0xfe) + dev->last_scan_code = dev->port->out_new; dev->cmd_queue_start = (dev->cmd_queue_start + 1) & 0xf; } if (dev->cmd_queue_start == dev->cmd_queue_end) @@ -166,6 +150,8 @@ kbc_at_dev_poll(void *priv) if ((dev->port->out_new == -1) && (dev->cmd_queue_start != dev->cmd_queue_end)) { kbc_at_dev_log("%s: %02X (CMD ) on channel 1\n", dev->name, dev->cmd_queue[dev->cmd_queue_start]); dev->port->out_new = dev->cmd_queue[dev->cmd_queue_start]; + if (dev->port->out_new != 0xfe) + dev->last_scan_code = dev->port->out_new; dev->cmd_queue_start = (dev->cmd_queue_start + 1) & 0xf; } if (dev->cmd_queue_start == dev->cmd_queue_end) diff --git a/src/device/kbc_xt.c b/src/device/kbc_xt.c new file mode 100644 index 000000000..176f1df43 --- /dev/null +++ b/src/device/kbc_xt.c @@ -0,0 +1,903 @@ +/* + * 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 XT-style keyboard. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * EngiNerd, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van kempen. + * Copyright 2020 EngiNerd. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include +#include <86box/86box.h> +#include <86box/device.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/fdd.h> +#include <86box/machine.h> +#include <86box/m_xt_t1000.h> +#include <86box/cassette.h> +#include <86box/io.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/ppi.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/sound.h> +#include <86box/snd_speaker.h> +#include <86box/video.h> +#include <86box/keyboard.h> + +#define STAT_PARITY 0x80 +#define STAT_RTIMEOUT 0x40 +#define STAT_TTIMEOUT 0x20 +#define STAT_LOCK 0x10 +#define STAT_CD 0x08 +#define STAT_SYSFLAG 0x04 +#define STAT_IFULL 0x02 +#define STAT_OFULL 0x01 + +/* 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_FE2010, + KBD_TYPE_XTCLONE +}; + +typedef struct xtkbd_t { + int want_irq; + int blocked; + int tandy; + + uint8_t pa; + uint8_t pb; + uint8_t pd; + uint8_t cfg; + uint8_t clock; + uint8_t key_waiting; + uint8_t type; + uint8_t pravetz_flags; + uint8_t cpu_speed; + + pc_timer_t send_delay_timer; +} xtkbd_t; + +static uint8_t key_queue[16]; +static int key_queue_start = 0; +static int key_queue_end = 0; +static int is_tandy = 0; +static int is_t1x00 = 0; +static int is_amstrad = 0; + +#ifdef ENABLE_KEYBOARD_XT_LOG +int keyboard_xt_do_log = ENABLE_KEYBOARD_XT_LOG; + +static void +kbd_log(const char *fmt, ...) +{ + va_list ap; + + if (keyboard_xt_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define kbd_log(fmt, ...) +#endif + +static uint8_t +get_fdd_switch_settings(void) +{ + + uint8_t fdd_count = 0; + + for (uint8_t i = 0; i < FDD_NUM; i++) { + if (fdd_get_flags(i)) + fdd_count++; + } + + if (!fdd_count) + return 0x00; + else + return ((fdd_count - 1) << 6) | 0x01; +} + +static uint8_t +get_videomode_switch_settings(void) +{ + + if (video_is_mda()) + return 0x30; + else if (video_is_cga()) + return 0x20; /* 0x10 would be 40x25 */ + else + return 0x00; +} + +static void +kbd_poll(void *priv) +{ + xtkbd_t *kbd = (xtkbd_t *) priv; + + timer_advance_u64(&kbd->send_delay_timer, 1000 * TIMER_USEC); + + if (!(kbd->pb & 0x40) && (kbd->type != KBD_TYPE_TANDY)) + return; + + if (kbd->want_irq) { + kbd->want_irq = 0; + kbd->pa = kbd->key_waiting; + kbd->blocked = 1; + picint(2); +#ifdef ENABLE_KEYBOARD_XT_LOG + kbd_log("XTkbd: kbd_poll(): keyboard_xt : take IRQ\n"); +#endif + } + + if ((key_queue_start != key_queue_end) && !kbd->blocked) { + kbd->key_waiting = key_queue[key_queue_start]; + kbd_log("XTkbd: reading %02X from the key queue at %i\n", + kbd->key_waiting, key_queue_start); + key_queue_start = (key_queue_start + 1) & 0x0f; + kbd->want_irq = 1; + } +} + +static void +kbd_adddata(uint16_t val) +{ + /* Test for T1000 'Fn' key (Right Alt / Right Ctrl) */ + if (is_t1x00) { + if (keyboard_recv(0x138) || keyboard_recv(0x11d)) { /* 'Fn' pressed */ + t1000_syskey(0x00, 0x04, 0x00); /* Set 'Fn' indicator */ + switch (val) { + case 0x45: /* Num Lock => toggle numpad */ + t1000_syskey(0x00, 0x00, 0x10); + break; + case 0x47: /* Home => internal display */ + t1000_syskey(0x40, 0x00, 0x00); + break; + case 0x49: /* PgDn => turbo on */ + t1000_syskey(0x80, 0x00, 0x00); + break; + case 0x4D: /* Right => toggle LCD font */ + t1000_syskey(0x00, 0x00, 0x20); + break; + case 0x4F: /* End => external display */ + t1000_syskey(0x00, 0x40, 0x00); + break; + case 0x51: /* PgDn => turbo off */ + t1000_syskey(0x00, 0x80, 0x00); + break; + case 0x54: /* SysRQ => toggle window */ + t1000_syskey(0x00, 0x00, 0x08); + break; + + default: + break; + } + } else + t1000_syskey(0x04, 0x00, 0x00); /* Reset 'Fn' indicator */ + } + + key_queue[key_queue_end] = val; + kbd_log("XTkbd: %02X added to key queue at %i\n", + val, key_queue_end); + key_queue_end = (key_queue_end + 1) & 0x0f; +} + +void +kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val)) +{ + uint8_t num_lock = 0; + uint8_t shift_states = 0; + + if (!adddata) + return; + + keyboard_get_states(NULL, &num_lock, NULL, NULL); + shift_states = keyboard_get_shift() & STATE_LSHIFT; + + if (is_amstrad) + num_lock = !num_lock; + + /* If NumLock is on, invert the left shift state so we can always check for + the the same way flag being set (and with NumLock on that then means it + is actually *NOT* set). */ + if (num_lock) + shift_states ^= STATE_LSHIFT; + + switch (val) { + case FAKE_LSHIFT_ON: + /* If NumLock is on, fake shifts are sent when shift is *NOT* presed, + if NumLock is off, fake shifts are sent when shift is pressed. */ + if (shift_states) { + /* Send fake shift. */ + adddata(num_lock ? 0x2a : 0xaa); + } + break; + case FAKE_LSHIFT_OFF: + if (shift_states) { + /* Send fake shift. */ + adddata(num_lock ? 0xaa : 0x2a); + } + break; + default: + adddata(val); + break; + } +} + +static void +kbd_adddata_ex(uint16_t val) +{ + kbd_adddata_process(val, kbd_adddata); +} + +static void +kbd_write(uint16_t port, uint8_t val, void *priv) +{ + xtkbd_t *kbd = (xtkbd_t *) priv; + uint8_t bit; + uint8_t set; + uint8_t new_clock; + + switch (port) { + case 0x61: /* Keyboard Control Register (aka Port B) */ + if (!(val & 0x80) || (kbd->type == KBD_TYPE_HYUNDAI)) { + new_clock = !!(val & 0x40); + if (!kbd->clock && new_clock) { + key_queue_start = key_queue_end = 0; + kbd->want_irq = 0; + kbd->blocked = 0; + kbd_adddata(0xaa); + } + } + + kbd->pb = val; + 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)) + pc_cas_set_motor(cassette, (kbd->pb & 0x08) == 0); + + speaker_update(); + + speaker_gated = val & 1; + speaker_enable = val & 2; + + if (speaker_enable) + was_speaker_enable = 1; + pit_devs[0].set_gate(pit_devs[0].data, 2, val & 1); + + if (val & 0x80) { + kbd->pa = 0; + kbd->blocked = 0; + picintc(2); + } + +#ifdef ENABLE_KEYBOARD_XT_LOG + if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) + kbd_log("XTkbd: Cassette motor is %s\n", !(val & 0x08) ? "ON" : "OFF"); +#endif + break; + + case 0x62: /* Switch Register (aka Port C) */ +#ifdef ENABLE_KEYBOARD_XT_LOG + if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) + kbd_log("XTkbd: Cassette IN is %i\n", !!(val & 0x10)); +#endif + if (kbd->type == KBD_TYPE_FE2010) { + kbd_log("XTkbd: Switch register in is %02X\n", val); + if (!(kbd->cfg & 0x08)) + kbd->pd = (kbd->pd & 0x30) | (val & 0xcf); + } + break; + + case 0x63: + if (kbd->type == KBD_TYPE_FE2010) { + kbd_log("XTkbd: Configuration register in is %02X\n", val); + if (!(kbd->cfg & 0x08)) + kbd->cfg = val; + } + break; + + case 0xc0 ... 0xcf: /* Pravetz Flags */ + kbd_log("XTkbd: Port %02X out: %02X\n", port, val); + if (kbd->type == KBD_TYPE_PRAVETZ) { + bit = (port >> 1) & 0x07; + set = (port & 0x01) << bit; + kbd->pravetz_flags = (kbd->pravetz_flags & ~(1 << bit)) | set; + } + break; + + case 0x1f0: + kbd_log("XTkbd: Port %04X out: %02X\n", port, val); + if (kbd->type == KBD_TYPE_VTECH) { + kbd->cpu_speed = val; + cpu_dynamic_switch(kbd->cpu_speed >> 7); + } + break; + + default: + break; + } +} + +static uint8_t +kbd_read(uint16_t port, void *priv) +{ + const xtkbd_t *kbd = (xtkbd_t *) priv; + uint8_t ret = 0xff; + + switch (port) { + case 0x60: /* Keyboard Data Register (aka Port A) */ + if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) || + (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ) || + (kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) || + (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || + (kbd->type == KBD_TYPE_ZENITH) || (kbd->type == KBD_TYPE_HYUNDAI) || + (kbd->type == KBD_TYPE_VTECH))) { + 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) || + (kbd->type == KBD_TYPE_VTECH)) + /* 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: + * bits 6-7: floppy drive number + * bits 4-5: video mode + * bit 2-3: base memory size + * bit 1: fpu enable + * bit 0: fdc enable + */ + ret = get_fdd_switch_settings(); + + ret |= get_videomode_switch_settings(); + + /* Base memory size should always be 64k */ + ret |= 0x0c; + + if (hasfpu) + ret |= 0x02; + } + } else + ret = kbd->pa; + break; + + case 0x61: /* Keyboard Control Register (aka Port B) */ + ret = kbd->pb; + break; + + case 0x62: /* Switch Register (aka Port C) */ + if (kbd->type == KBD_TYPE_FE2010) { + if (kbd->pb & 0x04) /* PB2 */ + ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00); + else + ret = kbd->pd >> 4; + } else 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: + case 48: + case 32: + case 16: + ret = 0x00; + break; + default: + ret = (((mem_size + isa_mem_size) - 64) / 32) & 0x0f; + break; + } + else + ret = (((mem_size + isa_mem_size) - 64) / 32) >> 4; + } 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; + else + ret = kbd->pd >> 4; + } else { + if (kbd->pb & 0x08) /* PB3 */ + ret = kbd->pd >> 4; + else + ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00); + } + ret |= (ppispeakon ? 0x20 : 0); + + /* 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 (cassette == NULL) + ret |= (ppispeakon ? 0x10 : 0); + else + ret |= (pc_cas_get_inp(cassette) ? 0x10 : 0); + } + + if (kbd->type == KBD_TYPE_TANDY) + ret |= (tandy1k_eeprom_read() ? 0x10 : 0); + break; + + 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_HYUNDAI) || + (kbd->type == KBD_TYPE_VTECH)) + ret = kbd->pd; + break; + + case 0xc0: /* Pravetz Flags */ + if (kbd->type == KBD_TYPE_PRAVETZ) + ret = kbd->pravetz_flags; + kbd_log("XTkbd: Port %02X in : %02X\n", port, ret); + break; + + case 0x1f0: + if (kbd->type == KBD_TYPE_VTECH) + ret = kbd->cpu_speed; + kbd_log("XTkbd: Port %04X in : %02X\n", port, ret); + break; + + default: + break; + } + + return ret; +} + +static void +kbd_reset(void *priv) +{ + xtkbd_t *kbd = (xtkbd_t *) priv; + + kbd->want_irq = 0; + kbd->blocked = 0; + kbd->pa = 0x00; + kbd->pb = 0x00; + kbd->pravetz_flags = 0x00; + + keyboard_scan = 1; + + key_queue_start = 0; + key_queue_end = 0; +} + +void +keyboard_set_is_amstrad(int ams) +{ + is_amstrad = ams; +} + +static void * +kbd_init(const device_t *info) +{ + xtkbd_t *kbd; + + kbd = (xtkbd_t *) calloc(1, sizeof(xtkbd_t)); + + io_sethandler(0x0060, 4, + kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); + keyboard_send = kbd_adddata_ex; + kbd->type = info->local; + if (kbd->type == KBD_TYPE_VTECH) + kbd->cpu_speed = (!!cpu) << 2; + kbd_reset(kbd); + if (kbd->type == KBD_TYPE_PRAVETZ) + io_sethandler(0x00c0, 16, + kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); + if (kbd->type == KBD_TYPE_VTECH) + io_sethandler(0x01f0, 1, + kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); + + key_queue_start = key_queue_end = 0; + + video_reset(gfxcard[0]); + + if ((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_TOSHIBA) || + (kbd->type == KBD_TYPE_OLIVETTI) || (kbd->type == KBD_TYPE_HYUNDAI) || + (kbd->type == KBD_TYPE_VTECH) || (kbd->type == KBD_TYPE_FE2010)) { + /* DIP switch readout: bit set = OFF, clear = ON. */ + if (kbd->type == KBD_TYPE_OLIVETTI) + /* Olivetti M19 + * Jumpers J1, J2 - monitor type. + * 01 - mono (high-res) + * 10 - color (low-res, disables 640x400x2 mode) + * 00 - autoswitching + */ + kbd->pd |= 0x00; + else + /* Switches 7, 8 - floppy drives. */ + kbd->pd = get_fdd_switch_settings(); + + /* Switches 5, 6 - video card type */ + kbd->pd |= get_videomode_switch_settings(); + + /* Switches 3, 4 - memory size. */ + if ((kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) || + (kbd->type == KBD_TYPE_HYUNDAI) || (kbd->type == KBD_TYPE_COMPAQ) || + (kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_FE2010)) { + switch (mem_size) { + case 256: + kbd->pd |= 0x00; + break; + case 512: + kbd->pd |= 0x04; + break; + case 576: + kbd->pd |= 0x08; + break; + case 640: + default: + kbd->pd |= 0x0c; + break; + } + } else if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_VTECH)) { + switch (mem_size) { + case 64: /* 1x64k */ + kbd->pd |= 0x00; + break; + case 128: /* 2x64k */ + kbd->pd |= 0x04; + break; + case 192: /* 3x64k */ + kbd->pd |= 0x08; + break; + case 256: /* 4x64k */ + default: + kbd->pd |= 0x0c; + break; + } + } else if (kbd->type == KBD_TYPE_PC82) { + switch (mem_size) { +#ifdef PC82_192K_3BANK + case 192: /* 3x64k, not supported by stock BIOS due to bugs */ + kbd->pd |= 0x08; + break; +#else + case 192: /* 2x64k + 2x32k */ +#endif + case 64: /* 4x16k */ + case 96: /* 2x32k + 2x16k */ + case 128: /* 4x32k */ + case 160: /* 2x64k + 2x16k */ + case 224: /* 3x64k + 1x32k */ + case 256: /* 4x64k */ + default: + kbd->pd |= 0x0c; + break; + } + } else { /* really just the PC '81 */ + switch (mem_size) { + case 16: /* 1x16k */ + kbd->pd |= 0x00; + break; + case 32: /* 2x16k */ + kbd->pd |= 0x04; + break; + case 48: /* 3x16k */ + kbd->pd |= 0x08; + break; + case 64: /* 4x16k */ + default: + kbd->pd |= 0x0c; + break; + } + } + + /* Switch 2 - 8087 FPU. */ + if (hasfpu) + kbd->pd |= 0x02; + } else if (kbd->type == KBD_TYPE_ZENITH) { + /* Zenith Data Systems Z-151 + * SW2 switch settings: + * bit 7: monitor frequency + * bits 5-6: autoboot (00-11 resident monitor, 10 hdd, 01 fdd) + * bits 0-4: installed memory + */ + kbd->pd = 0x20; + switch (mem_size) { + case 128: + kbd->pd |= 0x02; + break; + case 192: + kbd->pd |= 0x04; + break; + case 256: + kbd->pd |= 0x06; + break; + case 320: + kbd->pd |= 0x08; + break; + case 384: + kbd->pd |= 0x0a; + break; + case 448: + kbd->pd |= 0x0c; + break; + case 512: + kbd->pd |= 0x0e; + break; + case 576: + kbd->pd |= 0x10; + break; + case 640: + default: + kbd->pd |= 0x12; + break; + } + } + + timer_add(&kbd->send_delay_timer, kbd_poll, kbd, 1); + + is_tandy = (kbd->type == KBD_TYPE_TANDY); + is_t1x00 = (kbd->type == KBD_TYPE_TOSHIBA); + + if (keyboard_type == KEYBOARD_TYPE_INTERNAL) + keyboard_set_table(scancode_xt); + else + keyboard_add_device(); + + is_amstrad = 0; + + return kbd; +} + +static void +kbd_close(void *priv) +{ + xtkbd_t *kbd = (xtkbd_t *) priv; + + /* Stop the timer. */ + timer_disable(&kbd->send_delay_timer); + + /* Disable scanning. */ + keyboard_scan = 0; + + keyboard_send = NULL; + + io_removehandler(0x0060, 4, + kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); + + free(kbd); +} + +const device_t kbc_pc_device = { + .name = "IBM PC Keyboard Controller (1981)", + .internal_name = "kbc_pc", + .flags = 0, + .local = KBD_TYPE_PC81, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t kbc_pc82_device = { + .name = "IBM PC Keyboard Controller (1982)", + .internal_name = "kbc_pc82", + .flags = 0, + .local = KBD_TYPE_PC82, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t kbc_pravetz_device = { + .name = "Pravetz Keyboard Controller", + .internal_name = "kbc_pravetz", + .flags = 0, + .local = KBD_TYPE_PRAVETZ, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t kbc_xt_device = { + .name = "XT (1982) Keyboard Controller", + .internal_name = "kbc_xt", + .flags = 0, + .local = KBD_TYPE_XT82, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t kbc_xt86_device = { + .name = "XT (1986) Keyboard Controller", + .internal_name = "kbc_xt86", + .flags = 0, + .local = KBD_TYPE_XT86, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t kbc_xt_compaq_device = { + .name = "Compaq Portable Keyboard Controller", + .internal_name = "kbc_xt_compaq", + .flags = 0, + .local = KBD_TYPE_COMPAQ, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t kbc_tandy_device = { + .name = "Tandy 1000 Keyboard Controller", + .internal_name = "kbc_tandy", + .flags = 0, + .local = KBD_TYPE_TANDY, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t kbc_xt_t1x00_device = { + .name = "Toshiba T1x00 Keyboard Controller", + .internal_name = "kbc_xt_t1x00", + .flags = 0, + .local = KBD_TYPE_TOSHIBA, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t kbc_xt_lxt3_device = { + .name = "VTech Laser Turbo XT Keyboard Controller", + .internal_name = "kbc_xt_lxt", + .flags = 0, + .local = KBD_TYPE_VTECH, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t kbc_xt_olivetti_device = { + .name = "Olivetti XT Keyboard Controller", + .internal_name = "kbc_xt_olivetti", + .flags = 0, + .local = KBD_TYPE_OLIVETTI, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t kbc_xt_zenith_device = { + .name = "Zenith XT Keyboard Controller", + .internal_name = "kbc_xt_zenith", + .flags = 0, + .local = KBD_TYPE_ZENITH, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t kbc_xt_hyundai_device = { + .name = "Hyundai XT Keyboard Controller", + .internal_name = "kbc_xt_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 kbc_xt_fe2010_device = { + .name = "Faraday FE2010 XT Keyboard Controller", + .internal_name = "kbc_xt_fe2010", + .flags = 0, + .local = KBD_TYPE_FE2010, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t kbc_xtclone_device = { + .name = "XT (Clone) Keyboard Controller", + .internal_name = "kbc_xtclone", + .flags = 0, + .local = KBD_TYPE_XTCLONE, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/device/keyboard.c b/src/device/keyboard.c index 0fd342e55..0acc93505 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -27,6 +27,7 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/machine.h> +#include <86box/device.h> #include <86box/keyboard.h> #include <86box/plat.h> @@ -36,6 +37,38 @@ uint16_t scancode_map[768] = { 0 }; int keyboard_scan; +typedef struct keyboard_t { + const device_t *device; +} keyboard_t; + +int keyboard_type = 0; + +static const device_t keyboard_internal_device = { + .name = "Internal", + .internal_name = "internal", + .flags = 0, + .local = KEYBOARD_TYPE_INTERNAL, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +static keyboard_t keyboard_devices[] = { + // clang-format off + { &keyboard_internal_device }, + { &keyboard_pc_xt_device }, + { &keyboard_at_device }, + { &keyboard_ax_device }, + { &keyboard_ps2_device }, + { &keyboard_ps55_device }, + { NULL } + // clang-format on +}; + #ifdef ENABLE_KBC_AT_LOG int kbc_at_do_log = ENABLE_KBC_AT_LOG; @@ -64,10 +97,12 @@ static int keydelay[512]; #endif static scancode *scan_table; /* scancode table for keyboard */ -static uint8_t caps_lock = 0; -static uint8_t num_lock = 0; -static uint8_t scroll_lock = 0; -static uint8_t shift = 0; +static volatile uint8_t caps_lock = 0; +static volatile uint8_t num_lock = 0; +static volatile uint8_t scroll_lock = 0; +static volatile uint8_t kana_lock = 0; +static volatile uint8_t kbd_in_reset = 0; +static uint8_t shift = 0; static int key5576mode = 0; @@ -105,10 +140,12 @@ static scconvtbl scconv55_8a[18 + 1] = void keyboard_init(void) { - num_lock = 0; - caps_lock = 0; - scroll_lock = 0; - shift = 0; + num_lock = 0; + caps_lock = 0; + scroll_lock = 0; + kana_lock = 0; + shift = 0; + kbd_in_reset = 0; memset(recv_key, 0x00, sizeof(recv_key)); memset(recv_key_ui, 0x00, sizeof(recv_key)); @@ -236,6 +273,9 @@ key_process(uint16_t scan, int down) void keyboard_input(int down, uint16_t scan) { + if (kbd_in_reset) + return; + /* Special case for E1 1D, translate it to 0100 - special case. */ if ((scan >> 8) == 0xe1) { if ((scan & 0xff) == 0x1d) @@ -310,13 +350,16 @@ keyboard_input(int down, uint16_t scan) shift &= ~0x80; break; case 0x03a: /* Caps Lock */ - caps_lock ^= 1; + if (!(machine_has_bus(machine, MACHINE_AT) > 0)) + caps_lock ^= 1; break; case 0x045: - num_lock ^= 1; + if (!(machine_has_bus(machine, MACHINE_AT) > 0)) + num_lock ^= 1; break; case 0x046: - scroll_lock ^= 1; + if (!(machine_has_bus(machine, MACHINE_AT) > 0)) + scroll_lock ^= 1; break; default: @@ -338,9 +381,9 @@ void keyboard_all_up(void) { for (unsigned short i = 0; i < 0x200; i++) { - if (recv_key_ui[i]) { + if (recv_key_ui[i]) recv_key_ui[i] = 0; - } + if (recv_key[i]) { recv_key[i] = 0; key_process(i, 0); @@ -348,6 +391,18 @@ keyboard_all_up(void) } } +void +keyboard_set_in_reset(uint8_t in_reset) +{ + kbd_in_reset = in_reset; +} + +uint8_t +keyboard_get_in_reset(void) +{ + return kbd_in_reset; +} + static uint8_t keyboard_do_break(uint16_t scan) { @@ -367,11 +422,12 @@ keyboard_do_break(uint16_t scan) Caps Lock, Num Lock, and Scroll Lock when receving the "Set keyboard LEDs" command. */ void -keyboard_update_states(uint8_t cl, uint8_t nl, uint8_t sl) +keyboard_update_states(uint8_t cl, uint8_t nl, uint8_t sl, uint8_t kl) { caps_lock = cl; num_lock = nl; scroll_lock = sl; + kana_lock = kl; } uint8_t @@ -381,7 +437,7 @@ keyboard_get_shift(void) } void -keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl) +keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl, uint8_t *kl) { if (cl) *cl = caps_lock; @@ -389,6 +445,8 @@ keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl) *nl = num_lock; if (sl) *sl = scroll_lock; + if (kl) + *kl = kana_lock; } /* Called by the UI to update the states of Caps Lock, Num Lock, and Scroll Lock. */ @@ -432,7 +490,7 @@ keyboard_set_states(uint8_t cl, uint8_t nl, uint8_t sl) } } - keyboard_update_states(cl, nl, sl); + keyboard_update_states(cl, nl, sl, kana_lock); } int @@ -491,3 +549,57 @@ convert_scan_code(uint16_t scan_code) return scan_code; } + +const char * +keyboard_get_name(int keyboard) +{ + return (keyboard_devices[keyboard].device->name); +} + +const char * +keyboard_get_internal_name(int keyboard) +{ + return device_get_internal_name(keyboard_devices[keyboard].device); +} + +int +keyboard_get_from_internal_name(char *s) +{ + int c = 0; + + while (keyboard_devices[c].device != NULL) { + if (!strcmp((char *) keyboard_devices[c].device->internal_name, s)) + return c; + c++; + } + + return 0; +} + +int +keyboard_has_config(int keyboard) +{ + if (keyboard_devices[keyboard].device == NULL) + return 0; + + return (keyboard_devices[keyboard].device->config ? 1 : 0); +} + +const device_t * +keyboard_get_device(int keyboard) +{ + return (keyboard_devices[keyboard].device); +} + +/* Return number of MOUSE types we know about. */ +int +keyboard_get_ndev(void) +{ + return ((sizeof(keyboard_devices) / sizeof(keyboard_t)) - 1); +} + +void +keyboard_add_device(void) +{ + device_add(keyboard_devices[keyboard_type].device); +} diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index e61b8547a..9696956b1 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -27,41 +27,37 @@ #include <86box/mouse.h> #include <86box/machine.h> -#define FLAG_PS2 0x08 /* dev is AT or PS/2 */ -#define FLAG_AT 0x00 /* dev is AT or PS/2 */ -#define FLAG_TYPE_MASK 0x07 /* mask for type */ - #define FIFO_SIZE 16 #define BAT_COUNT 1000 -enum { - KBD_84_KEY = 0, - KBD_101_KEY, - KBD_102_KEY, - KBD_JIS, - KBD_KOREAN -}; - #define FLAG_ENABLED 0x10 /* dev is enabled for use */ #define FLAG_CTRLDAT 0x08 /* ctrl or data mode */ -const uint8_t id_bytes[16][4] = { { 0x00, 0x00, 0x00, 0x00 }, /* AT 84-key */ - { 0x00, 0x00, 0x00, 0x00 }, /* AT 101/102/106-key */ +const uint8_t id_bytes[24][4] = { { 0x00, 0x00, 0x00, 0x00 }, /* XT 83-key */ + { 0x00, 0x00, 0x00, 0x00 }, /* AT 84-key */ + { 0x00, 0x00, 0x00, 0x00 }, /* XT/AT 101/102/106-key */ { 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00 }, /* AT Korean */ + { 0x00, 0x00, 0x00, 0x00 }, /* AT KSC */ + { 0x00, 0x00, 0x00, 0x00 }, /* AT ABNT2 */ + { 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00 }, /* FLAG_AX = 0x08 */ { 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00 }, /* FLAG_PS2 = 0x08 */ + { 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00 }, /* FLAG_PS2_KBD = 0x10 */ + { 0x00, 0x00, 0x00, 0x00 }, { 0xab, 0x83, 0x00, 0x00 }, /* PS/2 101-key */ { 0xab, 0x83, 0x00, 0x00 }, /* PS/2 102-key */ { 0xab, 0x90, 0x00, 0x00 }, /* PS/55 106-key JIS (IBM-J 5576-002) */ /* Japanese keyboard ID - TODO: Find the actual Korean one. */ - { 0xab, 0x90, 0x00, 0x00 }, /* PS/2 Korean */ - { 0x00, 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0x00, 0x00 }, + { 0xab, 0x90, 0x00, 0x00 }, /* PS/2 KSC */ + { 0xab, 0x83, 0x00, 0x00 }, /* PS/2 ABNT2 */ { 0x00, 0x00, 0x00, 0x00 } }; /* Global keyboard flags for scan code set 3: @@ -78,9 +74,2079 @@ static atkbc_dev_t *SavedKbd = NULL; static uint8_t inv_cmd_response = 0xfa; +static int is_special = 0; + static uint16_t bat_counter = 0; -static const scancode scancode_set1[512] = { +const scancode scancode_set1_at[512] = { + // clang-format off + { .mk = { 0 }, .brk = { 0 } }, /* 000 */ + { .mk = { 0x01, 0 }, .brk = { 0x81, 0 } }, /* 001 */ + { .mk = { 0x02, 0 }, .brk = { 0x82, 0 } }, /* 002 */ + { .mk = { 0x03, 0 }, .brk = { 0x83, 0 } }, /* 003 */ + { .mk = { 0x04, 0 }, .brk = { 0x84, 0 } }, /* 004 */ + { .mk = { 0x05, 0 }, .brk = { 0x85, 0 } }, /* 005 */ + { .mk = { 0x06, 0 }, .brk = { 0x86, 0 } }, /* 006 */ + { .mk = { 0x07, 0 }, .brk = { 0x87, 0 } }, /* 007 */ + { .mk = { 0x08, 0 }, .brk = { 0x88, 0 } }, /* 008 */ + { .mk = { 0x09, 0 }, .brk = { 0x89, 0 } }, /* 009 */ + { .mk = { 0x0a, 0 }, .brk = { 0x8a, 0 } }, /* 00a */ + { .mk = { 0x0b, 0 }, .brk = { 0x8b, 0 } }, /* 00b */ + { .mk = { 0x0c, 0 }, .brk = { 0x8c, 0 } }, /* 00c */ + { .mk = { 0x0d, 0 }, .brk = { 0x8d, 0 } }, /* 00d */ + { .mk = { 0x0e, 0 }, .brk = { 0x8e, 0 } }, /* 00e */ + { .mk = { 0x0f, 0 }, .brk = { 0x8f, 0 } }, /* 00f */ + { .mk = { 0x10, 0 }, .brk = { 0x90, 0 } }, /* 010 */ + { .mk = { 0x11, 0 }, .brk = { 0x91, 0 } }, /* 011 */ + { .mk = { 0x12, 0 }, .brk = { 0x92, 0 } }, /* 012 */ + { .mk = { 0x13, 0 }, .brk = { 0x93, 0 } }, /* 013 */ + { .mk = { 0x14, 0 }, .brk = { 0x94, 0 } }, /* 014 */ + { .mk = { 0x15, 0 }, .brk = { 0x95, 0 } }, /* 015 */ + { .mk = { 0x16, 0 }, .brk = { 0x96, 0 } }, /* 016 */ + { .mk = { 0x17, 0 }, .brk = { 0x97, 0 } }, /* 017 */ + { .mk = { 0x18, 0 }, .brk = { 0x98, 0 } }, /* 018 */ + { .mk = { 0x19, 0 }, .brk = { 0x99, 0 } }, /* 019 */ + { .mk = { 0x1a, 0 }, .brk = { 0x9a, 0 } }, /* 01a */ + { .mk = { 0x1b, 0 }, .brk = { 0x9b, 0 } }, /* 01b */ + { .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 01c */ + { .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 01d */ + { .mk = { 0x1e, 0 }, .brk = { 0x9e, 0 } }, /* 01e */ + { .mk = { 0x1f, 0 }, .brk = { 0x9f, 0 } }, /* 01f */ + { .mk = { 0x20, 0 }, .brk = { 0xa0, 0 } }, /* 020 */ + { .mk = { 0x21, 0 }, .brk = { 0xa1, 0 } }, /* 021 */ + { .mk = { 0x22, 0 }, .brk = { 0xa2, 0 } }, /* 022 */ + { .mk = { 0x23, 0 }, .brk = { 0xa3, 0 } }, /* 023 */ + { .mk = { 0x24, 0 }, .brk = { 0xa4, 0 } }, /* 024 */ + { .mk = { 0x25, 0 }, .brk = { 0xa5, 0 } }, /* 025 */ + { .mk = { 0x26, 0 }, .brk = { 0xa6, 0 } }, /* 026 */ + { .mk = { 0x27, 0 }, .brk = { 0xa7, 0 } }, /* 027 */ + { .mk = { 0x28, 0 }, .brk = { 0xa8, 0 } }, /* 028 */ + { .mk = { 0x29, 0 }, .brk = { 0xa9, 0 } }, /* 029 */ + { .mk = { 0x2a, 0 }, .brk = { 0xaa, 0 } }, /* 02a */ + { .mk = { 0x2b, 0 }, .brk = { 0xab, 0 } }, /* 02b */ + { .mk = { 0x2c, 0 }, .brk = { 0xac, 0 } }, /* 02c */ + { .mk = { 0x2d, 0 }, .brk = { 0xad, 0 } }, /* 02d */ + { .mk = { 0x2e, 0 }, .brk = { 0xae, 0 } }, /* 02e */ + { .mk = { 0x2f, 0 }, .brk = { 0xaf, 0 } }, /* 02f */ + { .mk = { 0x30, 0 }, .brk = { 0xb0, 0 } }, /* 030 */ + { .mk = { 0x31, 0 }, .brk = { 0xb1, 0 } }, /* 031 */ + { .mk = { 0x32, 0 }, .brk = { 0xb2, 0 } }, /* 032 */ + { .mk = { 0x33, 0 }, .brk = { 0xb3, 0 } }, /* 033 */ + { .mk = { 0x34, 0 }, .brk = { 0xb4, 0 } }, /* 034 */ + { .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 035 */ + { .mk = { 0x36, 0 }, .brk = { 0xb6, 0 } }, /* 036 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 037 */ + { .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 038 */ + { .mk = { 0x39, 0 }, .brk = { 0xb9, 0 } }, /* 039 */ + { .mk = { 0x3a, 0 }, .brk = { 0xba, 0 } }, /* 03a */ + { .mk = { 0x3b, 0 }, .brk = { 0xbb, 0 } }, /* 03b */ + { .mk = { 0x3c, 0 }, .brk = { 0xbc, 0 } }, /* 03c */ + { .mk = { 0x3d, 0 }, .brk = { 0xbd, 0 } }, /* 03d */ + { .mk = { 0x3e, 0 }, .brk = { 0xbe, 0 } }, /* 03e */ + { .mk = { 0x3f, 0 }, .brk = { 0xbf, 0 } }, /* 03f */ + { .mk = { 0x40, 0 }, .brk = { 0xc0, 0 } }, /* 040 */ + { .mk = { 0x41, 0 }, .brk = { 0xc1, 0 } }, /* 041 */ + { .mk = { 0x42, 0 }, .brk = { 0xc2, 0 } }, /* 042 */ + { .mk = { 0x43, 0 }, .brk = { 0xc3, 0 } }, /* 043 */ + { .mk = { 0x44, 0 }, .brk = { 0xc4, 0 } }, /* 044 */ + { .mk = { 0x45, 0 }, .brk = { 0xc5, 0 } }, /* 045 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 046 */ + { .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 047 */ + { .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 048 */ + { .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 049 */ + { .mk = { 0x4a, 0 }, .brk = { 0xca, 0 } }, /* 04a */ + { .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 04b */ + { .mk = { 0x4c, 0 }, .brk = { 0xcc, 0 } }, /* 04c */ + { .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 04d */ + { .mk = { 0x4e, 0 }, .brk = { 0xce, 0 } }, /* 04e */ + { .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 04f */ + { .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 050 */ + { .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 051 */ + { .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 052 */ + { .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 053 */ + { .mk = { 0x54, 0 }, .brk = { 0xd4, 0 } }, /* 054 */ + { .mk = { 0 }, .brk = { 0 } }, /* 055 */ + { .mk = { 0x56, 0 }, .brk = { 0xd6, 0 } }, /* 054 */ + { .mk = { 0 }, .brk = { 0 } }, /* 057 */ + { .mk = { 0 }, .brk = { 0 } }, /* 058 */ + { .mk = { 0 }, .brk = { 0 } }, /* 059 */ + { .mk = { 0 }, .brk = { 0 } }, /* 05a */ + { .mk = { 0 }, .brk = { 0 } }, /* 05b */ + { .mk = { 0x5c, 0 }, .brk = { 0xdc, 0 } }, /* 054 */ + { .mk = { 0 }, .brk = { 0 } }, /* 05d */ + { .mk = { 0 }, .brk = { 0 } }, /* 05e */ + { .mk = { 0 }, .brk = { 0 } }, /* 05f */ + { .mk = { 0x60, 0 }, .brk = { 0xe0, 0 } }, /* 060 */ + { .mk = { 0x61, 0 }, .brk = { 0xe1, 0 } }, /* 061 */ + { .mk = { 0x62, 0 }, .brk = { 0xe2, 0 } }, /* 062 */ + { .mk = { 0x63, 0 }, .brk = { 0xe3, 0 } }, /* 063 */ + { .mk = { 0x64, 0 }, .brk = { 0xe4, 0 } }, /* 064 */ + { .mk = { 0x65, 0 }, .brk = { 0xe5, 0 } }, /* 065 */ + { .mk = { 0x66, 0 }, .brk = { 0xe6, 0 } }, /* 066 */ + { .mk = { 0x67, 0 }, .brk = { 0xe7, 0 } }, /* 067 */ + { .mk = { 0x68, 0 }, .brk = { 0xe8, 0 } }, /* 068 */ + { .mk = { 0x69, 0 }, .brk = { 0xe9, 0 } }, /* 069 */ + { .mk = { 0x6a, 0 }, .brk = { 0xea, 0 } }, /* 06a */ + { .mk = { 0x6b, 0 }, .brk = { 0xeb, 0 } }, /* 06b */ + { .mk = { 0x6c, 0 }, .brk = { 0xec, 0 } }, /* 06c */ + { .mk = { 0x6d, 0 }, .brk = { 0xed, 0 } }, /* 06d */ + { .mk = { 0x6e, 0 }, .brk = { 0xee, 0 } }, /* 06e */ + { .mk = { 0x6f, 0 }, .brk = { 0xef, 0 } }, /* 06f */ + { .mk = { 0x70, 0 }, .brk = { 0xf0, 0 } }, /* 070 */ + { .mk = { 0x71, 0 }, .brk = { 0xf1, 0 } }, /* 071 */ + { .mk = { 0x72, 0 }, .brk = { 0xf2, 0 } }, /* 072 */ + { .mk = { 0x73, 0 }, .brk = { 0xf3, 0 } }, /* 073 */ + { .mk = { 0x74, 0 }, .brk = { 0xf4, 0 } }, /* 074 */ + { .mk = { 0x75, 0 }, .brk = { 0xf5, 0 } }, /* 075 */ + { .mk = { 0x76, 0 }, .brk = { 0xf6, 0 } }, /* 076 */ + { .mk = { 0x77, 0 }, .brk = { 0xf7, 0 } }, /* 077 */ + { .mk = { 0x78, 0 }, .brk = { 0xf8, 0 } }, /* 078 */ + { .mk = { 0x79, 0 }, .brk = { 0xf9, 0 } }, /* 079 */ + { .mk = { 0x7a, 0 }, .brk = { 0xfa, 0 } }, /* 07a */ + { .mk = { 0x7b, 0 }, .brk = { 0xfb, 0 } }, /* 07b */ + { .mk = { 0x7c, 0 }, .brk = { 0xfc, 0 } }, /* 07c */ + { .mk = { 0x7d, 0 }, .brk = { 0xfd, 0 } }, /* 07d */ + { .mk = { 0x7e, 0 }, .brk = { 0xfe, 0 } }, /* 07e */ + { .mk = { 0x7f, 0 }, .brk = { 0xff, 0 } }, /* 07f */ + { .mk = { 0 }, .brk = { 0 } }, /* 080 */ + { .mk = { 0 }, .brk = { 0 } }, /* 081 */ + { .mk = { 0 }, .brk = { 0 } }, /* 082 */ + { .mk = { 0 }, .brk = { 0 } }, /* 083 */ + { .mk = { 0 }, .brk = { 0 } }, /* 084 */ + { .mk = { 0 }, .brk = { 0 } }, /* 085 */ + { .mk = { 0 }, .brk = { 0 } }, /* 086 */ + { .mk = { 0 }, .brk = { 0 } }, /* 087 */ + { .mk = { 0 }, .brk = { 0 } }, /* 088 */ + { .mk = { 0 }, .brk = { 0 } }, /* 089 */ + { .mk = { 0 }, .brk = { 0 } }, /* 08a */ + { .mk = { 0 }, .brk = { 0 } }, /* 08b */ + { .mk = { 0 }, .brk = { 0 } }, /* 08c */ + { .mk = { 0 }, .brk = { 0 } }, /* 08d */ + { .mk = { 0 }, .brk = { 0 } }, /* 08e */ + { .mk = { 0 }, .brk = { 0 } }, /* 08f */ + { .mk = { 0 }, .brk = { 0 } }, /* 090 */ + { .mk = { 0 }, .brk = { 0 } }, /* 091 */ + { .mk = { 0 }, .brk = { 0 } }, /* 092 */ + { .mk = { 0 }, .brk = { 0 } }, /* 093 */ + { .mk = { 0 }, .brk = { 0 } }, /* 094 */ + { .mk = { 0 }, .brk = { 0 } }, /* 095 */ + { .mk = { 0 }, .brk = { 0 } }, /* 096 */ + { .mk = { 0 }, .brk = { 0 } }, /* 097 */ + { .mk = { 0 }, .brk = { 0 } }, /* 098 */ + { .mk = { 0 }, .brk = { 0 } }, /* 099 */ + { .mk = { 0 }, .brk = { 0 } }, /* 09a */ + { .mk = { 0 }, .brk = { 0 } }, /* 09b */ + { .mk = { 0 }, .brk = { 0 } }, /* 09c */ + { .mk = { 0 }, .brk = { 0 } }, /* 09d */ + { .mk = { 0 }, .brk = { 0 } }, /* 09e */ + { .mk = { 0 }, .brk = { 0 } }, /* 09f */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 0af */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0be */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0da */ + { .mk = { 0 }, .brk = { 0 } }, /* 0db */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0de */ + { .mk = { 0 }, .brk = { 0 } }, /* 0df */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 0eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f0 */ + { .mk = { 0xf1, 0 }, .brk = { 0 } }, /* 0f1 */ + { .mk = { 0xf2, 0 }, .brk = { 0 } }, /* 0f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fe */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 100 */ + { .mk = { 0 }, .brk = { 0 } }, /* 101 */ + { .mk = { 0 }, .brk = { 0 } }, /* 102 */ + { .mk = { 0 }, .brk = { 0 } }, /* 103 */ + { .mk = { 0 }, .brk = { 0 } }, /* 104 */ + { .mk = { 0 }, .brk = { 0 } }, /* 105 */ + { .mk = { 0 }, .brk = { 0 } }, /* 106 */ + { .mk = { 0 }, .brk = { 0 } }, /* 107 */ + { .mk = { 0 }, .brk = { 0 } }, /* 108 */ + { .mk = { 0 }, .brk = { 0 } }, /* 109 */ + { .mk = { 0 }, .brk = { 0 } }, /* 10a */ + { .mk = { 0 }, .brk = { 0 } }, /* 10b */ + { .mk = { 0 }, .brk = { 0 } }, /* 10c */ + { .mk = { 0 }, .brk = { 0 } }, /* 10d */ + { .mk = { 0 }, .brk = { 0 } }, /* 10e */ + { .mk = { 0 }, .brk = { 0 } }, /* 10f */ + { .mk = { 0 }, .brk = { 0 } }, /* 110 */ + { .mk = { 0 }, .brk = { 0 } }, /* 111 */ + { .mk = { 0 }, .brk = { 0 } }, /* 112 */ + { .mk = { 0 }, .brk = { 0 } }, /* 113 */ + { .mk = { 0 }, .brk = { 0 } }, /* 114 */ + { .mk = { 0 }, .brk = { 0 } }, /* 115 */ + { .mk = { 0 }, .brk = { 0 } }, /* 116 */ + { .mk = { 0 }, .brk = { 0 } }, /* 117 */ + { .mk = { 0 }, .brk = { 0 } }, /* 118 */ + { .mk = { 0 }, .brk = { 0 } }, /* 119 */ + { .mk = { 0 }, .brk = { 0 } }, /* 11a */ + { .mk = { 0 }, .brk = { 0 } }, /* 11b */ + { .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 11c */ + { .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 11d */ + { .mk = { 0 }, .brk = { 0 } }, /* 11e */ + { .mk = { 0 }, .brk = { 0 } }, /* 11f */ + { .mk = { 0 }, .brk = { 0 } }, /* 120 */ + { .mk = { 0 }, .brk = { 0 } }, /* 121 */ + { .mk = { 0 }, .brk = { 0 } }, /* 122 */ + { .mk = { 0 }, .brk = { 0 } }, /* 123 */ + { .mk = { 0 }, .brk = { 0 } }, /* 124 */ + { .mk = { 0 }, .brk = { 0 } }, /* 125 */ + { .mk = { 0 }, .brk = { 0 } }, /* 126 */ + { .mk = { 0 }, .brk = { 0 } }, /* 127 */ + { .mk = { 0 }, .brk = { 0 } }, /* 128 */ + { .mk = { 0 }, .brk = { 0 } }, /* 129 */ + { .mk = { 0 }, .brk = { 0 } }, /* 12a */ + { .mk = { 0 }, .brk = { 0 } }, /* 12b */ + { .mk = { 0 }, .brk = { 0 } }, /* 12c */ + { .mk = { 0 }, .brk = { 0 } }, /* 12d */ + { .mk = { 0 }, .brk = { 0 } }, /* 12e */ + { .mk = { 0 }, .brk = { 0 } }, /* 12f */ + { .mk = { 0 }, .brk = { 0 } }, /* 130 */ + { .mk = { 0 }, .brk = { 0 } }, /* 131 */ + { .mk = { 0 }, .brk = { 0 } }, /* 132 */ + { .mk = { 0 }, .brk = { 0 } }, /* 133 */ + { .mk = { 0 }, .brk = { 0 } }, /* 134 */ + { .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 135 */ + { .mk = { 0 }, .brk = { 0 } }, /* 136 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 137 */ + { .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 138 */ + { .mk = { 0 }, .brk = { 0 } }, /* 139 */ + { .mk = { 0 }, .brk = { 0 } }, /* 13a */ + { .mk = { 0 }, .brk = { 0 } }, /* 13b */ + { .mk = { 0 }, .brk = { 0 } }, /* 13c */ + { .mk = { 0 }, .brk = { 0 } }, /* 13d */ + { .mk = { 0 }, .brk = { 0 } }, /* 13e */ + { .mk = { 0 }, .brk = { 0 } }, /* 13f */ + { .mk = { 0 }, .brk = { 0 } }, /* 140 */ + { .mk = { 0 }, .brk = { 0 } }, /* 141 */ + { .mk = { 0 }, .brk = { 0 } }, /* 142 */ + { .mk = { 0 }, .brk = { 0 } }, /* 143 */ + { .mk = { 0 }, .brk = { 0 } }, /* 144 */ + { .mk = { 0 }, .brk = { 0 } }, /* 145 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 146 */ + { .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 147 */ + { .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 148 */ + { .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 149 */ + { .mk = { 0 }, .brk = { 0 } }, /* 14a */ + { .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 14b */ + { .mk = { 0 }, .brk = { 0 } }, /* 14c */ + { .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 14d */ + { .mk = { 0 }, .brk = { 0 } }, /* 14e */ + { .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 14f */ + { .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 150 */ + { .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 151 */ + { .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 152 */ + { .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 153 */ + { .mk = { 0 }, .brk = { 0 } }, /* 154 */ + { .mk = { 0 }, .brk = { 0 } }, /* 155 */ + { .mk = { 0 }, .brk = { 0 } }, /* 156 */ + { .mk = { 0 }, .brk = { 0 } }, /* 157 */ + { .mk = { 0 }, .brk = { 0 } }, /* 158 */ + { .mk = { 0 }, .brk = { 0 } }, /* 159 */ + { .mk = { 0 }, .brk = { 0 } }, /* 15a */ + { .mk = { 0x56, 0 }, .brk = { 0xd6, 0 } }, /* 15b */ + { .mk = { 0 }, .brk = { 0 } }, /* 15c */ + { .mk = { 0 }, .brk = { 0 } }, /* 15d */ + { .mk = { 0 }, .brk = { 0 } }, /* 15e */ + { .mk = { 0 }, .brk = { 0 } }, /* 15f */ + { .mk = { 0 }, .brk = { 0 } }, /* 160 */ + { .mk = { 0 }, .brk = { 0 } }, /* 161 */ + { .mk = { 0 }, .brk = { 0 } }, /* 162 */ + { .mk = { 0 }, .brk = { 0 } }, /* 163 */ + { .mk = { 0 }, .brk = { 0 } }, /* 164 */ + { .mk = { 0 }, .brk = { 0 } }, /* 165 */ + { .mk = { 0 }, .brk = { 0 } }, /* 166 */ + { .mk = { 0 }, .brk = { 0 } }, /* 167 */ + { .mk = { 0 }, .brk = { 0 } }, /* 168 */ + { .mk = { 0 }, .brk = { 0 } }, /* 169 */ + { .mk = { 0 }, .brk = { 0 } }, /* 16a */ + { .mk = { 0 }, .brk = { 0 } }, /* 16b */ + { .mk = { 0 }, .brk = { 0 } }, /* 16c */ + { .mk = { 0 }, .brk = { 0 } }, /* 16d */ + { .mk = { 0 }, .brk = { 0 } }, /* 16e */ + { .mk = { 0 }, .brk = { 0 } }, /* 16f */ + { .mk = { 0 }, .brk = { 0 } }, /* 170 */ + { .mk = { 0 }, .brk = { 0 } }, /* 171 */ + { .mk = { 0 }, .brk = { 0 } }, /* 172 */ + { .mk = { 0 }, .brk = { 0 } }, /* 173 */ + { .mk = { 0 }, .brk = { 0 } }, /* 174 */ + { .mk = { 0 }, .brk = { 0 } }, /* 175 */ + { .mk = { 0 }, .brk = { 0 } }, /* 176 */ + { .mk = { 0 }, .brk = { 0 } }, /* 177 */ + { .mk = { 0 }, .brk = { 0 } }, /* 178 */ + { .mk = { 0 }, .brk = { 0 } }, /* 179 */ + { .mk = { 0 }, .brk = { 0 } }, /* 17a */ + { .mk = { 0 }, .brk = { 0 } }, /* 17b */ + { .mk = { 0 }, .brk = { 0 } }, /* 17c */ + { .mk = { 0 }, .brk = { 0 } }, /* 17d */ + { .mk = { 0 }, .brk = { 0 } }, /* 17e */ + { .mk = { 0 }, .brk = { 0 } }, /* 17f */ + { .mk = { 0 }, .brk = { 0 } }, /* 180 */ + { .mk = { 0 }, .brk = { 0 } }, /* 181 */ + { .mk = { 0 }, .brk = { 0 } }, /* 182 */ + { .mk = { 0 }, .brk = { 0 } }, /* 183 */ + { .mk = { 0 }, .brk = { 0 } }, /* 184 */ + { .mk = { 0 }, .brk = { 0 } }, /* 185 */ + { .mk = { 0 }, .brk = { 0 } }, /* 186 */ + { .mk = { 0 }, .brk = { 0 } }, /* 187 */ + { .mk = { 0 }, .brk = { 0 } }, /* 188 */ + { .mk = { 0 }, .brk = { 0 } }, /* 189 */ + { .mk = { 0 }, .brk = { 0 } }, /* 18a */ + { .mk = { 0 }, .brk = { 0 } }, /* 18b */ + { .mk = { 0 }, .brk = { 0 } }, /* 18c */ + { .mk = { 0 }, .brk = { 0 } }, /* 18d */ + { .mk = { 0 }, .brk = { 0 } }, /* 18e */ + { .mk = { 0 }, .brk = { 0 } }, /* 18f */ + { .mk = { 0 }, .brk = { 0 } }, /* 190 */ + { .mk = { 0 }, .brk = { 0 } }, /* 191 */ + { .mk = { 0 }, .brk = { 0 } }, /* 192 */ + { .mk = { 0 }, .brk = { 0 } }, /* 193 */ + { .mk = { 0 }, .brk = { 0 } }, /* 194 */ + { .mk = { 0 }, .brk = { 0 } }, /* 195 */ + { .mk = { 0 }, .brk = { 0 } }, /* 196 */ + { .mk = { 0 }, .brk = { 0 } }, /* 197 */ + { .mk = { 0 }, .brk = { 0 } }, /* 198 */ + { .mk = { 0 }, .brk = { 0 } }, /* 199 */ + { .mk = { 0 }, .brk = { 0 } }, /* 19a */ + { .mk = { 0 }, .brk = { 0 } }, /* 19b */ + { .mk = { 0 }, .brk = { 0 } }, /* 19c */ + { .mk = { 0 }, .brk = { 0 } }, /* 19d */ + { .mk = { 0 }, .brk = { 0 } }, /* 19e */ + { .mk = { 0 }, .brk = { 0 } }, /* 19f */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 1af */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1be */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1da */ + { .mk = { 0 }, .brk = { 0 } }, /* 1db */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1de */ + { .mk = { 0 }, .brk = { 0 } }, /* 1df */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 1eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fe */ + { .mk = { 0 }, .brk = { 0 } } /* 1ff */ + // clang-format on +}; + +const scancode scancode_set2_at[512] = { + // clang-format off + { .mk = { 0 }, .brk = { 0 } }, /* 000 */ + { .mk = { 0x76, 0 }, .brk = { 0xF0, 0x76, 0 } }, /* 001 */ + { .mk = { 0x16, 0 }, .brk = { 0xF0, 0x16, 0 } }, /* 002 */ + { .mk = { 0x1E, 0 }, .brk = { 0xF0, 0x1E, 0 } }, /* 003 */ + { .mk = { 0x26, 0 }, .brk = { 0xF0, 0x26, 0 } }, /* 004 */ + { .mk = { 0x25, 0 }, .brk = { 0xF0, 0x25, 0 } }, /* 005 */ + { .mk = { 0x2E, 0 }, .brk = { 0xF0, 0x2E, 0 } }, /* 006 */ + { .mk = { 0x36, 0 }, .brk = { 0xF0, 0x36, 0 } }, /* 007 */ + { .mk = { 0x3D, 0 }, .brk = { 0xF0, 0x3D, 0 } }, /* 008 */ + { .mk = { 0x3E, 0 }, .brk = { 0xF0, 0x3E, 0 } }, /* 009 */ + { .mk = { 0x46, 0 }, .brk = { 0xF0, 0x46, 0 } }, /* 00a */ + { .mk = { 0x45, 0 }, .brk = { 0xF0, 0x45, 0 } }, /* 00b */ + { .mk = { 0x4E, 0 }, .brk = { 0xF0, 0x4E, 0 } }, /* 00c */ + { .mk = { 0x55, 0 }, .brk = { 0xF0, 0x55, 0 } }, /* 00d */ + { .mk = { 0x66, 0 }, .brk = { 0xF0, 0x66, 0 } }, /* 00e */ + { .mk = { 0x0D, 0 }, .brk = { 0xF0, 0x0D, 0 } }, /* 00f */ + { .mk = { 0x15, 0 }, .brk = { 0xF0, 0x15, 0 } }, /* 010 */ + { .mk = { 0x1D, 0 }, .brk = { 0xF0, 0x1D, 0 } }, /* 011 */ + { .mk = { 0x24, 0 }, .brk = { 0xF0, 0x24, 0 } }, /* 012 */ + { .mk = { 0x2D, 0 }, .brk = { 0xF0, 0x2D, 0 } }, /* 013 */ + { .mk = { 0x2C, 0 }, .brk = { 0xF0, 0x2C, 0 } }, /* 014 */ + { .mk = { 0x35, 0 }, .brk = { 0xF0, 0x35, 0 } }, /* 015 */ + { .mk = { 0x3C, 0 }, .brk = { 0xF0, 0x3C, 0 } }, /* 016 */ + { .mk = { 0x43, 0 }, .brk = { 0xF0, 0x43, 0 } }, /* 017 */ + { .mk = { 0x44, 0 }, .brk = { 0xF0, 0x44, 0 } }, /* 018 */ + { .mk = { 0x4D, 0 }, .brk = { 0xF0, 0x4D, 0 } }, /* 019 */ + { .mk = { 0x54, 0 }, .brk = { 0xF0, 0x54, 0 } }, /* 01a */ + { .mk = { 0x5B, 0 }, .brk = { 0xF0, 0x5B, 0 } }, /* 01b */ + { .mk = { 0x5A, 0 }, .brk = { 0xF0, 0x5A, 0 } }, /* 01c */ + { .mk = { 0x14, 0 }, .brk = { 0xF0, 0x14, 0 } }, /* 01d */ + { .mk = { 0x1C, 0 }, .brk = { 0xF0, 0x1C, 0 } }, /* 01e */ + { .mk = { 0x1B, 0 }, .brk = { 0xF0, 0x1B, 0 } }, /* 01f */ + { .mk = { 0x23, 0 }, .brk = { 0xF0, 0x23, 0 } }, /* 020 */ + { .mk = { 0x2B, 0 }, .brk = { 0xF0, 0x2B, 0 } }, /* 021 */ + { .mk = { 0x34, 0 }, .brk = { 0xF0, 0x34, 0 } }, /* 022 */ + { .mk = { 0x33, 0 }, .brk = { 0xF0, 0x33, 0 } }, /* 023 */ + { .mk = { 0x3B, 0 }, .brk = { 0xF0, 0x3B, 0 } }, /* 024 */ + { .mk = { 0x42, 0 }, .brk = { 0xF0, 0x42, 0 } }, /* 025 */ + { .mk = { 0x4B, 0 }, .brk = { 0xF0, 0x4B, 0 } }, /* 026 */ + { .mk = { 0x4C, 0 }, .brk = { 0xF0, 0x4C, 0 } }, /* 027 */ + { .mk = { 0x52, 0 }, .brk = { 0xF0, 0x52, 0 } }, /* 028 */ + { .mk = { 0x0E, 0 }, .brk = { 0xF0, 0x0E, 0 } }, /* 029 */ + { .mk = { 0x12, 0 }, .brk = { 0xF0, 0x12, 0 } }, /* 02a */ + { .mk = { 0x5D, 0 }, .brk = { 0xF0, 0x5D, 0 } }, /* 02b */ + { .mk = { 0x1A, 0 }, .brk = { 0xF0, 0x1A, 0 } }, /* 02c */ + { .mk = { 0x22, 0 }, .brk = { 0xF0, 0x22, 0 } }, /* 02d */ + { .mk = { 0x21, 0 }, .brk = { 0xF0, 0x21, 0 } }, /* 02e */ + { .mk = { 0x2A, 0 }, .brk = { 0xF0, 0x2A, 0 } }, /* 02f */ + { .mk = { 0x32, 0 }, .brk = { 0xF0, 0x32, 0 } }, /* 030 */ + { .mk = { 0x31, 0 }, .brk = { 0xF0, 0x31, 0 } }, /* 031 */ + { .mk = { 0x3A, 0 }, .brk = { 0xF0, 0x3A, 0 } }, /* 032 */ + { .mk = { 0x41, 0 }, .brk = { 0xF0, 0x41, 0 } }, /* 033 */ + { .mk = { 0x49, 0 }, .brk = { 0xF0, 0x49, 0 } }, /* 034 */ + { .mk = { 0x4A, 0 }, .brk = { 0xF0, 0x4A, 0 } }, /* 035 */ + { .mk = { 0x59, 0 }, .brk = { 0xF0, 0x59, 0 } }, /* 036 */ + { .mk = { 0x7C, 0 }, .brk = { 0xF0, 0x7C, 0 } }, /* 037 */ + { .mk = { 0x11, 0 }, .brk = { 0xF0, 0x11, 0 } }, /* 038 */ + { .mk = { 0x29, 0 }, .brk = { 0xF0, 0x29, 0 } }, /* 039 */ + { .mk = { 0x58, 0 }, .brk = { 0xF0, 0x58, 0 } }, /* 03a */ + { .mk = { 0x05, 0 }, .brk = { 0xF0, 0x05, 0 } }, /* 03b */ + { .mk = { 0x06, 0 }, .brk = { 0xF0, 0x06, 0 } }, /* 03c */ + { .mk = { 0x04, 0 }, .brk = { 0xF0, 0x04, 0 } }, /* 03d */ + { .mk = { 0x0C, 0 }, .brk = { 0xF0, 0x0C, 0 } }, /* 03e */ + { .mk = { 0x03, 0 }, .brk = { 0xF0, 0x03, 0 } }, /* 03f */ + { .mk = { 0x0B, 0 }, .brk = { 0xF0, 0x0B, 0 } }, /* 040 */ + { .mk = { 0x83, 0 }, .brk = { 0xF0, 0x83, 0 } }, /* 041 */ + { .mk = { 0x0A, 0 }, .brk = { 0xF0, 0x0A, 0 } }, /* 042 */ + { .mk = { 0x01, 0 }, .brk = { 0xF0, 0x01, 0 } }, /* 043 */ + { .mk = { 0x09, 0 }, .brk = { 0xF0, 0x09, 0 } }, /* 044 */ + { .mk = { 0x77, 0 }, .brk = { 0xF0, 0x77, 0 } }, /* 045 */ + { .mk = { 0x7E, 0 }, .brk = { 0xF0, 0x7E, 0 } }, /* 046 */ + { .mk = { 0x6C, 0 }, .brk = { 0xF0, 0x6C, 0 } }, /* 047 */ + { .mk = { 0x75, 0 }, .brk = { 0xF0, 0x75, 0 } }, /* 048 */ + { .mk = { 0x7D, 0 }, .brk = { 0xF0, 0x7D, 0 } }, /* 049 */ + { .mk = { 0x7B, 0 }, .brk = { 0xF0, 0x7B, 0 } }, /* 04a */ + { .mk = { 0x6B, 0 }, .brk = { 0xF0, 0x6B, 0 } }, /* 04b */ + { .mk = { 0x73, 0 }, .brk = { 0xF0, 0x73, 0 } }, /* 04c */ + { .mk = { 0x74, 0 }, .brk = { 0xF0, 0x74, 0 } }, /* 04d */ + { .mk = { 0x79, 0 }, .brk = { 0xF0, 0x79, 0 } }, /* 04e */ + { .mk = { 0x69, 0 }, .brk = { 0xF0, 0x69, 0 } }, /* 04f */ + { .mk = { 0x72, 0 }, .brk = { 0xF0, 0x72, 0 } }, /* 050 */ + { .mk = { 0x7A, 0 }, .brk = { 0xF0, 0x7A, 0 } }, /* 051 */ + { .mk = { 0x70, 0 }, .brk = { 0xF0, 0x70, 0 } }, /* 052 */ + { .mk = { 0x71, 0 }, .brk = { 0xF0, 0x71, 0 } }, /* 053 */ + { .mk = { 0x84, 0 }, .brk = { 0xF0, 0x84, 0 } }, /* 054 */ + { .mk = { 0 }, .brk = { 0 } }, /* 055 */ + { .mk = { 0x61, 0 }, .brk = { 0xF0, 0x61, 0 } }, /* 056 */ + { .mk = { 0 }, .brk = { 0 } }, /* 057 */ + { .mk = { 0 }, .brk = { 0 } }, /* 058 */ + { .mk = { 0 }, .brk = { 0 } }, /* 059 */ + { .mk = { 0 }, .brk = { 0 } }, /* 05a */ + { .mk = { 0 }, .brk = { 0 } }, /* 05b */ + { .mk = { 0x27, 0 }, .brk = { 0xF0, 0x27, 0 } }, /* 05c */ + { .mk = { 0 }, .brk = { 0 } }, /* 05d */ + { .mk = { 0 }, .brk = { 0 } }, /* 05e */ + { .mk = { 0 }, .brk = { 0 } }, /* 05f */ + { .mk = { 0x47, 0 }, .brk = { 0xF0, 0x47, 0 } }, /* 060 */ + { .mk = { 0x4F, 0 }, .brk = { 0xF0, 0x4F, 0 } }, /* 061 */ + { .mk = { 0x56, 0 }, .brk = { 0xF0, 0x56, 0 } }, /* 062 */ + { .mk = { 0x5E, 0 }, .brk = { 0xF0, 0x5E, 0 } }, /* 063 */ + { .mk = { 0x08, 0 }, .brk = { 0xF0, 0x08, 0 } }, /* 064 */ + { .mk = { 0x10, 0 }, .brk = { 0xF0, 0x10, 0 } }, /* 065 */ + { .mk = { 0x18, 0 }, .brk = { 0xF0, 0x18, 0 } }, /* 066 */ + { .mk = { 0x20, 0 }, .brk = { 0xF0, 0x20, 0 } }, /* 067 */ + { .mk = { 0x28, 0 }, .brk = { 0xF0, 0x28, 0 } }, /* 068 */ + { .mk = { 0x30, 0 }, .brk = { 0xF0, 0x30, 0 } }, /* 069 */ + { .mk = { 0x38, 0 }, .brk = { 0xF0, 0x38, 0 } }, /* 06a */ + { .mk = { 0x40, 0 }, .brk = { 0xF0, 0x40, 0 } }, /* 06b */ + { .mk = { 0x48, 0 }, .brk = { 0xF0, 0x48, 0 } }, /* 06c */ + { .mk = { 0x50, 0 }, .brk = { 0xF0, 0x50, 0 } }, /* 06d */ + { .mk = { 0x57, 0 }, .brk = { 0xF0, 0x57, 0 } }, /* 06e */ + { .mk = { 0x6F, 0 }, .brk = { 0xF0, 0x6F, 0 } }, /* 06f */ + { .mk = { 0x13, 0 }, .brk = { 0xF0, 0x13, 0 } }, /* 070 */ + { .mk = { 0x19, 0 }, .brk = { 0xF0, 0x19, 0 } }, /* 071 */ + { .mk = { 0x39, 0 }, .brk = { 0xF0, 0x39, 0 } }, /* 072 */ + { .mk = { 0x51, 0 }, .brk = { 0xF0, 0x51, 0 } }, /* 073 */ + { .mk = { 0x53, 0 }, .brk = { 0xF0, 0x53, 0 } }, /* 074 */ + { .mk = { 0x5C, 0 }, .brk = { 0xF0, 0x5C, 0 } }, /* 075 */ + { .mk = { 0x5F, 0 }, .brk = { 0xF0, 0x5F, 0 } }, /* 076 */ + { .mk = { 0x62, 0 }, .brk = { 0xF0, 0x62, 0 } }, /* 077 */ + { .mk = { 0x63, 0 }, .brk = { 0xF0, 0x63, 0 } }, /* 078 */ + { .mk = { 0x64, 0 }, .brk = { 0xF0, 0x64, 0 } }, /* 079 */ + { .mk = { 0x65, 0 }, .brk = { 0xF0, 0x65, 0 } }, /* 07a */ + { .mk = { 0x67, 0 }, .brk = { 0xF0, 0x67, 0 } }, /* 07b */ + { .mk = { 0x68, 0 }, .brk = { 0xF0, 0x68, 0 } }, /* 07c */ + { .mk = { 0x6A, 0 }, .brk = { 0xF0, 0x6A, 0 } }, /* 07d */ + { .mk = { 0x6D, 0 }, .brk = { 0xF0, 0x6D, 0 } }, /* 07e */ + { .mk = { 0x6E, 0 }, .brk = { 0xF0, 0x6E, 0 } }, /* 07f */ + { .mk = { 0 }, .brk = { 0 } }, /* 080 */ + { .mk = { 0 }, .brk = { 0 } }, /* 081 */ + { .mk = { 0 }, .brk = { 0 } }, /* 082 */ + { .mk = { 0 }, .brk = { 0 } }, /* 083 */ + { .mk = { 0 }, .brk = { 0 } }, /* 084 */ + { .mk = { 0 }, .brk = { 0 } }, /* 085 */ + { .mk = { 0 }, .brk = { 0 } }, /* 086 */ + { .mk = { 0 }, .brk = { 0 } }, /* 087 */ + { .mk = { 0 }, .brk = { 0 } }, /* 088 */ + { .mk = { 0 }, .brk = { 0 } }, /* 089 */ + { .mk = { 0 }, .brk = { 0 } }, /* 08a */ + { .mk = { 0 }, .brk = { 0 } }, /* 08b */ + { .mk = { 0 }, .brk = { 0 } }, /* 08c */ + { .mk = { 0 }, .brk = { 0 } }, /* 08d */ + { .mk = { 0 }, .brk = { 0 } }, /* 08e */ + { .mk = { 0 }, .brk = { 0 } }, /* 08f */ + { .mk = { 0 }, .brk = { 0 } }, /* 090 */ + { .mk = { 0 }, .brk = { 0 } }, /* 091 */ + { .mk = { 0 }, .brk = { 0 } }, /* 092 */ + { .mk = { 0 }, .brk = { 0 } }, /* 093 */ + { .mk = { 0 }, .brk = { 0 } }, /* 094 */ + { .mk = { 0 }, .brk = { 0 } }, /* 095 */ + { .mk = { 0 }, .brk = { 0 } }, /* 096 */ + { .mk = { 0 }, .brk = { 0 } }, /* 097 */ + { .mk = { 0 }, .brk = { 0 } }, /* 098 */ + { .mk = { 0 }, .brk = { 0 } }, /* 099 */ + { .mk = { 0 }, .brk = { 0 } }, /* 09a */ + { .mk = { 0 }, .brk = { 0 } }, /* 09b */ + { .mk = { 0 }, .brk = { 0 } }, /* 09c */ + { .mk = { 0 }, .brk = { 0 } }, /* 09d */ + { .mk = { 0 }, .brk = { 0 } }, /* 09e */ + { .mk = { 0 }, .brk = { 0 } }, /* 09f */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 0af */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0be */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0da */ + { .mk = { 0 }, .brk = { 0 } }, /* 0db */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0de */ + { .mk = { 0 }, .brk = { 0 } }, /* 0df */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 0eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f0 */ + { .mk = { 0xf1, 0 }, .brk = { 0xf0, 0xf1, 0 } }, /* 0f1 */ + { .mk = { 0xf2, 0 }, .brk = { 0xf0, 0xf2, 0 } }, /* 0f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fe */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 100 */ + { .mk = { 0 }, .brk = { 0 } }, /* 101 */ + { .mk = { 0 }, .brk = { 0 } }, /* 102 */ + { .mk = { 0 }, .brk = { 0 } }, /* 103 */ + { .mk = { 0 }, .brk = { 0 } }, /* 104 */ + { .mk = { 0 }, .brk = { 0 } }, /* 105 */ + { .mk = { 0 }, .brk = { 0 } }, /* 106 */ + { .mk = { 0 }, .brk = { 0 } }, /* 107 */ + { .mk = { 0 }, .brk = { 0 } }, /* 108 */ + { .mk = { 0 }, .brk = { 0 } }, /* 109 */ + { .mk = { 0 }, .brk = { 0 } }, /* 10a */ + { .mk = { 0 }, .brk = { 0 } }, /* 10b */ + { .mk = { 0 }, .brk = { 0 } }, /* 10c */ + { .mk = { 0 }, .brk = { 0 } }, /* 10d */ + { .mk = { 0 }, .brk = { 0 } }, /* 10e */ + { .mk = { 0 }, .brk = { 0 } }, /* 10f */ + { .mk = { 0 }, .brk = { 0 } }, /* 110 */ + { .mk = { 0 }, .brk = { 0 } }, /* 111 */ + { .mk = { 0 }, .brk = { 0 } }, /* 112 */ + { .mk = { 0 }, .brk = { 0 } }, /* 113 */ + { .mk = { 0 }, .brk = { 0 } }, /* 114 */ + { .mk = { 0 }, .brk = { 0 } }, /* 115 */ + { .mk = { 0 }, .brk = { 0 } }, /* 116 */ + { .mk = { 0 }, .brk = { 0 } }, /* 117 */ + { .mk = { 0 }, .brk = { 0 } }, /* 118 */ + { .mk = { 0 }, .brk = { 0 } }, /* 119 */ + { .mk = { 0 }, .brk = { 0 } }, /* 11a */ + { .mk = { 0 }, .brk = { 0 } }, /* 11b */ + { .mk = { 0x5A, 0 }, .brk = { 0xF0, 0x5A, 0 } }, /* 11c */ + { .mk = { 0x14, 0 }, .brk = { 0xF0, 0x14, 0 } }, /* 11d */ + { .mk = { 0 }, .brk = { 0 } }, /* 11e */ + { .mk = { 0 }, .brk = { 0 } }, /* 11f */ + { .mk = { 0 }, .brk = { 0 } }, /* 120 */ + { .mk = { 0 }, .brk = { 0 } }, /* 121 */ + { .mk = { 0 }, .brk = { 0 } }, /* 122 */ + { .mk = { 0 }, .brk = { 0 } }, /* 123 */ + { .mk = { 0 }, .brk = { 0 } }, /* 124 */ + { .mk = { 0 }, .brk = { 0 } }, /* 125 */ + { .mk = { 0 }, .brk = { 0 } }, /* 126 */ + { .mk = { 0 }, .brk = { 0 } }, /* 127 */ + { .mk = { 0 }, .brk = { 0 } }, /* 128 */ + { .mk = { 0 }, .brk = { 0 } }, /* 129 */ + { .mk = { 0 }, .brk = { 0 } }, /* 12a */ + { .mk = { 0 }, .brk = { 0 } }, /* 12b */ + { .mk = { 0 }, .brk = { 0 } }, /* 12c */ + { .mk = { 0 }, .brk = { 0 } }, /* 12d */ + { .mk = { 0 }, .brk = { 0 } }, /* 12e */ + { .mk = { 0 }, .brk = { 0 } }, /* 12f */ + { .mk = { 0 }, .brk = { 0 } }, /* 130 */ + { .mk = { 0 }, .brk = { 0 } }, /* 131 */ + { .mk = { 0 }, .brk = { 0 } }, /* 132 */ + { .mk = { 0 }, .brk = { 0 } }, /* 133 */ + { .mk = { 0 }, .brk = { 0 } }, /* 134 */ + { .mk = { 0x4A, 0 }, .brk = { 0xF0, 0x4A, 0 } }, /* 135 */ + { .mk = { 0 }, .brk = { 0 } }, /* 136 */ + { .mk = { 0x7C, 0 }, .brk = { 0xF0, 0x7C, 0 } }, /* 137 */ + { .mk = { 0x11, 0 }, .brk = { 0xF0, 0x11, 0 } }, /* 138 */ + { .mk = { 0 }, .brk = { 0 } }, /* 139 */ + { .mk = { 0 }, .brk = { 0 } }, /* 13a */ + { .mk = { 0 }, .brk = { 0 } }, /* 13b */ + { .mk = { 0 }, .brk = { 0 } }, /* 13c */ + { .mk = { 0 }, .brk = { 0 } }, /* 13d */ + { .mk = { 0 }, .brk = { 0 } }, /* 13e */ + { .mk = { 0 }, .brk = { 0 } }, /* 13f */ + { .mk = { 0 }, .brk = { 0 } }, /* 140 */ + { .mk = { 0 }, .brk = { 0 } }, /* 141 */ + { .mk = { 0 }, .brk = { 0 } }, /* 142 */ + { .mk = { 0 }, .brk = { 0 } }, /* 143 */ + { .mk = { 0 }, .brk = { 0 } }, /* 144 */ + { .mk = { 0 }, .brk = { 0 } }, /* 145 */ + { .mk = { 0x7E, 0 }, .brk = { 0xF0, 0x7E, 0 } }, /* 146 */ + { .mk = { 0x6C, 0 }, .brk = { 0xF0, 0x6C, 0 } }, /* 147 */ + { .mk = { 0x75, 0 }, .brk = { 0xF0, 0x75, 0 } }, /* 148 */ + { .mk = { 0x7D, 0 }, .brk = { 0xF0, 0x7D, 0 } }, /* 149 */ + { .mk = { 0 }, .brk = { 0 } }, /* 14a */ + { .mk = { 0x6B, 0 }, .brk = { 0xF0, 0x6B, 0 } }, /* 14b */ + { .mk = { 0 }, .brk = { 0 } }, /* 14c */ + { .mk = { 0x74, 0 }, .brk = { 0xF0, 0x74, 0 } }, /* 14d */ + { .mk = { 0 }, .brk = { 0 } }, /* 14e */ + { .mk = { 0x69, 0 }, .brk = { 0xF0, 0x69, 0 } }, /* 14f */ + { .mk = { 0x72, 0 }, .brk = { 0xF0, 0x72, 0 } }, /* 150 */ + { .mk = { 0x7A, 0 }, .brk = { 0xF0, 0x7A, 0 } }, /* 151 */ + { .mk = { 0x70, 0 }, .brk = { 0xF0, 0x70, 0 } }, /* 152 */ + { .mk = { 0x71, 0 }, .brk = { 0xF0, 0x71, 0 } }, /* 153 */ + { .mk = { 0 }, .brk = { 0 } }, /* 154 */ + { .mk = { 0 }, .brk = { 0 } }, /* 155 */ + { .mk = { 0 }, .brk = { 0 } }, /* 156 */ + { .mk = { 0 }, .brk = { 0 } }, /* 157 */ + { .mk = { 0 }, .brk = { 0 } }, /* 158 */ + { .mk = { 0 }, .brk = { 0 } }, /* 159 */ + { .mk = { 0 }, .brk = { 0 } }, /* 15a */ + { .mk = { 0x61, 0 }, .brk = { 0xF0, 0x61, 0 } }, /* 15b */ + { .mk = { 0 }, .brk = { 0 } }, /* 15c */ + { .mk = { 0 }, .brk = { 0 } }, /* 15d */ + { .mk = { 0 }, .brk = { 0 } }, /* 15e */ + { .mk = { 0 }, .brk = { 0 } }, /* 15f */ + { .mk = { 0 }, .brk = { 0 } }, /* 160 */ + { .mk = { 0 }, .brk = { 0 } }, /* 161 */ + { .mk = { 0 }, .brk = { 0 } }, /* 162 */ + { .mk = { 0 }, .brk = { 0 } }, /* 163 */ + { .mk = { 0 }, .brk = { 0 } }, /* 164 */ + { .mk = { 0 }, .brk = { 0 } }, /* 165 */ + { .mk = { 0 }, .brk = { 0 } }, /* 166 */ + { .mk = { 0 }, .brk = { 0 } }, /* 167 */ + { .mk = { 0 }, .brk = { 0 } }, /* 168 */ + { .mk = { 0 }, .brk = { 0 } }, /* 169 */ + { .mk = { 0 }, .brk = { 0 } }, /* 16a */ + { .mk = { 0 }, .brk = { 0 } }, /* 16b */ + { .mk = { 0 }, .brk = { 0 } }, /* 16c */ + { .mk = { 0 }, .brk = { 0 } }, /* 16d */ + { .mk = { 0 }, .brk = { 0 } }, /* 16e */ + { .mk = { 0 }, .brk = { 0 } }, /* 16f */ + { .mk = { 0 }, .brk = { 0 } }, /* 170 */ + { .mk = { 0 }, .brk = { 0 } }, /* 171 */ + { .mk = { 0 }, .brk = { 0 } }, /* 172 */ + { .mk = { 0 }, .brk = { 0 } }, /* 173 */ + { .mk = { 0 }, .brk = { 0 } }, /* 174 */ + { .mk = { 0 }, .brk = { 0 } }, /* 175 */ + { .mk = { 0 }, .brk = { 0 } }, /* 176 */ + { .mk = { 0 }, .brk = { 0 } }, /* 177 */ + { .mk = { 0 }, .brk = { 0 } }, /* 178 */ + { .mk = { 0 }, .brk = { 0 } }, /* 179 */ + { .mk = { 0 }, .brk = { 0 } }, /* 17a */ + { .mk = { 0 }, .brk = { 0 } }, /* 17b */ + { .mk = { 0 }, .brk = { 0 } }, /* 17c */ + { .mk = { 0 }, .brk = { 0 } }, /* 17d */ + { .mk = { 0 }, .brk = { 0 } }, /* 17e */ + { .mk = { 0 }, .brk = { 0 } }, /* 17f */ + { .mk = { 0 }, .brk = { 0 } }, /* 180 */ + { .mk = { 0 }, .brk = { 0 } }, /* 181 */ + { .mk = { 0 }, .brk = { 0 } }, /* 182 */ + { .mk = { 0 }, .brk = { 0 } }, /* 183 */ + { .mk = { 0 }, .brk = { 0 } }, /* 184 */ + { .mk = { 0 }, .brk = { 0 } }, /* 185 */ + { .mk = { 0 }, .brk = { 0 } }, /* 186 */ + { .mk = { 0 }, .brk = { 0 } }, /* 187 */ + { .mk = { 0 }, .brk = { 0 } }, /* 188 */ + { .mk = { 0 }, .brk = { 0 } }, /* 189 */ + { .mk = { 0 }, .brk = { 0 } }, /* 18a */ + { .mk = { 0 }, .brk = { 0 } }, /* 18b */ + { .mk = { 0 }, .brk = { 0 } }, /* 18c */ + { .mk = { 0 }, .brk = { 0 } }, /* 18d */ + { .mk = { 0 }, .brk = { 0 } }, /* 18e */ + { .mk = { 0 }, .brk = { 0 } }, /* 18f */ + { .mk = { 0 }, .brk = { 0 } }, /* 190 */ + { .mk = { 0 }, .brk = { 0 } }, /* 191 */ + { .mk = { 0 }, .brk = { 0 } }, /* 192 */ + { .mk = { 0 }, .brk = { 0 } }, /* 193 */ + { .mk = { 0 }, .brk = { 0 } }, /* 194 */ + { .mk = { 0 }, .brk = { 0 } }, /* 195 */ + { .mk = { 0 }, .brk = { 0 } }, /* 196 */ + { .mk = { 0 }, .brk = { 0 } }, /* 197 */ + { .mk = { 0 }, .brk = { 0 } }, /* 198 */ + { .mk = { 0 }, .brk = { 0 } }, /* 199 */ + { .mk = { 0 }, .brk = { 0 } }, /* 19a */ + { .mk = { 0 }, .brk = { 0 } }, /* 19b */ + { .mk = { 0 }, .brk = { 0 } }, /* 19c */ + { .mk = { 0 }, .brk = { 0 } }, /* 19d */ + { .mk = { 0 }, .brk = { 0 } }, /* 19e */ + { .mk = { 0 }, .brk = { 0 } }, /* 19f */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 1af */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1be */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1da */ + { .mk = { 0 }, .brk = { 0 } }, /* 1db */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1de */ + { .mk = { 0 }, .brk = { 0 } }, /* 1df */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 1eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fe */ + { .mk = { 0 }, .brk = { 0 } } /* 1ff */ + // clang-format on +}; + +const scancode scancode_set1_ax[512] = { + // clang-format off + { .mk = { 0 }, .brk = { 0 } }, /* 000 */ + { .mk = { 0x01, 0 }, .brk = { 0x81, 0 } }, /* 001 */ + { .mk = { 0x02, 0 }, .brk = { 0x82, 0 } }, /* 002 */ + { .mk = { 0x03, 0 }, .brk = { 0x83, 0 } }, /* 003 */ + { .mk = { 0x04, 0 }, .brk = { 0x84, 0 } }, /* 004 */ + { .mk = { 0x05, 0 }, .brk = { 0x85, 0 } }, /* 005 */ + { .mk = { 0x06, 0 }, .brk = { 0x86, 0 } }, /* 006 */ + { .mk = { 0x07, 0 }, .brk = { 0x87, 0 } }, /* 007 */ + { .mk = { 0x08, 0 }, .brk = { 0x88, 0 } }, /* 008 */ + { .mk = { 0x09, 0 }, .brk = { 0x89, 0 } }, /* 009 */ + { .mk = { 0x0a, 0 }, .brk = { 0x8a, 0 } }, /* 00a */ + { .mk = { 0x0b, 0 }, .brk = { 0x8b, 0 } }, /* 00b */ + { .mk = { 0x0c, 0 }, .brk = { 0x8c, 0 } }, /* 00c */ + { .mk = { 0x0d, 0 }, .brk = { 0x8d, 0 } }, /* 00d */ + { .mk = { 0x0e, 0 }, .brk = { 0x8e, 0 } }, /* 00e */ + { .mk = { 0x0f, 0 }, .brk = { 0x8f, 0 } }, /* 00f */ + { .mk = { 0x10, 0 }, .brk = { 0x90, 0 } }, /* 010 */ + { .mk = { 0x11, 0 }, .brk = { 0x91, 0 } }, /* 011 */ + { .mk = { 0x12, 0 }, .brk = { 0x92, 0 } }, /* 012 */ + { .mk = { 0x13, 0 }, .brk = { 0x93, 0 } }, /* 013 */ + { .mk = { 0x14, 0 }, .brk = { 0x94, 0 } }, /* 014 */ + { .mk = { 0x15, 0 }, .brk = { 0x95, 0 } }, /* 015 */ + { .mk = { 0x16, 0 }, .brk = { 0x96, 0 } }, /* 016 */ + { .mk = { 0x17, 0 }, .brk = { 0x97, 0 } }, /* 017 */ + { .mk = { 0x18, 0 }, .brk = { 0x98, 0 } }, /* 018 */ + { .mk = { 0x19, 0 }, .brk = { 0x99, 0 } }, /* 019 */ + { .mk = { 0x1a, 0 }, .brk = { 0x9a, 0 } }, /* 01a */ + { .mk = { 0x1b, 0 }, .brk = { 0x9b, 0 } }, /* 01b */ + { .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 01c */ + { .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 01d */ + { .mk = { 0x1e, 0 }, .brk = { 0x9e, 0 } }, /* 01e */ + { .mk = { 0x1f, 0 }, .brk = { 0x9f, 0 } }, /* 01f */ + { .mk = { 0x20, 0 }, .brk = { 0xa0, 0 } }, /* 020 */ + { .mk = { 0x21, 0 }, .brk = { 0xa1, 0 } }, /* 021 */ + { .mk = { 0x22, 0 }, .brk = { 0xa2, 0 } }, /* 022 */ + { .mk = { 0x23, 0 }, .brk = { 0xa3, 0 } }, /* 023 */ + { .mk = { 0x24, 0 }, .brk = { 0xa4, 0 } }, /* 024 */ + { .mk = { 0x25, 0 }, .brk = { 0xa5, 0 } }, /* 025 */ + { .mk = { 0x26, 0 }, .brk = { 0xa6, 0 } }, /* 026 */ + { .mk = { 0x27, 0 }, .brk = { 0xa7, 0 } }, /* 027 */ + { .mk = { 0x28, 0 }, .brk = { 0xa8, 0 } }, /* 028 */ + { .mk = { 0x2b, 0 }, .brk = { 0xab, 0 } }, /* 029 */ + { .mk = { 0x2a, 0 }, .brk = { 0xaa, 0 } }, /* 02a */ + { .mk = { 0x29, 0 }, .brk = { 0xa9, 0 } }, /* 02b */ + { .mk = { 0x2c, 0 }, .brk = { 0xac, 0 } }, /* 02c */ + { .mk = { 0x2d, 0 }, .brk = { 0xad, 0 } }, /* 02d */ + { .mk = { 0x2e, 0 }, .brk = { 0xae, 0 } }, /* 02e */ + { .mk = { 0x2f, 0 }, .brk = { 0xaf, 0 } }, /* 02f */ + { .mk = { 0x30, 0 }, .brk = { 0xb0, 0 } }, /* 030 */ + { .mk = { 0x31, 0 }, .brk = { 0xb1, 0 } }, /* 031 */ + { .mk = { 0x32, 0 }, .brk = { 0xb2, 0 } }, /* 032 */ + { .mk = { 0x33, 0 }, .brk = { 0xb3, 0 } }, /* 033 */ + { .mk = { 0x34, 0 }, .brk = { 0xb4, 0 } }, /* 034 */ + { .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 035 */ + { .mk = { 0x36, 0 }, .brk = { 0xb6, 0 } }, /* 036 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 037 */ + { .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 038 */ + { .mk = { 0x39, 0 }, .brk = { 0xb9, 0 } }, /* 039 */ + { .mk = { 0x3a, 0 }, .brk = { 0xba, 0 } }, /* 03a */ + { .mk = { 0x3b, 0 }, .brk = { 0xbb, 0 } }, /* 03b */ + { .mk = { 0x3c, 0 }, .brk = { 0xbc, 0 } }, /* 03c */ + { .mk = { 0x3d, 0 }, .brk = { 0xbd, 0 } }, /* 03d */ + { .mk = { 0x3e, 0 }, .brk = { 0xbe, 0 } }, /* 03e */ + { .mk = { 0x3f, 0 }, .brk = { 0xbf, 0 } }, /* 03f */ + { .mk = { 0x40, 0 }, .brk = { 0xc0, 0 } }, /* 040 */ + { .mk = { 0x41, 0 }, .brk = { 0xc1, 0 } }, /* 041 */ + { .mk = { 0x42, 0 }, .brk = { 0xc2, 0 } }, /* 042 */ + { .mk = { 0x43, 0 }, .brk = { 0xc3, 0 } }, /* 043 */ + { .mk = { 0x44, 0 }, .brk = { 0xc4, 0 } }, /* 044 */ + { .mk = { 0x45, 0 }, .brk = { 0xc5, 0 } }, /* 045 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 046 */ + { .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 047 */ + { .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 048 */ + { .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 049 */ + { .mk = { 0x4a, 0 }, .brk = { 0xca, 0 } }, /* 04a */ + { .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 04b */ + { .mk = { 0x4c, 0 }, .brk = { 0xcc, 0 } }, /* 04c */ + { .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 04d */ + { .mk = { 0x4e, 0 }, .brk = { 0xce, 0 } }, /* 04e */ + { .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 04f */ + { .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 050 */ + { .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 051 */ + { .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 052 */ + { .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 053 */ + { .mk = { 0x54, 0 }, .brk = { 0xd4, 0 } }, /* 054 */ + { .mk = { 0 }, .brk = { 0 } }, /* 055 */ + { .mk = { 0x56, 0 }, .brk = { 0xd6, 0 } }, /* 054 */ + { .mk = { 0 }, .brk = { 0 } }, /* 057 */ + { .mk = { 0 }, .brk = { 0 } }, /* 058 */ + { .mk = { 0 }, .brk = { 0 } }, /* 059 */ + { .mk = { 0 }, .brk = { 0 } }, /* 05a */ + { .mk = { 0 }, .brk = { 0 } }, /* 05b */ + { .mk = { 0x5c, 0 }, .brk = { 0xdc, 0 } }, /* 05c */ + { .mk = { 0 }, .brk = { 0 } }, /* 05d */ + { .mk = { 0 }, .brk = { 0 } }, /* 05e */ + { .mk = { 0 }, .brk = { 0 } }, /* 05f */ + { .mk = { 0x60, 0 }, .brk = { 0xe0, 0 } }, /* 060 */ + { .mk = { 0x61, 0 }, .brk = { 0xe1, 0 } }, /* 061 */ + { .mk = { 0x62, 0 }, .brk = { 0xe2, 0 } }, /* 062 */ + { .mk = { 0x63, 0 }, .brk = { 0xe3, 0 } }, /* 063 */ + { .mk = { 0x64, 0 }, .brk = { 0xe4, 0 } }, /* 064 */ + { .mk = { 0x65, 0 }, .brk = { 0xe5, 0 } }, /* 065 */ + { .mk = { 0x66, 0 }, .brk = { 0xe6, 0 } }, /* 066 */ + { .mk = { 0x67, 0 }, .brk = { 0xe7, 0 } }, /* 067 */ + { .mk = { 0x68, 0 }, .brk = { 0xe8, 0 } }, /* 068 */ + { .mk = { 0x69, 0 }, .brk = { 0xe9, 0 } }, /* 069 */ + { .mk = { 0x6a, 0 }, .brk = { 0xea, 0 } }, /* 06a */ + { .mk = { 0x6b, 0 }, .brk = { 0xeb, 0 } }, /* 06b */ + { .mk = { 0x6c, 0 }, .brk = { 0xec, 0 } }, /* 06c */ + { .mk = { 0x6d, 0 }, .brk = { 0xed, 0 } }, /* 06d */ + { .mk = { 0x6e, 0 }, .brk = { 0xee, 0 } }, /* 06e */ + { .mk = { 0x6f, 0 }, .brk = { 0xef, 0 } }, /* 06f */ + { .mk = { 0x70, 0 }, .brk = { 0xf0, 0 } }, /* 070 */ + { .mk = { 0x71, 0 }, .brk = { 0xf1, 0 } }, /* 071 */ + { .mk = { 0x72, 0 }, .brk = { 0xf2, 0 } }, /* 072 */ + { .mk = { 0x56, 0 }, .brk = { 0xd6, 0 } }, /* 054 */ + { .mk = { 0x74, 0 }, .brk = { 0xf4, 0 } }, /* 074 */ + { .mk = { 0x75, 0 }, .brk = { 0xf5, 0 } }, /* 075 */ + { .mk = { 0x76, 0 }, .brk = { 0xf6, 0 } }, /* 076 */ + { .mk = { 0x77, 0 }, .brk = { 0xf7, 0 } }, /* 077 */ + { .mk = { 0x78, 0 }, .brk = { 0xf8, 0 } }, /* 078 */ + { .mk = { 0x79, 0 }, .brk = { 0xf9, 0 } }, /* 079 */ + { .mk = { 0x7a, 0 }, .brk = { 0xfa, 0 } }, /* 07a */ + { .mk = { 0x7b, 0 }, .brk = { 0xfb, 0 } }, /* 07b */ + { .mk = { 0x7c, 0 }, .brk = { 0xfc, 0 } }, /* 07c */ + { .mk = { 0x2b, 0 }, .brk = { 0xab, 0 } }, /* 07d */ + { .mk = { 0x7e, 0 }, .brk = { 0xfe, 0 } }, /* 07e */ + { .mk = { 0x7f, 0 }, .brk = { 0xff, 0 } }, /* 07f */ + { .mk = { 0 }, .brk = { 0 } }, /* 080 */ + { .mk = { 0 }, .brk = { 0 } }, /* 081 */ + { .mk = { 0 }, .brk = { 0 } }, /* 082 */ + { .mk = { 0 }, .brk = { 0 } }, /* 083 */ + { .mk = { 0 }, .brk = { 0 } }, /* 084 */ + { .mk = { 0 }, .brk = { 0 } }, /* 085 */ + { .mk = { 0 }, .brk = { 0 } }, /* 086 */ + { .mk = { 0 }, .brk = { 0 } }, /* 087 */ + { .mk = { 0 }, .brk = { 0 } }, /* 088 */ + { .mk = { 0 }, .brk = { 0 } }, /* 089 */ + { .mk = { 0 }, .brk = { 0 } }, /* 08a */ + { .mk = { 0 }, .brk = { 0 } }, /* 08b */ + { .mk = { 0 }, .brk = { 0 } }, /* 08c */ + { .mk = { 0 }, .brk = { 0 } }, /* 08d */ + { .mk = { 0 }, .brk = { 0 } }, /* 08e */ + { .mk = { 0 }, .brk = { 0 } }, /* 08f */ + { .mk = { 0 }, .brk = { 0 } }, /* 090 */ + { .mk = { 0 }, .brk = { 0 } }, /* 091 */ + { .mk = { 0 }, .brk = { 0 } }, /* 092 */ + { .mk = { 0 }, .brk = { 0 } }, /* 093 */ + { .mk = { 0 }, .brk = { 0 } }, /* 094 */ + { .mk = { 0 }, .brk = { 0 } }, /* 095 */ + { .mk = { 0 }, .brk = { 0 } }, /* 096 */ + { .mk = { 0 }, .brk = { 0 } }, /* 097 */ + { .mk = { 0 }, .brk = { 0 } }, /* 098 */ + { .mk = { 0 }, .brk = { 0 } }, /* 099 */ + { .mk = { 0 }, .brk = { 0 } }, /* 09a */ + { .mk = { 0 }, .brk = { 0 } }, /* 09b */ + { .mk = { 0 }, .brk = { 0 } }, /* 09c */ + { .mk = { 0 }, .brk = { 0 } }, /* 09d */ + { .mk = { 0 }, .brk = { 0 } }, /* 09e */ + { .mk = { 0 }, .brk = { 0 } }, /* 09f */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 0af */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0be */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0da */ + { .mk = { 0 }, .brk = { 0 } }, /* 0db */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0de */ + { .mk = { 0 }, .brk = { 0 } }, /* 0df */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 0eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f0 */ + { .mk = { 0xf1, 0 }, .brk = { 0 } }, /* 0f1 */ + { .mk = { 0xf2, 0 }, .brk = { 0 } }, /* 0f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fe */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 100 */ + { .mk = { 0 }, .brk = { 0 } }, /* 101 */ + { .mk = { 0 }, .brk = { 0 } }, /* 102 */ + { .mk = { 0 }, .brk = { 0 } }, /* 103 */ + { .mk = { 0 }, .brk = { 0 } }, /* 104 */ + { .mk = { 0 }, .brk = { 0 } }, /* 105 */ + { .mk = { 0 }, .brk = { 0 } }, /* 106 */ + { .mk = { 0 }, .brk = { 0 } }, /* 107 */ + { .mk = { 0 }, .brk = { 0 } }, /* 108 */ + { .mk = { 0 }, .brk = { 0 } }, /* 109 */ + { .mk = { 0 }, .brk = { 0 } }, /* 10a */ + { .mk = { 0 }, .brk = { 0 } }, /* 10b */ + { .mk = { 0 }, .brk = { 0 } }, /* 10c */ + { .mk = { 0 }, .brk = { 0 } }, /* 10d */ + { .mk = { 0 }, .brk = { 0 } }, /* 10e */ + { .mk = { 0 }, .brk = { 0 } }, /* 10f */ + { .mk = { 0 }, .brk = { 0 } }, /* 110 */ + { .mk = { 0 }, .brk = { 0 } }, /* 111 */ + { .mk = { 0 }, .brk = { 0 } }, /* 112 */ + { .mk = { 0 }, .brk = { 0 } }, /* 113 */ + { .mk = { 0 }, .brk = { 0 } }, /* 114 */ + { .mk = { 0 }, .brk = { 0 } }, /* 115 */ + { .mk = { 0 }, .brk = { 0 } }, /* 116 */ + { .mk = { 0 }, .brk = { 0 } }, /* 117 */ + { .mk = { 0 }, .brk = { 0 } }, /* 118 */ + { .mk = { 0 }, .brk = { 0 } }, /* 119 */ + { .mk = { 0 }, .brk = { 0 } }, /* 11a */ + { .mk = { 0 }, .brk = { 0 } }, /* 11b */ + { .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 11c */ + { .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 11d */ + { .mk = { 0 }, .brk = { 0 } }, /* 11e */ + { .mk = { 0 }, .brk = { 0 } }, /* 11f */ + { .mk = { 0 }, .brk = { 0 } }, /* 120 */ + { .mk = { 0 }, .brk = { 0 } }, /* 121 */ + { .mk = { 0 }, .brk = { 0 } }, /* 122 */ + { .mk = { 0 }, .brk = { 0 } }, /* 123 */ + { .mk = { 0 }, .brk = { 0 } }, /* 124 */ + { .mk = { 0 }, .brk = { 0 } }, /* 125 */ + { .mk = { 0 }, .brk = { 0 } }, /* 126 */ + { .mk = { 0 }, .brk = { 0 } }, /* 127 */ + { .mk = { 0 }, .brk = { 0 } }, /* 128 */ + { .mk = { 0 }, .brk = { 0 } }, /* 129 */ + { .mk = { 0 }, .brk = { 0 } }, /* 12a */ + { .mk = { 0 }, .brk = { 0 } }, /* 12b */ + { .mk = { 0 }, .brk = { 0 } }, /* 12c */ + { .mk = { 0 }, .brk = { 0 } }, /* 12d */ + { .mk = { 0 }, .brk = { 0 } }, /* 12e */ + { .mk = { 0 }, .brk = { 0 } }, /* 12f */ + { .mk = { 0 }, .brk = { 0 } }, /* 130 */ + { .mk = { 0 }, .brk = { 0 } }, /* 131 */ + { .mk = { 0 }, .brk = { 0 } }, /* 132 */ + { .mk = { 0 }, .brk = { 0 } }, /* 133 */ + { .mk = { 0 }, .brk = { 0 } }, /* 134 */ + { .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 135 */ + { .mk = { 0 }, .brk = { 0 } }, /* 136 */ + { .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 137 */ + { .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 138 */ + { .mk = { 0 }, .brk = { 0 } }, /* 139 */ + { .mk = { 0 }, .brk = { 0 } }, /* 13a */ + { .mk = { 0 }, .brk = { 0 } }, /* 13b */ + { .mk = { 0 }, .brk = { 0 } }, /* 13c */ + { .mk = { 0 }, .brk = { 0 } }, /* 13d */ + { .mk = { 0 }, .brk = { 0 } }, /* 13e */ + { .mk = { 0 }, .brk = { 0 } }, /* 13f */ + { .mk = { 0 }, .brk = { 0 } }, /* 140 */ + { .mk = { 0 }, .brk = { 0 } }, /* 141 */ + { .mk = { 0 }, .brk = { 0 } }, /* 142 */ + { .mk = { 0 }, .brk = { 0 } }, /* 143 */ + { .mk = { 0 }, .brk = { 0 } }, /* 144 */ + { .mk = { 0 }, .brk = { 0 } }, /* 145 */ + { .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 146 */ + { .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 147 */ + { .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 148 */ + { .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 149 */ + { .mk = { 0 }, .brk = { 0 } }, /* 14a */ + { .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 14b */ + { .mk = { 0 }, .brk = { 0 } }, /* 14c */ + { .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 14d */ + { .mk = { 0 }, .brk = { 0 } }, /* 14e */ + { .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 14f */ + { .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 150 */ + { .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 151 */ + { .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 152 */ + { .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 153 */ + { .mk = { 0 }, .brk = { 0 } }, /* 154 */ + { .mk = { 0 }, .brk = { 0 } }, /* 155 */ + { .mk = { 0 }, .brk = { 0 } }, /* 156 */ + { .mk = { 0 }, .brk = { 0 } }, /* 157 */ + { .mk = { 0 }, .brk = { 0 } }, /* 158 */ + { .mk = { 0 }, .brk = { 0 } }, /* 159 */ + { .mk = { 0 }, .brk = { 0 } }, /* 15a */ + { .mk = { 0x5c, 0 }, .brk = { 0xdc, 0 } }, /* 15b */ + { .mk = { 0 }, .brk = { 0 } }, /* 15c */ + { .mk = { 0 }, .brk = { 0 } }, /* 15d */ + { .mk = { 0 }, .brk = { 0 } }, /* 15e */ + { .mk = { 0 }, .brk = { 0 } }, /* 15f */ + { .mk = { 0 }, .brk = { 0 } }, /* 160 */ + { .mk = { 0 }, .brk = { 0 } }, /* 161 */ + { .mk = { 0 }, .brk = { 0 } }, /* 162 */ + { .mk = { 0 }, .brk = { 0 } }, /* 163 */ + { .mk = { 0 }, .brk = { 0 } }, /* 164 */ + { .mk = { 0 }, .brk = { 0 } }, /* 165 */ + { .mk = { 0 }, .brk = { 0 } }, /* 166 */ + { .mk = { 0 }, .brk = { 0 } }, /* 167 */ + { .mk = { 0 }, .brk = { 0 } }, /* 168 */ + { .mk = { 0 }, .brk = { 0 } }, /* 169 */ + { .mk = { 0 }, .brk = { 0 } }, /* 16a */ + { .mk = { 0 }, .brk = { 0 } }, /* 16b */ + { .mk = { 0 }, .brk = { 0 } }, /* 16c */ + { .mk = { 0 }, .brk = { 0 } }, /* 16d */ + { .mk = { 0 }, .brk = { 0 } }, /* 16e */ + { .mk = { 0 }, .brk = { 0 } }, /* 16f */ + { .mk = { 0 }, .brk = { 0 } }, /* 170 */ + { .mk = { 0 }, .brk = { 0 } }, /* 171 */ + { .mk = { 0 }, .brk = { 0 } }, /* 172 */ + { .mk = { 0 }, .brk = { 0 } }, /* 173 */ + { .mk = { 0 }, .brk = { 0 } }, /* 174 */ + { .mk = { 0 }, .brk = { 0 } }, /* 175 */ + { .mk = { 0 }, .brk = { 0 } }, /* 176 */ + { .mk = { 0 }, .brk = { 0 } }, /* 177 */ + { .mk = { 0 }, .brk = { 0 } }, /* 178 */ + { .mk = { 0 }, .brk = { 0 } }, /* 179 */ + { .mk = { 0 }, .brk = { 0 } }, /* 17a */ + { .mk = { 0 }, .brk = { 0 } }, /* 17b */ + { .mk = { 0 }, .brk = { 0 } }, /* 17c */ + { .mk = { 0 }, .brk = { 0 } }, /* 17d */ + { .mk = { 0 }, .brk = { 0 } }, /* 17e */ + { .mk = { 0 }, .brk = { 0 } }, /* 17f */ + { .mk = { 0 }, .brk = { 0 } }, /* 180 */ + { .mk = { 0 }, .brk = { 0 } }, /* 181 */ + { .mk = { 0 }, .brk = { 0 } }, /* 182 */ + { .mk = { 0 }, .brk = { 0 } }, /* 183 */ + { .mk = { 0 }, .brk = { 0 } }, /* 184 */ + { .mk = { 0 }, .brk = { 0 } }, /* 185 */ + { .mk = { 0 }, .brk = { 0 } }, /* 186 */ + { .mk = { 0 }, .brk = { 0 } }, /* 187 */ + { .mk = { 0 }, .brk = { 0 } }, /* 188 */ + { .mk = { 0 }, .brk = { 0 } }, /* 189 */ + { .mk = { 0 }, .brk = { 0 } }, /* 18a */ + { .mk = { 0 }, .brk = { 0 } }, /* 18b */ + { .mk = { 0 }, .brk = { 0 } }, /* 18c */ + { .mk = { 0 }, .brk = { 0 } }, /* 18d */ + { .mk = { 0 }, .brk = { 0 } }, /* 18e */ + { .mk = { 0 }, .brk = { 0 } }, /* 18f */ + { .mk = { 0 }, .brk = { 0 } }, /* 190 */ + { .mk = { 0 }, .brk = { 0 } }, /* 191 */ + { .mk = { 0 }, .brk = { 0 } }, /* 192 */ + { .mk = { 0 }, .brk = { 0 } }, /* 193 */ + { .mk = { 0 }, .brk = { 0 } }, /* 194 */ + { .mk = { 0 }, .brk = { 0 } }, /* 195 */ + { .mk = { 0 }, .brk = { 0 } }, /* 196 */ + { .mk = { 0 }, .brk = { 0 } }, /* 197 */ + { .mk = { 0 }, .brk = { 0 } }, /* 198 */ + { .mk = { 0 }, .brk = { 0 } }, /* 199 */ + { .mk = { 0 }, .brk = { 0 } }, /* 19a */ + { .mk = { 0 }, .brk = { 0 } }, /* 19b */ + { .mk = { 0 }, .brk = { 0 } }, /* 19c */ + { .mk = { 0 }, .brk = { 0 } }, /* 19d */ + { .mk = { 0 }, .brk = { 0 } }, /* 19e */ + { .mk = { 0 }, .brk = { 0 } }, /* 19f */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 1af */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1be */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1da */ + { .mk = { 0 }, .brk = { 0 } }, /* 1db */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1de */ + { .mk = { 0 }, .brk = { 0 } }, /* 1df */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 1eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fe */ + { .mk = { 0 }, .brk = { 0 } } /* 1ff */ + // clang-format on +}; + +const scancode scancode_set2_ax[512] = { + // clang-format off + { .mk = { 0 }, .brk = { 0 } }, /* 000 */ + { .mk = { 0x76, 0 }, .brk = { 0xF0, 0x76, 0 } }, /* 001 */ + { .mk = { 0x16, 0 }, .brk = { 0xF0, 0x16, 0 } }, /* 002 */ + { .mk = { 0x1E, 0 }, .brk = { 0xF0, 0x1E, 0 } }, /* 003 */ + { .mk = { 0x26, 0 }, .brk = { 0xF0, 0x26, 0 } }, /* 004 */ + { .mk = { 0x25, 0 }, .brk = { 0xF0, 0x25, 0 } }, /* 005 */ + { .mk = { 0x2E, 0 }, .brk = { 0xF0, 0x2E, 0 } }, /* 006 */ + { .mk = { 0x36, 0 }, .brk = { 0xF0, 0x36, 0 } }, /* 007 */ + { .mk = { 0x3D, 0 }, .brk = { 0xF0, 0x3D, 0 } }, /* 008 */ + { .mk = { 0x3E, 0 }, .brk = { 0xF0, 0x3E, 0 } }, /* 009 */ + { .mk = { 0x46, 0 }, .brk = { 0xF0, 0x46, 0 } }, /* 00a */ + { .mk = { 0x45, 0 }, .brk = { 0xF0, 0x45, 0 } }, /* 00b */ + { .mk = { 0x4E, 0 }, .brk = { 0xF0, 0x4E, 0 } }, /* 00c */ + { .mk = { 0x55, 0 }, .brk = { 0xF0, 0x55, 0 } }, /* 00d */ + { .mk = { 0x66, 0 }, .brk = { 0xF0, 0x66, 0 } }, /* 00e */ + { .mk = { 0x0D, 0 }, .brk = { 0xF0, 0x0D, 0 } }, /* 00f */ + { .mk = { 0x15, 0 }, .brk = { 0xF0, 0x15, 0 } }, /* 010 */ + { .mk = { 0x1D, 0 }, .brk = { 0xF0, 0x1D, 0 } }, /* 011 */ + { .mk = { 0x24, 0 }, .brk = { 0xF0, 0x24, 0 } }, /* 012 */ + { .mk = { 0x2D, 0 }, .brk = { 0xF0, 0x2D, 0 } }, /* 013 */ + { .mk = { 0x2C, 0 }, .brk = { 0xF0, 0x2C, 0 } }, /* 014 */ + { .mk = { 0x35, 0 }, .brk = { 0xF0, 0x35, 0 } }, /* 015 */ + { .mk = { 0x3C, 0 }, .brk = { 0xF0, 0x3C, 0 } }, /* 016 */ + { .mk = { 0x43, 0 }, .brk = { 0xF0, 0x43, 0 } }, /* 017 */ + { .mk = { 0x44, 0 }, .brk = { 0xF0, 0x44, 0 } }, /* 018 */ + { .mk = { 0x4D, 0 }, .brk = { 0xF0, 0x4D, 0 } }, /* 019 */ + { .mk = { 0x54, 0 }, .brk = { 0xF0, 0x54, 0 } }, /* 01a */ + { .mk = { 0x5B, 0 }, .brk = { 0xF0, 0x5B, 0 } }, /* 01b */ + { .mk = { 0x5A, 0 }, .brk = { 0xF0, 0x5A, 0 } }, /* 01c */ + { .mk = { 0x14, 0 }, .brk = { 0xF0, 0x14, 0 } }, /* 01d */ + { .mk = { 0x1C, 0 }, .brk = { 0xF0, 0x1C, 0 } }, /* 01e */ + { .mk = { 0x1B, 0 }, .brk = { 0xF0, 0x1B, 0 } }, /* 01f */ + { .mk = { 0x23, 0 }, .brk = { 0xF0, 0x23, 0 } }, /* 020 */ + { .mk = { 0x2B, 0 }, .brk = { 0xF0, 0x2B, 0 } }, /* 021 */ + { .mk = { 0x34, 0 }, .brk = { 0xF0, 0x34, 0 } }, /* 022 */ + { .mk = { 0x33, 0 }, .brk = { 0xF0, 0x33, 0 } }, /* 023 */ + { .mk = { 0x3B, 0 }, .brk = { 0xF0, 0x3B, 0 } }, /* 024 */ + { .mk = { 0x42, 0 }, .brk = { 0xF0, 0x42, 0 } }, /* 025 */ + { .mk = { 0x4B, 0 }, .brk = { 0xF0, 0x4B, 0 } }, /* 026 */ + { .mk = { 0x4C, 0 }, .brk = { 0xF0, 0x4C, 0 } }, /* 027 */ + { .mk = { 0x52, 0 }, .brk = { 0xF0, 0x52, 0 } }, /* 028 */ + { .mk = { 0x5D, 0 }, .brk = { 0xF0, 0x5D, 0 } }, /* 029 */ + { .mk = { 0x12, 0 }, .brk = { 0xF0, 0x12, 0 } }, /* 02a */ + { .mk = { 0x0E, 0 }, .brk = { 0xF0, 0x0E, 0 } }, /* 02b */ + { .mk = { 0x1A, 0 }, .brk = { 0xF0, 0x1A, 0 } }, /* 02c */ + { .mk = { 0x22, 0 }, .brk = { 0xF0, 0x22, 0 } }, /* 02d */ + { .mk = { 0x21, 0 }, .brk = { 0xF0, 0x21, 0 } }, /* 02e */ + { .mk = { 0x2A, 0 }, .brk = { 0xF0, 0x2A, 0 } }, /* 02f */ + { .mk = { 0x32, 0 }, .brk = { 0xF0, 0x32, 0 } }, /* 030 */ + { .mk = { 0x31, 0 }, .brk = { 0xF0, 0x31, 0 } }, /* 031 */ + { .mk = { 0x3A, 0 }, .brk = { 0xF0, 0x3A, 0 } }, /* 032 */ + { .mk = { 0x41, 0 }, .brk = { 0xF0, 0x41, 0 } }, /* 033 */ + { .mk = { 0x49, 0 }, .brk = { 0xF0, 0x49, 0 } }, /* 034 */ + { .mk = { 0x4A, 0 }, .brk = { 0xF0, 0x4A, 0 } }, /* 035 */ + { .mk = { 0x59, 0 }, .brk = { 0xF0, 0x59, 0 } }, /* 036 */ + { .mk = { 0x7C, 0 }, .brk = { 0xF0, 0x7C, 0 } }, /* 037 */ + { .mk = { 0x11, 0 }, .brk = { 0xF0, 0x11, 0 } }, /* 038 */ + { .mk = { 0x29, 0 }, .brk = { 0xF0, 0x29, 0 } }, /* 039 */ + { .mk = { 0x58, 0 }, .brk = { 0xF0, 0x58, 0 } }, /* 03a */ + { .mk = { 0x05, 0 }, .brk = { 0xF0, 0x05, 0 } }, /* 03b */ + { .mk = { 0x06, 0 }, .brk = { 0xF0, 0x06, 0 } }, /* 03c */ + { .mk = { 0x04, 0 }, .brk = { 0xF0, 0x04, 0 } }, /* 03d */ + { .mk = { 0x0C, 0 }, .brk = { 0xF0, 0x0C, 0 } }, /* 03e */ + { .mk = { 0x03, 0 }, .brk = { 0xF0, 0x03, 0 } }, /* 03f */ + { .mk = { 0x0B, 0 }, .brk = { 0xF0, 0x0B, 0 } }, /* 040 */ + { .mk = { 0x83, 0 }, .brk = { 0xF0, 0x83, 0 } }, /* 041 */ + { .mk = { 0x0A, 0 }, .brk = { 0xF0, 0x0A, 0 } }, /* 042 */ + { .mk = { 0x01, 0 }, .brk = { 0xF0, 0x01, 0 } }, /* 043 */ + { .mk = { 0x09, 0 }, .brk = { 0xF0, 0x09, 0 } }, /* 044 */ + { .mk = { 0x77, 0 }, .brk = { 0xF0, 0x77, 0 } }, /* 045 */ + { .mk = { 0x7E, 0 }, .brk = { 0xF0, 0x7E, 0 } }, /* 046 */ + { .mk = { 0x6C, 0 }, .brk = { 0xF0, 0x6C, 0 } }, /* 047 */ + { .mk = { 0x75, 0 }, .brk = { 0xF0, 0x75, 0 } }, /* 048 */ + { .mk = { 0x7D, 0 }, .brk = { 0xF0, 0x7D, 0 } }, /* 049 */ + { .mk = { 0x7B, 0 }, .brk = { 0xF0, 0x7B, 0 } }, /* 04a */ + { .mk = { 0x6B, 0 }, .brk = { 0xF0, 0x6B, 0 } }, /* 04b */ + { .mk = { 0x73, 0 }, .brk = { 0xF0, 0x73, 0 } }, /* 04c */ + { .mk = { 0x74, 0 }, .brk = { 0xF0, 0x74, 0 } }, /* 04d */ + { .mk = { 0x79, 0 }, .brk = { 0xF0, 0x79, 0 } }, /* 04e */ + { .mk = { 0x69, 0 }, .brk = { 0xF0, 0x69, 0 } }, /* 04f */ + { .mk = { 0x72, 0 }, .brk = { 0xF0, 0x72, 0 } }, /* 050 */ + { .mk = { 0x7A, 0 }, .brk = { 0xF0, 0x7A, 0 } }, /* 051 */ + { .mk = { 0x70, 0 }, .brk = { 0xF0, 0x70, 0 } }, /* 052 */ + { .mk = { 0x71, 0 }, .brk = { 0xF0, 0x71, 0 } }, /* 053 */ + { .mk = { 0x84, 0 }, .brk = { 0xF0, 0x84, 0 } }, /* 054 */ + { .mk = { 0 }, .brk = { 0 } }, /* 055 */ + { .mk = { 0x61, 0 }, .brk = { 0xF0, 0x61, 0 } }, /* 056 */ + { .mk = { 0 }, .brk = { 0 } }, /* 057 */ + { .mk = { 0 }, .brk = { 0 } }, /* 058 */ + { .mk = { 0 }, .brk = { 0 } }, /* 059 */ + { .mk = { 0 }, .brk = { 0 } }, /* 05a */ + { .mk = { 0 }, .brk = { 0 } }, /* 05b */ + { .mk = { 0x27, 0 }, .brk = { 0xF0, 0x27, 0 } }, /* 05c */ + { .mk = { 0 }, .brk = { 0 } }, /* 05d */ + { .mk = { 0 }, .brk = { 0 } }, /* 05e */ + { .mk = { 0 }, .brk = { 0 } }, /* 05f */ + { .mk = { 0x47, 0 }, .brk = { 0xF0, 0x47, 0 } }, /* 060 */ + { .mk = { 0x4F, 0 }, .brk = { 0xF0, 0x4F, 0 } }, /* 061 */ + { .mk = { 0x56, 0 }, .brk = { 0xF0, 0x56, 0 } }, /* 062 */ + { .mk = { 0x5E, 0 }, .brk = { 0xF0, 0x5E, 0 } }, /* 063 */ + { .mk = { 0x08, 0 }, .brk = { 0xF0, 0x08, 0 } }, /* 064 */ + { .mk = { 0x10, 0 }, .brk = { 0xF0, 0x10, 0 } }, /* 065 */ + { .mk = { 0x18, 0 }, .brk = { 0xF0, 0x18, 0 } }, /* 066 */ + { .mk = { 0x20, 0 }, .brk = { 0xF0, 0x20, 0 } }, /* 067 */ + { .mk = { 0x28, 0 }, .brk = { 0xF0, 0x28, 0 } }, /* 068 */ + { .mk = { 0x30, 0 }, .brk = { 0xF0, 0x30, 0 } }, /* 069 */ + { .mk = { 0x38, 0 }, .brk = { 0xF0, 0x38, 0 } }, /* 06a */ + { .mk = { 0x40, 0 }, .brk = { 0xF0, 0x40, 0 } }, /* 06b */ + { .mk = { 0x48, 0 }, .brk = { 0xF0, 0x48, 0 } }, /* 06c */ + { .mk = { 0x50, 0 }, .brk = { 0xF0, 0x50, 0 } }, /* 06d */ + { .mk = { 0x57, 0 }, .brk = { 0xF0, 0x57, 0 } }, /* 06e */ + { .mk = { 0x6F, 0 }, .brk = { 0xF0, 0x6F, 0 } }, /* 06f */ + { .mk = { 0x13, 0 }, .brk = { 0xF0, 0x13, 0 } }, /* 070 */ + { .mk = { 0x19, 0 }, .brk = { 0xF0, 0x19, 0 } }, /* 071 */ + { .mk = { 0x39, 0 }, .brk = { 0xF0, 0x39, 0 } }, /* 072 */ + { .mk = { 0x5D, 0 }, .brk = { 0xF0, 0x5D, 0 } }, /* 073 */ + { .mk = { 0x53, 0 }, .brk = { 0xF0, 0x53, 0 } }, /* 074 */ + { .mk = { 0x5C, 0 }, .brk = { 0xF0, 0x5C, 0 } }, /* 075 */ + { .mk = { 0x5F, 0 }, .brk = { 0xF0, 0x5F, 0 } }, /* 076 */ + { .mk = { 0x62, 0 }, .brk = { 0xF0, 0x62, 0 } }, /* 077 */ + { .mk = { 0x63, 0 }, .brk = { 0xF0, 0x63, 0 } }, /* 078 */ + { .mk = { 0x64, 0 }, .brk = { 0xF0, 0x64, 0 } }, /* 079 */ + { .mk = { 0x65, 0 }, .brk = { 0xF0, 0x65, 0 } }, /* 07a */ + { .mk = { 0x67, 0 }, .brk = { 0xF0, 0x67, 0 } }, /* 07b */ + { .mk = { 0x68, 0 }, .brk = { 0xF0, 0x68, 0 } }, /* 07c */ + { .mk = { 0x61, 0 }, .brk = { 0xF0, 0x61, 0 } }, /* 07d */ + { .mk = { 0x6D, 0 }, .brk = { 0xF0, 0x6D, 0 } }, /* 07e */ + { .mk = { 0x6E, 0 }, .brk = { 0xF0, 0x6E, 0 } }, /* 07f */ + { .mk = { 0 }, .brk = { 0 } }, /* 080 */ + { .mk = { 0 }, .brk = { 0 } }, /* 081 */ + { .mk = { 0 }, .brk = { 0 } }, /* 082 */ + { .mk = { 0 }, .brk = { 0 } }, /* 083 */ + { .mk = { 0 }, .brk = { 0 } }, /* 084 */ + { .mk = { 0 }, .brk = { 0 } }, /* 085 */ + { .mk = { 0 }, .brk = { 0 } }, /* 086 */ + { .mk = { 0 }, .brk = { 0 } }, /* 087 */ + { .mk = { 0 }, .brk = { 0 } }, /* 088 */ + { .mk = { 0 }, .brk = { 0 } }, /* 089 */ + { .mk = { 0 }, .brk = { 0 } }, /* 08a */ + { .mk = { 0 }, .brk = { 0 } }, /* 08b */ + { .mk = { 0 }, .brk = { 0 } }, /* 08c */ + { .mk = { 0 }, .brk = { 0 } }, /* 08d */ + { .mk = { 0 }, .brk = { 0 } }, /* 08e */ + { .mk = { 0 }, .brk = { 0 } }, /* 08f */ + { .mk = { 0 }, .brk = { 0 } }, /* 090 */ + { .mk = { 0 }, .brk = { 0 } }, /* 091 */ + { .mk = { 0 }, .brk = { 0 } }, /* 092 */ + { .mk = { 0 }, .brk = { 0 } }, /* 093 */ + { .mk = { 0 }, .brk = { 0 } }, /* 094 */ + { .mk = { 0 }, .brk = { 0 } }, /* 095 */ + { .mk = { 0 }, .brk = { 0 } }, /* 096 */ + { .mk = { 0 }, .brk = { 0 } }, /* 097 */ + { .mk = { 0 }, .brk = { 0 } }, /* 098 */ + { .mk = { 0 }, .brk = { 0 } }, /* 099 */ + { .mk = { 0 }, .brk = { 0 } }, /* 09a */ + { .mk = { 0 }, .brk = { 0 } }, /* 09b */ + { .mk = { 0 }, .brk = { 0 } }, /* 09c */ + { .mk = { 0 }, .brk = { 0 } }, /* 09d */ + { .mk = { 0 }, .brk = { 0 } }, /* 09e */ + { .mk = { 0 }, .brk = { 0 } }, /* 09f */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 0af */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0be */ + { .mk = { 0 }, .brk = { 0 } }, /* 0bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 0cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0da */ + { .mk = { 0 }, .brk = { 0 } }, /* 0db */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0de */ + { .mk = { 0 }, .brk = { 0 } }, /* 0df */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 0eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f0 */ + { .mk = { 0xf1, 0 }, .brk = { 0xf0, 0xf1, 0 } }, /* 0f1 */ + { .mk = { 0xf2, 0 }, .brk = { 0xf0, 0xf2, 0 } }, /* 0f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 0fe */ + { .mk = { 0 }, .brk = { 0 } }, /* 0ff */ + { .mk = { 0 }, .brk = { 0 } }, /* 100 */ + { .mk = { 0 }, .brk = { 0 } }, /* 101 */ + { .mk = { 0 }, .brk = { 0 } }, /* 102 */ + { .mk = { 0 }, .brk = { 0 } }, /* 103 */ + { .mk = { 0 }, .brk = { 0 } }, /* 104 */ + { .mk = { 0 }, .brk = { 0 } }, /* 105 */ + { .mk = { 0 }, .brk = { 0 } }, /* 106 */ + { .mk = { 0 }, .brk = { 0 } }, /* 107 */ + { .mk = { 0 }, .brk = { 0 } }, /* 108 */ + { .mk = { 0 }, .brk = { 0 } }, /* 109 */ + { .mk = { 0 }, .brk = { 0 } }, /* 10a */ + { .mk = { 0 }, .brk = { 0 } }, /* 10b */ + { .mk = { 0 }, .brk = { 0 } }, /* 10c */ + { .mk = { 0 }, .brk = { 0 } }, /* 10d */ + { .mk = { 0 }, .brk = { 0 } }, /* 10e */ + { .mk = { 0 }, .brk = { 0 } }, /* 10f */ + { .mk = { 0 }, .brk = { 0 } }, /* 110 */ + { .mk = { 0 }, .brk = { 0 } }, /* 111 */ + { .mk = { 0 }, .brk = { 0 } }, /* 112 */ + { .mk = { 0 }, .brk = { 0 } }, /* 113 */ + { .mk = { 0 }, .brk = { 0 } }, /* 114 */ + { .mk = { 0 }, .brk = { 0 } }, /* 115 */ + { .mk = { 0 }, .brk = { 0 } }, /* 116 */ + { .mk = { 0 }, .brk = { 0 } }, /* 117 */ + { .mk = { 0 }, .brk = { 0 } }, /* 118 */ + { .mk = { 0 }, .brk = { 0 } }, /* 119 */ + { .mk = { 0 }, .brk = { 0 } }, /* 11a */ + { .mk = { 0 }, .brk = { 0 } }, /* 11b */ + { .mk = { 0x5A, 0 }, .brk = { 0xF0, 0x5A, 0 } }, /* 11c */ + { .mk = { 0x14, 0 }, .brk = { 0xF0, 0x14, 0 } }, /* 11d */ + { .mk = { 0 }, .brk = { 0 } }, /* 11e */ + { .mk = { 0 }, .brk = { 0 } }, /* 11f */ + { .mk = { 0 }, .brk = { 0 } }, /* 120 */ + { .mk = { 0 }, .brk = { 0 } }, /* 121 */ + { .mk = { 0 }, .brk = { 0 } }, /* 122 */ + { .mk = { 0 }, .brk = { 0 } }, /* 123 */ + { .mk = { 0 }, .brk = { 0 } }, /* 124 */ + { .mk = { 0 }, .brk = { 0 } }, /* 125 */ + { .mk = { 0 }, .brk = { 0 } }, /* 126 */ + { .mk = { 0 }, .brk = { 0 } }, /* 127 */ + { .mk = { 0 }, .brk = { 0 } }, /* 128 */ + { .mk = { 0 }, .brk = { 0 } }, /* 129 */ + { .mk = { 0 }, .brk = { 0 } }, /* 12a */ + { .mk = { 0 }, .brk = { 0 } }, /* 12b */ + { .mk = { 0 }, .brk = { 0 } }, /* 12c */ + { .mk = { 0 }, .brk = { 0 } }, /* 12d */ + { .mk = { 0 }, .brk = { 0 } }, /* 12e */ + { .mk = { 0 }, .brk = { 0 } }, /* 12f */ + { .mk = { 0 }, .brk = { 0 } }, /* 130 */ + { .mk = { 0 }, .brk = { 0 } }, /* 131 */ + { .mk = { 0 }, .brk = { 0 } }, /* 132 */ + { .mk = { 0 }, .brk = { 0 } }, /* 133 */ + { .mk = { 0 }, .brk = { 0 } }, /* 134 */ + { .mk = { 0x4A, 0 }, .brk = { 0xF0, 0x4A, 0 } }, /* 135 */ + { .mk = { 0 }, .brk = { 0 } }, /* 136 */ + { .mk = { 0x7C, 0 }, .brk = { 0xF0, 0x7C, 0 } }, /* 137 */ + { .mk = { 0x11, 0 }, .brk = { 0xF0, 0x11, 0 } }, /* 138 */ + { .mk = { 0 }, .brk = { 0 } }, /* 139 */ + { .mk = { 0 }, .brk = { 0 } }, /* 13a */ + { .mk = { 0 }, .brk = { 0 } }, /* 13b */ + { .mk = { 0 }, .brk = { 0 } }, /* 13c */ + { .mk = { 0 }, .brk = { 0 } }, /* 13d */ + { .mk = { 0 }, .brk = { 0 } }, /* 13e */ + { .mk = { 0 }, .brk = { 0 } }, /* 13f */ + { .mk = { 0 }, .brk = { 0 } }, /* 140 */ + { .mk = { 0 }, .brk = { 0 } }, /* 141 */ + { .mk = { 0 }, .brk = { 0 } }, /* 142 */ + { .mk = { 0 }, .brk = { 0 } }, /* 143 */ + { .mk = { 0 }, .brk = { 0 } }, /* 144 */ + { .mk = { 0 }, .brk = { 0 } }, /* 145 */ + { .mk = { 0x7E, 0 }, .brk = { 0xF0, 0x7E, 0 } }, /* 146 */ + { .mk = { 0x6C, 0 }, .brk = { 0xF0, 0x6C, 0 } }, /* 147 */ + { .mk = { 0x75, 0 }, .brk = { 0xF0, 0x75, 0 } }, /* 148 */ + { .mk = { 0x7D, 0 }, .brk = { 0xF0, 0x7D, 0 } }, /* 149 */ + { .mk = { 0 }, .brk = { 0 } }, /* 14a */ + { .mk = { 0x6B, 0 }, .brk = { 0xF0, 0x6B, 0 } }, /* 14b */ + { .mk = { 0 }, .brk = { 0 } }, /* 14c */ + { .mk = { 0x74, 0 }, .brk = { 0xF0, 0x74, 0 } }, /* 14d */ + { .mk = { 0 }, .brk = { 0 } }, /* 14e */ + { .mk = { 0x69, 0 }, .brk = { 0xF0, 0x69, 0 } }, /* 14f */ + { .mk = { 0x72, 0 }, .brk = { 0xF0, 0x72, 0 } }, /* 150 */ + { .mk = { 0x7A, 0 }, .brk = { 0xF0, 0x7A, 0 } }, /* 151 */ + { .mk = { 0x70, 0 }, .brk = { 0xF0, 0x70, 0 } }, /* 152 */ + { .mk = { 0x71, 0 }, .brk = { 0xF0, 0x71, 0 } }, /* 153 */ + { .mk = { 0 }, .brk = { 0 } }, /* 154 */ + { .mk = { 0 }, .brk = { 0 } }, /* 155 */ + { .mk = { 0 }, .brk = { 0 } }, /* 156 */ + { .mk = { 0 }, .brk = { 0 } }, /* 157 */ + { .mk = { 0 }, .brk = { 0 } }, /* 158 */ + { .mk = { 0 }, .brk = { 0 } }, /* 159 */ + { .mk = { 0 }, .brk = { 0 } }, /* 15a */ + { .mk = { 0x27, 0 }, .brk = { 0xF0, 0x27, 0 } }, /* 15b */ + { .mk = { 0 }, .brk = { 0 } }, /* 15c */ + { .mk = { 0 }, .brk = { 0 } }, /* 15d */ + { .mk = { 0 }, .brk = { 0 } }, /* 15e */ + { .mk = { 0 }, .brk = { 0 } }, /* 15f */ + { .mk = { 0 }, .brk = { 0 } }, /* 160 */ + { .mk = { 0 }, .brk = { 0 } }, /* 161 */ + { .mk = { 0 }, .brk = { 0 } }, /* 162 */ + { .mk = { 0 }, .brk = { 0 } }, /* 163 */ + { .mk = { 0 }, .brk = { 0 } }, /* 164 */ + { .mk = { 0 }, .brk = { 0 } }, /* 165 */ + { .mk = { 0 }, .brk = { 0 } }, /* 166 */ + { .mk = { 0 }, .brk = { 0 } }, /* 167 */ + { .mk = { 0 }, .brk = { 0 } }, /* 168 */ + { .mk = { 0 }, .brk = { 0 } }, /* 169 */ + { .mk = { 0 }, .brk = { 0 } }, /* 16a */ + { .mk = { 0 }, .brk = { 0 } }, /* 16b */ + { .mk = { 0 }, .brk = { 0 } }, /* 16c */ + { .mk = { 0 }, .brk = { 0 } }, /* 16d */ + { .mk = { 0 }, .brk = { 0 } }, /* 16e */ + { .mk = { 0 }, .brk = { 0 } }, /* 16f */ + { .mk = { 0 }, .brk = { 0 } }, /* 170 */ + { .mk = { 0 }, .brk = { 0 } }, /* 171 */ + { .mk = { 0 }, .brk = { 0 } }, /* 172 */ + { .mk = { 0 }, .brk = { 0 } }, /* 173 */ + { .mk = { 0 }, .brk = { 0 } }, /* 174 */ + { .mk = { 0 }, .brk = { 0 } }, /* 175 */ + { .mk = { 0 }, .brk = { 0 } }, /* 176 */ + { .mk = { 0 }, .brk = { 0 } }, /* 177 */ + { .mk = { 0 }, .brk = { 0 } }, /* 178 */ + { .mk = { 0 }, .brk = { 0 } }, /* 179 */ + { .mk = { 0 }, .brk = { 0 } }, /* 17a */ + { .mk = { 0 }, .brk = { 0 } }, /* 17b */ + { .mk = { 0 }, .brk = { 0 } }, /* 17c */ + { .mk = { 0 }, .brk = { 0 } }, /* 17d */ + { .mk = { 0 }, .brk = { 0 } }, /* 17e */ + { .mk = { 0 }, .brk = { 0 } }, /* 17f */ + { .mk = { 0 }, .brk = { 0 } }, /* 180 */ + { .mk = { 0 }, .brk = { 0 } }, /* 181 */ + { .mk = { 0 }, .brk = { 0 } }, /* 182 */ + { .mk = { 0 }, .brk = { 0 } }, /* 183 */ + { .mk = { 0 }, .brk = { 0 } }, /* 184 */ + { .mk = { 0 }, .brk = { 0 } }, /* 185 */ + { .mk = { 0 }, .brk = { 0 } }, /* 186 */ + { .mk = { 0 }, .brk = { 0 } }, /* 187 */ + { .mk = { 0 }, .brk = { 0 } }, /* 188 */ + { .mk = { 0 }, .brk = { 0 } }, /* 189 */ + { .mk = { 0 }, .brk = { 0 } }, /* 18a */ + { .mk = { 0 }, .brk = { 0 } }, /* 18b */ + { .mk = { 0 }, .brk = { 0 } }, /* 18c */ + { .mk = { 0 }, .brk = { 0 } }, /* 18d */ + { .mk = { 0 }, .brk = { 0 } }, /* 18e */ + { .mk = { 0 }, .brk = { 0 } }, /* 18f */ + { .mk = { 0 }, .brk = { 0 } }, /* 190 */ + { .mk = { 0 }, .brk = { 0 } }, /* 191 */ + { .mk = { 0 }, .brk = { 0 } }, /* 192 */ + { .mk = { 0 }, .brk = { 0 } }, /* 193 */ + { .mk = { 0 }, .brk = { 0 } }, /* 194 */ + { .mk = { 0 }, .brk = { 0 } }, /* 195 */ + { .mk = { 0 }, .brk = { 0 } }, /* 196 */ + { .mk = { 0 }, .brk = { 0 } }, /* 197 */ + { .mk = { 0 }, .brk = { 0 } }, /* 198 */ + { .mk = { 0 }, .brk = { 0 } }, /* 199 */ + { .mk = { 0 }, .brk = { 0 } }, /* 19a */ + { .mk = { 0 }, .brk = { 0 } }, /* 19b */ + { .mk = { 0 }, .brk = { 0 } }, /* 19c */ + { .mk = { 0 }, .brk = { 0 } }, /* 19d */ + { .mk = { 0 }, .brk = { 0 } }, /* 19e */ + { .mk = { 0 }, .brk = { 0 } }, /* 19f */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1a9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1aa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ab */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ac */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ad */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ae */ + { .mk = { 0 }, .brk = { 0 } }, /* 1af */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1b9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ba */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1be */ + { .mk = { 0 }, .brk = { 0 } }, /* 1bf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1c9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ca */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ce */ + { .mk = { 0 }, .brk = { 0 } }, /* 1cf */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1d9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1da */ + { .mk = { 0 }, .brk = { 0 } }, /* 1db */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1dd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1de */ + { .mk = { 0 }, .brk = { 0 } }, /* 1df */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1e9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ea */ + { .mk = { 0 }, .brk = { 0 } }, /* 1eb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ec */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ed */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ee */ + { .mk = { 0 }, .brk = { 0 } }, /* 1ef */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f0 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f1 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f2 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f3 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f4 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f5 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f6 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f7 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f8 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1f9 */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fa */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fb */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fc */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fd */ + { .mk = { 0 }, .brk = { 0 } }, /* 1fe */ + { .mk = { 0 }, .brk = { 0 } } /* 1ff */ + // clang-format on +}; + +const scancode scancode_set1[512] = { // clang-format off { .mk = { 0 }, .brk = { 0 } }, /* 000 */ { .mk = { 0x01, 0 }, .brk = { 0x81, 0 } }, /* 001 */ @@ -428,11 +2494,11 @@ static const scancode scancode_set1[512] = { { .mk = {0xe0, 0x57, 0 }, .brk = { 0xe0, 0xd7, 0 } }, /* 157 */ { .mk = {0xe0, 0x58, 0 }, .brk = { 0xe0, 0xd8, 0 } }, /* 158 */ { .mk = {0xe0, 0x59, 0 }, .brk = { 0xe0, 0xd9, 0 } }, /* 159 */ - { .mk = {0xe0, 0x5a, 0 }, .brk = { 0xe0, 0xaa, 0 } }, /* 15a */ + { .mk = {0xe0, 0x5a, 0 }, .brk = { 0xe0, 0xda, 0 } }, /* 15a */ { .mk = {0xe0, 0x5b, 0 }, .brk = { 0xe0, 0xdb, 0 } }, /* 15b */ { .mk = {0xe0, 0x5c, 0 }, .brk = { 0xe0, 0xdc, 0 } }, /* 15c */ { .mk = {0xe0, 0x5d, 0 }, .brk = { 0xe0, 0xdd, 0 } }, /* 15d */ - { .mk = {0xe0, 0x5e, 0 }, .brk = { 0xe0, 0xee, 0 } }, /* 15e */ + { .mk = {0xe0, 0x5e, 0 }, .brk = { 0xe0, 0xde, 0 } }, /* 15e */ { .mk = {0xe0, 0x5f, 0 }, .brk = { 0xe0, 0xdf, 0 } }, /* 15f */ { .mk = { 0 }, .brk = { 0 } }, /* 160 */ { .mk = {0xe0, 0x61, 0 }, .brk = { 0xe0, 0xe1, 0 } }, /* 161 */ @@ -1159,7 +3225,7 @@ static const scancode scancode_set3[512] = { { .mk = { 0x52, 0 }, .brk = { 0xf0, 0x52, 0 } }, /* 028 */ { .mk = { 0x0E, 0 }, .brk = { 0xf0, 0x0E, 0 } }, /* 029 */ { .mk = { 0x12, 0 }, .brk = { 0xf0, 0x12, 0 } }, /* 02a */ - { .mk = { 0x5C, 0 }, .brk = { 0xf0, 0x5C, 0 } }, /* 02b */ + { .mk = {0x8c, 0x2B, 0 }, .brk = { 0xf0, 0x8c, 0x2B, 0 } }, /* 02b */ { .mk = { 0x1A, 0 }, .brk = { 0xf0, 0x1A, 0 } }, /* 02c */ { .mk = { 0x22, 0 }, .brk = { 0xf0, 0x22, 0 } }, /* 02d */ { .mk = { 0x21, 0 }, .brk = { 0xf0, 0x21, 0 } }, /* 02e */ @@ -1202,7 +3268,7 @@ static const scancode scancode_set3[512] = { { .mk = { 0x71, 0 }, .brk = { 0xf0, 0x71, 0 } }, /* 053 */ { .mk = { 0x57, 0 }, .brk = { 0xf0, 0x57, 0 } }, /* 054 */ { .mk = { 0x60, 0 }, .brk = { 0xf0, 0x60, 0 } }, /* 055 */ - { .mk = { 0 }, .brk = { 0 } }, /* 056 */ + { .mk = {0x8c, 0x56, 0 }, .brk = { 0xf0, 0x8c, 0x56, 0 } }, /* 056 */ { .mk = { 0x56, 0 }, .brk = { 0xf0, 0x56, 0 } }, /* 057 */ { .mk = { 0x5E, 0 }, .brk = { 0xf0, 0x5E, 0 } }, /* 058 */ { .mk = { 0 }, .brk = { 0 } }, /* 059 */ @@ -1228,20 +3294,20 @@ static const scancode scancode_set3[512] = { { .mk = { 0x50, 0 }, .brk = { 0xf0, 0x50, 0 } }, /* 06d */ { .mk = { 0 }, .brk = { 0 } }, /* 06e */ { .mk = { 0 }, .brk = { 0 } }, /* 06f */ - { .mk = { 0x87, 0 }, .brk = { 0xf0, 0x87, 0 } }, /* 070 */ + { .mk = {0x8c, 0x70, 0 }, .brk = { 0xf0, 0x8c, 0x70, 0 } }, /* 07d */ { .mk = { 0 }, .brk = { 0 } }, /* 071 */ { .mk = { 0 }, .brk = { 0 } }, /* 072 */ - { .mk = { 0x51, 0 }, .brk = { 0xf0, 0x51, 0 } }, /* 073 */ + { .mk = {0x8c, 0x73, 0 }, .brk = { 0xf0, 0x8c, 0x73, 0 } }, /* 073 */ { .mk = { 0x53, 0 }, .brk = { 0xf0, 0x53, 0 } }, /* 074 */ { .mk = { 0x5C, 0 }, .brk = { 0xf0, 0x5C, 0 } }, /* 075 */ { .mk = { 0 }, .brk = { 0 } }, /* 076 */ { .mk = { 0x62, 0 }, .brk = { 0xf0, 0x62, 0 } }, /* 077 */ { .mk = { 0x63, 0 }, .brk = { 0xf0, 0x63, 0 } }, /* 078 */ - { .mk = { 0x86, 0 }, .brk = { 0xf0, 0x86, 0 } }, /* 079 */ + { .mk = {0x8c, 0x79, 0 }, .brk = { 0xf0, 0x8c, 0x79, 0 } }, /* 079 */ { .mk = { 0 }, .brk = { 0 } }, /* 07a */ - { .mk = { 0x85, 0 }, .brk = { 0xf0, 0x85, 0 } }, /* 07b */ + { .mk = {0x8c, 0x7b, 0 }, .brk = { 0xf0, 0x8c, 0x7b, 0 } }, /* 07b */ { .mk = { 0x68, 0 }, .brk = { 0xf0, 0x68, 0 } }, /* 07c */ - { .mk = { 0x13, 0 }, .brk = { 0xf0, 0x13, 0 } }, /* 07d */ + { .mk = {0x8c, 0x7d, 0 }, .brk = { 0xf0, 0x8c, 0x7d, 0 } }, /* 07d */ { .mk = { 0 }, .brk = { 0 } }, /* 07e */ { .mk = { 0 }, .brk = { 0 } }, /* 07f */ { .mk = { 0x80, 0 }, .brk = { 0xf0, 0x80, 0 } }, /* 080 */ @@ -3229,16 +5295,26 @@ keyboard_at_log(const char *fmt, ...) #endif static void -keyboard_at_set_scancode_set(void) +keyboard_at_set_scancode_set(atkbc_dev_t *dev) { switch (keyboard_mode) { default: case 0x01: - keyboard_set_table(scancode_set1); + if (dev->type & FLAG_AX) + keyboard_set_table(scancode_set1_ax); + else if ((dev->type & FLAG_TYPE_MASK) > KBD_84_KEY) + keyboard_set_table(scancode_set1); + else + keyboard_set_table(scancode_set1_at); break; case 0x02: - keyboard_set_table(scancode_set2); + if (dev->type & FLAG_AX) + keyboard_set_table(scancode_set2_ax); + else if ((dev->type & FLAG_TYPE_MASK) > KBD_84_KEY) + keyboard_set_table(scancode_set2); + else + keyboard_set_table(scancode_set2_at); break; case 0x03: @@ -3274,9 +5350,92 @@ add_data_kbd(uint16_t val) uint8_t num_lock = 0; uint8_t shift_states = 0; + if ((keyboard_mode == 0x03) && (val == 0x8c)) { + is_special = 1; + return; + } else if (is_special) { + uint8_t keys = (dev->type & FLAG_TYPE_MASK); + + switch (val) { + case 0x2b: + switch (keys) { + default: + val = 0x5c; + break; + case KBD_102_KEY: case KBD_JIS: + case KBD_ABNT2: + val = 0x53; + break; + } + break; + case 0x56: + switch (keys) { + default: + val = 0x12; + break; + case KBD_102_KEY: case KBD_ABNT2: + val = 0x13; + break; + } + break; + case 0x70: + switch (keys) { + default: + val = 0x29; + break; + case KBD_JIS: + val = 0x87; + break; + } + break; + case 0x73: + switch (keys) { + default: + val = 0x59; + break; + case KBD_JIS: case KBD_ABNT2: + val = 0x5c; + break; + } + break; + case 0x79: + switch (keys) { + default: + val = 0x29; + break; + case KBD_JIS: + val = 0x86; + break; + } + break; + case 0x7b: + switch (keys) { + default: + val = 0x29; + break; + case KBD_JIS: + val = 0x85; + break; + } + break; + case 0x7d: + switch (keys) { + default: + val = 0x66; + break; + case KBD_JIS: + val = 0x13; + break; + } + break; + } + + is_special = 0; + } + dev->ignore = 1; - keyboard_get_states(NULL, &num_lock, NULL); + keyboard_get_states(NULL, &num_lock, NULL, NULL); shift_states = keyboard_get_shift() & STATE_SHIFT_MASK; switch (val) { @@ -3463,7 +5622,9 @@ keyboard_at_set_defaults(atkbc_dev_t *dev) memset(keyboard_set3_flags, 0, 512); keyboard_mode = 0x02; - keyboard_at_set_scancode_set(); + keyboard_at_set_scancode_set(dev); + + is_special = 0; } static void @@ -3476,6 +5637,10 @@ keyboard_at_bat(void *priv) keyboard_scan = 1; + keyboard_all_up(); + keyboard_update_states(0, 0, 0, 0); + + keyboard_set_in_reset(0); kbc_at_dev_queue_add(dev, 0xaa, 0); } else { bat_counter--; @@ -3490,7 +5655,6 @@ keyboard_at_invalid_cmd(atkbc_dev_t *dev) kbc_at_dev_queue_add(dev, inv_cmd_response, 0); } - static void keyboard_at_write(void *priv) { @@ -3510,6 +5674,7 @@ keyboard_at_write(void *priv) switch (dev->command) { case 0xed: /* Set/reset LEDs */ kbc_at_dev_queue_add(dev, 0xfa, 0); + keyboard_update_states(!!(val & 0x4), !!(val & 0x2), val & 0x1, !!(val & 0x8)); keyboard_at_log("%s: Set/reset LEDs [%02X]\n", dev->name, val); break; @@ -3526,8 +5691,9 @@ keyboard_at_write(void *priv) case 0x8a: kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK */ keyboard_mode = val; + is_special = 0; keyboard_at_log("%s: Set scan code set [%02X]\n", dev->name, keyboard_mode); - keyboard_at_set_scancode_set(); + keyboard_at_set_scancode_set(dev); break; default: /* Fatal so any instance of anything attempting to set scan code > 3 can be reported to us. */ @@ -3595,7 +5761,7 @@ keyboard_at_write(void *priv) break; case 0xf0: /* get/set scan code set */ - if (dev->type & FLAG_PS2) { + if (dev->type & FLAG_PS2_KBD) { dev->command = val; keyboard_at_log("%s: scan code set\n", dev->name); dev->flags |= FLAG_CTRLDAT; @@ -3638,6 +5804,13 @@ keyboard_at_write(void *priv) case 0xf6: /* set defaults */ keyboard_at_log("%s: set defaults%s\n", dev->name, (val == 0xf6) ? "" : " and disable keyboard"); + dev->port->out_new = -1; + dev->port->wantcmd = 0; + + kbc_at_dev_queue_reset(dev, 1); + + dev->last_scan_code = 0x00; + keyboard_scan = !(val & 0x01); keyboard_at_log("%s: val = %02X, keyboard_scan = %i\n", dev->name, val, keyboard_scan); @@ -3648,11 +5821,11 @@ keyboard_at_write(void *priv) memset(keyboard_set3_flags, 0, 512); keyboard_mode = 0x02; - keyboard_at_set_scancode_set(); + keyboard_at_set_scancode_set(dev); break; case 0xf7: /* set all keys to repeat */ - if (dev->type & FLAG_PS2) { + if (dev->type & FLAG_PS2_KBD) { keyboard_at_log("%s: set all keys to repeat\n", dev->name); kbc_at_dev_queue_add(dev, 0xfa, 0); keyboard_set3_all_break = 1; @@ -3661,7 +5834,7 @@ keyboard_at_write(void *priv) break; case 0xf8: /* set all keys to give make/break codes */ - if (dev->type & FLAG_PS2) { + if (dev->type & FLAG_PS2_KBD) { keyboard_at_log("%s: set all keys to give make/break codes\n", dev->name); kbc_at_dev_queue_add(dev, 0xfa, 0); keyboard_set3_all_break = 1; @@ -3670,7 +5843,7 @@ keyboard_at_write(void *priv) break; case 0xf9: /* set all keys to give make codes only */ - if (dev->type & FLAG_PS2) { + if (dev->type & FLAG_PS2_KBD) { keyboard_at_log("%s: set all keys to give make codes only\n", dev->name); kbc_at_dev_queue_add(dev, 0xfa, 0); keyboard_set3_all_break = 0; @@ -3679,7 +5852,7 @@ keyboard_at_write(void *priv) break; case 0xfa: /* set all keys to repeat and give make/break codes */ - if (dev->type & FLAG_PS2) { + if (dev->type & FLAG_PS2_KBD) { keyboard_at_log("%s: set all keys to repeat and give make/break codes\n", dev->name); kbc_at_dev_queue_add(dev, 0xfa, 0); keyboard_set3_all_repeat = 1; @@ -3707,11 +5880,11 @@ keyboard_at_write(void *priv) /* TODO: This is supposed to resend multiple bytes after some commands. */ case 0xfe: /* resend last scan code */ keyboard_at_log("%s: resend last scan code\n", dev->name); - kbc_at_dev_queue_add(dev, 0xfa, 0); kbc_at_dev_queue_add(dev, dev->last_scan_code, 0); break; case 0xff: /* reset */ + keyboard_set_in_reset(1); kbc_at_dev_reset(dev, 1); bat_counter = 1000; break; @@ -3722,6 +5895,44 @@ keyboard_at_write(void *priv) } } +#ifdef SCAN_CODE_TABLES_COMPARISON +/* Non-translated to translated scan codes. */ +static const uint8_t nont_to_t[256] = { + 0x00, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58, + 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59, + 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a, + 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b, + 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c, + 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d, + 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e, + 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f, + 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60, + 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61, + 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e, + 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76, + 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b, + 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f, + 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45, + 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54, + 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; +#endif + /* * Initialize the device for use by the user. * @@ -3742,14 +5953,13 @@ keyboard_at_init(const device_t *info) Key 63 = Japanese key between right Ctrl and right Alt, scan code: 86 (Henkan/Zenkouho 79); Key 65? = Japanese key between right Ctrl and right Alt, scan code: 87 (Hiragana/Katakana 70). */ - dev->type = FLAG_PS2 | KBD_102_KEY /* device_get_config_int("type") */; + dev->type = info->local | device_get_config_int("keys"); + /* We assume that the IBM PS/55 machine uses the 5576-002 keyboard (JP/CN layout) here. This is not smart but suitable for supporting a keyboard ID that is rarely used in standard PCs. At least, the Taiwanese PS/55 uses the same keyboard ID and scancode set. The Korean one is unknown. */ - if (!!strstr(machine_getname(), "PS/55")) - dev->type = FLAG_PS2 | KBD_JIS; keyboard_at_log("%s: type=%d\n", dev->name, dev->type); @@ -3767,8 +5977,143 @@ keyboard_at_init(const device_t *info) keyboard_send = add_data_kbd; SavedKbd = dev; + keyboard_update_states(0, 0, 0, 0); - inv_cmd_response = (dev->type & FLAG_PS2) ? 0xfe : 0xfa; + inv_cmd_response = (dev->type & FLAG_PS2_KBD) ? 0xfe : 0xfa; + + is_special = 0; + +#ifdef SCAN_CODE_TABLES_COMPARISON + pclog_toggle_suppr(); + + pclog("Scan code set 01 vs. 81 (make):\n===============================\n"); + for (int i = 0; i < 512; i++) { + pclog("Scan code %03X:", i); + int j = 0; + do { + if (scancode_set1[i].mk[j] == scancode_set81[i].mk[j]) + pclog(" --"); + else + pclog(" (%02X != %02X)", scancode_set1[i].mk[j], scancode_set81[i].mk[j]); + j++; + } while ((scancode_set1[i].mk[j] != 0) && (scancode_set81[i].mk[j] != 0)); + pclog("\n"); + } + + pclog("\nScan code set 01 vs. 81 (break):\n================================\n"); + for (int i = 0; i < 512; i++) { + pclog("Scan code %03X:", i); + int j = 0; + do { + if (scancode_set1[i].brk[j] == scancode_set81[i].brk[j]) + pclog(" --"); + else + pclog(" (%02X != %02X)", scancode_set1[i].brk[j], scancode_set81[i].brk[j]); + j++; + } while ((scancode_set1[i].brk[j] != 0) && (scancode_set81[i].brk[j] != 0)); + pclog("\n"); + } + + pclog("\nScan code set 02 vs. 82 (make):\n===============================\n"); + for (int i = 0; i < 512; i++) { + pclog("Scan code %03X:", i); + int j = 0; + do { + if (scancode_set2[i].mk[j] == scancode_set82[i].mk[j]) + pclog(" --"); + else + pclog(" (%02X != %02X)", scancode_set2[i].mk[j], scancode_set82[i].mk[j]); + j++; + } while ((scancode_set2[i].mk[j] != 0) && (scancode_set82[i].mk[j] != 0)); + pclog("\n"); + } + + pclog("\nScan code set 02 vs. 82 (break):\n================================\n"); + for (int i = 0; i < 512; i++) { + pclog("Scan code %03X:", i); + int j = 0; + do { + if (scancode_set2[i].brk[j] == scancode_set82[i].brk[j]) + pclog(" --"); + else + pclog(" (%02X != %02X)", scancode_set2[i].brk[j], scancode_set82[i].brk[j]); + j++; + } while ((scancode_set2[i].brk[j] != 0) && (scancode_set82[i].brk[j] != 0)); + pclog("\n"); + } + + pclog("\nScan code set 01 vs. 02 (make):\n===============================\n"); + for (int i = 0; i < 512; i++) { + pclog("Scan code %03X:", i); + int j = 0; + int k = 0; + int was_f0 = 0; + do { + if (scancode_set2[i].mk[k] == 0xf0) + was_f0 = 1; + else { + uint8_t code = nont_to_t[scancode_set2[i].mk[k]]; + + if (was_f0) { + if (code & 0x80) + code = 0x00; + else + code |= 0x80; + + was_f0 = 0; + } + + if (scancode_set1[i].mk[j] == code) + pclog(" --"); + else + pclog(" (%02X != %02X)", scancode_set1[i].mk[j], code); + + j++; + } + + k++; + } while ((scancode_set1[i].mk[j] != 0) && (scancode_set2[i].mk[k] != 0)); + pclog("\n"); + } + + pclog("\nScan code set 01 vs. 02 (break):\n================================\n"); + for (int i = 0; i < 512; i++) { + pclog("Scan code %03X:", i); + int j = 0; + int k = 0; + int was_f0 = 0; + do { + if (scancode_set2[i].brk[k] == 0xf0) + was_f0 = 1; + else { + uint8_t code = nont_to_t[scancode_set2[i].brk[k]]; + + if (was_f0) { + if (code & 0x80) + code = 0x00; + else + code |= 0x80; + + was_f0 = 0; + } + + if (scancode_set1[i].brk[j] == code) + pclog(" --"); + else + pclog(" (%02X != %02X)", scancode_set1[i].brk[j], code); + + j++; + } + + k++; + } while ((scancode_set1[i].brk[j] != 0) && (scancode_set2[i].brk[k] != 0)); + pclog("\n"); + } + + pclog_toggle_suppr(); + + fatal("Comparison finished\n"); +#endif /* Return our private data to the I/O layer. */ return dev; @@ -3785,6 +6130,8 @@ keyboard_at_close(void *priv) /* Disable the scancode maps. */ keyboard_set_table(NULL); + keyboard_update_states(0, 0, 0, 0); + SavedKbd = NULL; free(dev); @@ -3793,22 +6140,20 @@ keyboard_at_close(void *priv) static const device_config_t keyboard_at_config[] = { // clang-format off { - .name = "type", - .description = "Type", + .name = "keys", + .description = "Keys", .type = CONFIG_SELECTION, .default_string = NULL, - .default_int = 1, + .default_int = KBD_101_KEY, .file_filter = NULL, .spinner = { 0 }, .selection = { - { .description = "AT 84-key", .value = FLAG_AT | KBD_84_KEY }, - { .description = "AT 101/102/106-key", .value = FLAG_AT | KBD_101_KEY }, - { .description = "AT Korean", .value = FLAG_AT | KBD_KOREAN }, - { .description = "PS/2 101-key", .value = FLAG_PS2 | KBD_101_KEY }, - { .description = "PS/2 102-key", .value = FLAG_PS2 | KBD_102_KEY }, - { .description = "PS/2 106-key JIS", .value = FLAG_PS2 | KBD_JIS }, - { .description = "PS/2 Korean", .value = FLAG_PS2 | KBD_KOREAN }, - { .description = "" } + { .description = "84", .value = KBD_84_KEY }, + { .description = "101 (ANSI)", .value = KBD_101_KEY }, + { .description = "102 (ISO)", .value = KBD_102_KEY }, + { .description = "106 (JIS)", .value = KBD_JIS }, + { .description = "103 (KSC)", .value = KBD_KSC }, + { .description = "104 (ABNT2)", .value = KBD_ABNT2 } }, .bios = { { 0 } } }, @@ -3818,12 +6163,36 @@ static const device_config_t keyboard_at_config[] = { // clang-format on }; -/* TODO: Add more keyboard types. */ -const device_t keyboard_at_generic_device = { - .name = "Standard AT or PS/2 Keyboard", - .internal_name = "ps2", - .flags = DEVICE_PS2_KBC, - .local = 0, +static const device_config_t keyboard_ps2_config[] = { + // clang-format off + { + .name = "keys", + .description = "Keys", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = KBD_101_KEY, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "101 (ANSI)", .value = KBD_101_KEY }, + { .description = "102 (ISO)", .value = KBD_102_KEY }, + { .description = "106 (JIS)", .value = KBD_JIS }, + { .description = "103 (KSC)", .value = KBD_KSC }, + { .description = "104 (ABNT2)", .value = KBD_ABNT2 } + }, + .bios = { { 0 } } + }, + { + .name = "", .description = "", .type = CONFIG_END + } + // clang-format on +}; + +const device_t keyboard_at_device = { + .name = "AT Keyboard", + .internal_name = "keyboard_at", + .flags = DEVICE_AT_KBC, + .local = FLAG_AT, .init = keyboard_at_init, .close = keyboard_at_close, .reset = NULL, @@ -3832,3 +6201,60 @@ const device_t keyboard_at_generic_device = { .force_redraw = NULL, .config = keyboard_at_config }; + +const device_t keyboard_ax_device = { + .name = "AX Keyboard", + .internal_name = "keyboard_ax", + .flags = DEVICE_AT_KBC, + .local = FLAG_AX | KBD_JIS, + .init = keyboard_at_init, + .close = keyboard_at_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t keyboard_ps2_device = { + .name = "PS/2 Keyboard", + .internal_name = "keyboard_ps2", + .flags = DEVICE_AT_KBC | DEVICE_PS2_KBC, + .local = FLAG_PS2_KBD, + .init = keyboard_at_init, + .close = keyboard_at_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = keyboard_ps2_config +}; + +const device_t keyboard_ps55_device = { + .name = "PS/55 Keyboard", + .internal_name = "keyboard_ps55", + .flags = DEVICE_AT_KBC | DEVICE_PS2_KBC, + .local = FLAG_PS2_KBD | KBD_JIS, + .init = keyboard_at_init, + .close = keyboard_at_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t keyboard_at_generic_device = { + .name = "AT/PS/2 Keyboard", + .internal_name = "keyboard_at", + .flags = DEVICE_AT_KBC, + .local = KBD_102_KEY, + .init = keyboard_at_init, + .close = keyboard_at_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = keyboard_at_config +}; + diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index 3c616a2ab..2936868b0 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -35,60 +35,8 @@ #include <86box/machine.h> #include <86box/m_xt_t1000.h> #include <86box/cassette.h> -#include <86box/io.h> -#include <86box/pic.h> -#include <86box/pit.h> -#include <86box/ppi.h> -#include <86box/mem.h> -#include <86box/rom.h> -#include <86box/sound.h> -#include <86box/snd_speaker.h> -#include <86box/video.h> #include <86box/keyboard.h> -#define STAT_PARITY 0x80 -#define STAT_RTIMEOUT 0x40 -#define STAT_TTIMEOUT 0x20 -#define STAT_LOCK 0x10 -#define STAT_CD 0x08 -#define STAT_SYSFLAG 0x04 -#define STAT_IFULL 0x02 -#define STAT_OFULL 0x01 - -/* Keyboard Types */ -enum { - KBD_TYPE_PC81 = 0, - KBD_TYPE_PC82, - KBD_TYPE_XT82, - KBD_TYPE_XT86, - KBD_TYPE_COMPAQ, - KBD_TYPE_TANDY, - KBD_TYPE_TOSHIBA, - KBD_TYPE_VTECH, - KBD_TYPE_OLIVETTI, - KBD_TYPE_ZENITH, - KBD_TYPE_PRAVETZ, - KBD_TYPE_HYUNDAI, - KBD_TYPE_XTCLONE -}; - -typedef struct xtkbd_t { - int want_irq; - int blocked; - int tandy; - - uint8_t pa; - uint8_t pb; - uint8_t pd; - uint8_t clock; - uint8_t key_waiting; - uint8_t type; - uint8_t pravetz_flags; - uint8_t cpu_speed; - - pc_timer_t send_delay_timer; -} xtkbd_t; - /*XT keyboard has no escape scancodes, and no scancodes beyond 53*/ const scancode scancode_xt[512] = { // clang-format off @@ -607,779 +555,66 @@ const scancode scancode_xt[512] = { // clang-format on }; -static uint8_t key_queue[16]; -static int key_queue_start = 0; -static int key_queue_end = 0; -static int is_tandy = 0; -static int is_t1x00 = 0; -static int is_amstrad = 0; - -#ifdef ENABLE_KEYBOARD_XT_LOG -int keyboard_xt_do_log = ENABLE_KEYBOARD_XT_LOG; - -static void -kbd_log(const char *fmt, ...) -{ - va_list ap; - - if (keyboard_xt_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define kbd_log(fmt, ...) -#endif - -static uint8_t -get_fdd_switch_settings(void) -{ - - uint8_t fdd_count = 0; - - for (uint8_t i = 0; i < FDD_NUM; i++) { - if (fdd_get_flags(i)) - fdd_count++; - } - - if (!fdd_count) - return 0x00; - else - return ((fdd_count - 1) << 6) | 0x01; -} - -static uint8_t -get_videomode_switch_settings(void) -{ - - if (video_is_mda()) - return 0x30; - else if (video_is_cga()) - return 0x20; /* 0x10 would be 40x25 */ - else - return 0x00; -} - -static void -kbd_poll(void *priv) -{ - xtkbd_t *kbd = (xtkbd_t *) priv; - - timer_advance_u64(&kbd->send_delay_timer, 1000 * TIMER_USEC); - - if (!(kbd->pb & 0x40) && (kbd->type != KBD_TYPE_TANDY)) - return; - - if (kbd->want_irq) { - kbd->want_irq = 0; - kbd->pa = kbd->key_waiting; - kbd->blocked = 1; - picint(2); -#ifdef ENABLE_KEYBOARD_XT_LOG - kbd_log("XTkbd: kbd_poll(): keyboard_xt : take IRQ\n"); -#endif - } - - if ((key_queue_start != key_queue_end) && !kbd->blocked) { - kbd->key_waiting = key_queue[key_queue_start]; - kbd_log("XTkbd: reading %02X from the key queue at %i\n", - kbd->key_waiting, key_queue_start); - key_queue_start = (key_queue_start + 1) & 0x0f; - kbd->want_irq = 1; - } -} - -static void -kbd_adddata(uint16_t val) -{ - /* Test for T1000 'Fn' key (Right Alt / Right Ctrl) */ - if (is_t1x00) { - if (keyboard_recv(0x138) || keyboard_recv(0x11d)) { /* 'Fn' pressed */ - t1000_syskey(0x00, 0x04, 0x00); /* Set 'Fn' indicator */ - switch (val) { - case 0x45: /* Num Lock => toggle numpad */ - t1000_syskey(0x00, 0x00, 0x10); - break; - case 0x47: /* Home => internal display */ - t1000_syskey(0x40, 0x00, 0x00); - break; - case 0x49: /* PgDn => turbo on */ - t1000_syskey(0x80, 0x00, 0x00); - break; - case 0x4D: /* Right => toggle LCD font */ - t1000_syskey(0x00, 0x00, 0x20); - break; - case 0x4F: /* End => external display */ - t1000_syskey(0x00, 0x40, 0x00); - break; - case 0x51: /* PgDn => turbo off */ - t1000_syskey(0x00, 0x80, 0x00); - break; - case 0x54: /* SysRQ => toggle window */ - t1000_syskey(0x00, 0x00, 0x08); - break; - - default: - break; - } - } else - t1000_syskey(0x04, 0x00, 0x00); /* Reset 'Fn' indicator */ - } - - key_queue[key_queue_end] = val; - kbd_log("XTkbd: %02X added to key queue at %i\n", - val, key_queue_end); - key_queue_end = (key_queue_end + 1) & 0x0f; -} - -void -kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val)) -{ - uint8_t num_lock = 0; - uint8_t shift_states = 0; - - if (!adddata) - return; - - keyboard_get_states(NULL, &num_lock, NULL); - shift_states = keyboard_get_shift() & STATE_LSHIFT; - - if (is_amstrad) - num_lock = !num_lock; - - /* If NumLock is on, invert the left shift state so we can always check for - the the same way flag being set (and with NumLock on that then means it - is actually *NOT* set). */ - if (num_lock) - shift_states ^= STATE_LSHIFT; - - switch (val) { - case FAKE_LSHIFT_ON: - /* If NumLock is on, fake shifts are sent when shift is *NOT* presed, - if NumLock is off, fake shifts are sent when shift is pressed. */ - if (shift_states) { - /* Send fake shift. */ - adddata(num_lock ? 0x2a : 0xaa); - } - break; - case FAKE_LSHIFT_OFF: - if (shift_states) { - /* Send fake shift. */ - adddata(num_lock ? 0xaa : 0x2a); - } - break; - default: - adddata(val); - break; - } -} - -static void -kbd_adddata_ex(uint16_t val) -{ - kbd_adddata_process(val, kbd_adddata); -} - -static void -kbd_write(uint16_t port, uint8_t val, void *priv) -{ - xtkbd_t *kbd = (xtkbd_t *) priv; - uint8_t bit; - uint8_t set; - uint8_t new_clock; - - switch (port) { - case 0x61: /* Keyboard Control Register (aka Port B) */ - if (!(val & 0x80) || (kbd->type == KBD_TYPE_HYUNDAI)) { - new_clock = !!(val & 0x40); - if (!kbd->clock && new_clock) { - key_queue_start = key_queue_end = 0; - kbd->want_irq = 0; - kbd->blocked = 0; - kbd_adddata(0xaa); - } - } - - kbd->pb = val; - 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)) - pc_cas_set_motor(cassette, (kbd->pb & 0x08) == 0); - - speaker_update(); - - speaker_gated = val & 1; - speaker_enable = val & 2; - - if (speaker_enable) - was_speaker_enable = 1; - pit_devs[0].set_gate(pit_devs[0].data, 2, val & 1); - - if (val & 0x80) { - kbd->pa = 0; - kbd->blocked = 0; - picintc(2); - } - -#ifdef ENABLE_KEYBOARD_XT_LOG - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) - kbd_log("XTkbd: Cassette motor is %s\n", !(val & 0x08) ? "ON" : "OFF"); -#endif - break; -#ifdef ENABLE_KEYBOARD_XT_LOG - case 0x62: /* Switch Register (aka Port C) */ - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) - kbd_log("XTkbd: Cassette IN is %i\n", !!(val & 0x10)); - break; -#endif - - case 0xc0 ... 0xcf: /* Pravetz Flags */ - kbd_log("XTkbd: Port %02X out: %02X\n", port, val); - if (kbd->type == KBD_TYPE_PRAVETZ) { - bit = (port >> 1) & 0x07; - set = (port & 0x01) << bit; - kbd->pravetz_flags = (kbd->pravetz_flags & ~(1 << bit)) | set; - } - break; - - case 0x1f0: - kbd_log("XTkbd: Port %04X out: %02X\n", port, val); - if (kbd->type == KBD_TYPE_VTECH) { - kbd->cpu_speed = val; - cpu_dynamic_switch(kbd->cpu_speed >> 7); - } - break; - - default: - break; - } -} - -static uint8_t -kbd_read(uint16_t port, void *priv) -{ - const xtkbd_t *kbd = (xtkbd_t *) priv; - uint8_t ret = 0xff; - - switch (port) { - case 0x60: /* Keyboard Data Register (aka Port A) */ - if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) || - (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ) || - (kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) || - (kbd->type == KBD_TYPE_XTCLONE) || (kbd->type == KBD_TYPE_COMPAQ) || - (kbd->type == KBD_TYPE_ZENITH) || (kbd->type == KBD_TYPE_HYUNDAI) || - (kbd->type == KBD_TYPE_VTECH))) { - 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) || - (kbd->type == KBD_TYPE_VTECH)) - /* 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: - * bits 6-7: floppy drive number - * bits 4-5: video mode - * bit 2-3: base memory size - * bit 1: fpu enable - * bit 0: fdc enable - */ - ret = get_fdd_switch_settings(); - - ret |= get_videomode_switch_settings(); - - /* Base memory size should always be 64k */ - ret |= 0x0c; - - if (hasfpu) - ret |= 0x02; - } - } else - ret = kbd->pa; - break; - - case 0x61: /* Keyboard Control Register (aka Port B) */ - ret = kbd->pb; - 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->pb & 0x04) /* PB2 */ - switch (mem_size + isa_mem_size) { - case 64: - case 48: - case 32: - case 16: - ret = 0x00; - break; - default: - ret = (((mem_size + isa_mem_size) - 64) / 32) & 0x0f; - break; - } - else - ret = (((mem_size + isa_mem_size) - 64) / 32) >> 4; - } 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; - else - ret = kbd->pd >> 4; - } else { - if (kbd->pb & 0x08) /* PB3 */ - ret = kbd->pd >> 4; - else - ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00); - } - ret |= (ppispeakon ? 0x20 : 0); - - /* 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 (cassette == NULL) - ret |= (ppispeakon ? 0x10 : 0); - else - ret |= (pc_cas_get_inp(cassette) ? 0x10 : 0); - } - - if (kbd->type == KBD_TYPE_TANDY) - ret |= (tandy1k_eeprom_read() ? 0x10 : 0); - break; - - 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_HYUNDAI) || - (kbd->type == KBD_TYPE_VTECH)) - ret = kbd->pd; - break; - - case 0xc0: /* Pravetz Flags */ - if (kbd->type == KBD_TYPE_PRAVETZ) - ret = kbd->pravetz_flags; - kbd_log("XTkbd: Port %02X in : %02X\n", port, ret); - break; - - case 0x1f0: - if (kbd->type == KBD_TYPE_VTECH) - ret = kbd->cpu_speed; - kbd_log("XTkbd: Port %04X in : %02X\n", port, ret); - break; - - default: - break; - } - - return ret; -} - -static void -kbd_reset(void *priv) -{ - xtkbd_t *kbd = (xtkbd_t *) priv; - - kbd->want_irq = 0; - kbd->blocked = 0; - kbd->pa = 0x00; - kbd->pb = 0x00; - kbd->pravetz_flags = 0x00; - - keyboard_scan = 1; - - key_queue_start = 0; - key_queue_end = 0; -} - -void -keyboard_set_is_amstrad(int ams) -{ - is_amstrad = ams; -} +typedef struct { + int type; +} kbd_t; static void * kbd_init(const device_t *info) { - xtkbd_t *kbd; + kbd_t *dev = (kbd_t *) calloc(1, sizeof(kbd_t)); - kbd = (xtkbd_t *) calloc(1, sizeof(xtkbd_t)); + dev->type = info->local; - io_sethandler(0x0060, 4, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); - keyboard_send = kbd_adddata_ex; - kbd->type = info->local; - if (kbd->type == KBD_TYPE_VTECH) - kbd->cpu_speed = (!!cpu) << 2; - kbd_reset(kbd); - if (kbd->type == KBD_TYPE_PRAVETZ) - io_sethandler(0x00c0, 16, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); - if (kbd->type == KBD_TYPE_VTECH) - io_sethandler(0x01f0, 1, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); + if (dev->type == KBD_83_KEY) + keyboard_set_table(scancode_xt); + else + keyboard_set_table(scancode_set1); - key_queue_start = key_queue_end = 0; - - video_reset(gfxcard[0]); - - if ((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_TOSHIBA) || - (kbd->type == KBD_TYPE_OLIVETTI) || (kbd->type == KBD_TYPE_HYUNDAI) || - (kbd->type == KBD_TYPE_VTECH)) { - /* DIP switch readout: bit set = OFF, clear = ON. */ - if (kbd->type == KBD_TYPE_OLIVETTI) - /* Olivetti M19 - * Jumpers J1, J2 - monitor type. - * 01 - mono (high-res) - * 10 - color (low-res, disables 640x400x2 mode) - * 00 - autoswitching - */ - kbd->pd |= 0x00; - else - /* Switches 7, 8 - floppy drives. */ - kbd->pd = get_fdd_switch_settings(); - - /* Switches 5, 6 - video card type */ - kbd->pd |= get_videomode_switch_settings(); - - /* Switches 3, 4 - memory size. */ - if ((kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) || - (kbd->type == KBD_TYPE_HYUNDAI) || (kbd->type == KBD_TYPE_COMPAQ) || - (kbd->type == KBD_TYPE_TOSHIBA)) { - switch (mem_size) { - case 256: - kbd->pd |= 0x00; - break; - case 512: - kbd->pd |= 0x04; - break; - case 576: - kbd->pd |= 0x08; - break; - case 640: - default: - kbd->pd |= 0x0c; - break; - } - } else if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_VTECH)) { - switch (mem_size) { - case 64: /* 1x64k */ - kbd->pd |= 0x00; - break; - case 128: /* 2x64k */ - kbd->pd |= 0x04; - break; - case 192: /* 3x64k */ - kbd->pd |= 0x08; - break; - case 256: /* 4x64k */ - default: - kbd->pd |= 0x0c; - break; - } - } else if (kbd->type == KBD_TYPE_PC82) { - switch (mem_size) { -#ifdef PC82_192K_3BANK - case 192: /* 3x64k, not supported by stock BIOS due to bugs */ - kbd->pd |= 0x08; - break; -#else - case 192: /* 2x64k + 2x32k */ -#endif - case 64: /* 4x16k */ - case 96: /* 2x32k + 2x16k */ - case 128: /* 4x32k */ - case 160: /* 2x64k + 2x16k */ - case 224: /* 3x64k + 1x32k */ - case 256: /* 4x64k */ - default: - kbd->pd |= 0x0c; - break; - } - } else { /* really just the PC '81 */ - switch (mem_size) { - case 16: /* 1x16k */ - kbd->pd |= 0x00; - break; - case 32: /* 2x16k */ - kbd->pd |= 0x04; - break; - case 48: /* 3x16k */ - kbd->pd |= 0x08; - break; - case 64: /* 4x16k */ - default: - kbd->pd |= 0x0c; - break; - } - } - - /* Switch 2 - 8087 FPU. */ - if (hasfpu) - kbd->pd |= 0x02; - } else if (kbd->type == KBD_TYPE_ZENITH) { - /* Zenith Data Systems Z-151 - * SW2 switch settings: - * bit 7: monitor frequency - * bits 5-6: autoboot (00-11 resident monitor, 10 hdd, 01 fdd) - * bits 0-4: installed memory - */ - kbd->pd = 0x20; - switch (mem_size) { - case 128: - kbd->pd |= 0x02; - break; - case 192: - kbd->pd |= 0x04; - break; - case 256: - kbd->pd |= 0x06; - break; - case 320: - kbd->pd |= 0x08; - break; - case 384: - kbd->pd |= 0x0a; - break; - case 448: - kbd->pd |= 0x0c; - break; - case 512: - kbd->pd |= 0x0e; - break; - case 576: - kbd->pd |= 0x10; - break; - case 640: - default: - kbd->pd |= 0x12; - break; - } - } - - timer_add(&kbd->send_delay_timer, kbd_poll, kbd, 1); - - keyboard_set_table(scancode_xt); - - is_tandy = (kbd->type == KBD_TYPE_TANDY); - is_t1x00 = (kbd->type == KBD_TYPE_TOSHIBA); - - is_amstrad = 0; - - return kbd; + return dev; } static void kbd_close(void *priv) { - xtkbd_t *kbd = (xtkbd_t *) priv; - - /* Stop the timer. */ - timer_disable(&kbd->send_delay_timer); - - /* Disable scanning. */ - keyboard_scan = 0; - - keyboard_send = NULL; - - io_removehandler(0x0060, 4, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); + kbd_t *kbd = (kbd_t *) priv; free(kbd); } -const device_t keyboard_pc_device = { - .name = "IBM PC Keyboard (1981)", - .internal_name = "keyboard_pc", - .flags = 0, - .local = KBD_TYPE_PC81, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL +static const device_config_t keyboard_pc_xt_config[] = { + // clang-format off + { + .name = "keys", + .description = "Keys", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = KBD_83_KEY, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "83", .value = KBD_83_KEY }, + { .description = "101 (ANSI)", .value = KBD_101_KEY }, + { .description = "102 (ISO)", .value = KBD_102_KEY } + }, + .bios = { { 0 } } + }, + { + .name = "", .description = "", .type = CONFIG_END + } + // clang-format on }; -const device_t keyboard_pc82_device = { - .name = "IBM PC Keyboard (1982)", - .internal_name = "keyboard_pc82", - .flags = 0, - .local = KBD_TYPE_PC82, +const device_t keyboard_pc_xt_device = { + .name = "PC/XT Keyboard", + .internal_name = "keyboard_pc_xt", + .flags = DEVICE_XT_KBC, + .local = 0, .init = kbd_init, .close = kbd_close, - .reset = kbd_reset, + .reset = NULL, .available = NULL, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_pravetz_device = { - .name = "Pravetz Keyboard", - .internal_name = "keyboard_pravetz", - .flags = 0, - .local = KBD_TYPE_PRAVETZ, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_xt_device = { - .name = "XT (1982) Keyboard", - .internal_name = "keyboard_xt", - .flags = 0, - .local = KBD_TYPE_XT82, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_xt86_device = { - .name = "XT (1986) Keyboard", - .internal_name = "keyboard_xt86", - .flags = 0, - .local = KBD_TYPE_XT86, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_xt_compaq_device = { - .name = "Compaq Portable Keyboard", - .internal_name = "keyboard_xt_compaq", - .flags = 0, - .local = KBD_TYPE_COMPAQ, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_tandy_device = { - .name = "Tandy 1000 Keyboard", - .internal_name = "keyboard_tandy", - .flags = 0, - .local = KBD_TYPE_TANDY, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_xt_t1x00_device = { - .name = "Toshiba T1x00 Keyboard", - .internal_name = "keyboard_xt_t1x00", - .flags = 0, - .local = KBD_TYPE_TOSHIBA, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -#ifdef USE_LASERXT -const device_t keyboard_xt_lxt3_device = { - .name = "VTech Laser Turbo XT Keyboard", - .internal_name = "keyboard_xt_lxt", - .flags = 0, - .local = KBD_TYPE_VTECH, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; -#endif /* USE_LASERXT */ - -const device_t keyboard_xt_olivetti_device = { - .name = "Olivetti XT Keyboard", - .internal_name = "keyboard_xt_olivetti", - .flags = 0, - .local = KBD_TYPE_OLIVETTI, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t keyboard_xt_zenith_device = { - .name = "Zenith XT Keyboard", - .internal_name = "keyboard_xt_zenith", - .flags = 0, - .local = KBD_TYPE_ZENITH, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .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", - .flags = 0, - .local = KBD_TYPE_XTCLONE, - .init = kbd_init, - .close = kbd_close, - .reset = kbd_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .config = keyboard_pc_xt_config }; diff --git a/src/device/lpt.c b/src/device/lpt.c new file mode 100644 index 000000000..c54345856 --- /dev/null +++ b/src/device/lpt.c @@ -0,0 +1,945 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/fifo.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/dma.h> +#include <86box/lpt.h> +#include <86box/pic.h> +#include <86box/sound.h> +#include <86box/prt_devs.h> +#include <86box/thread.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/network.h> + +static int next_inst = 0; +int lpt_3bc_used = 0; + +lpt_port_t lpt_ports[PARALLEL_MAX]; + +lpt_device_t lpt_devs[PARALLEL_MAX]; + +const lpt_device_t lpt_none_device = { + .name = "None", + .internal_name = "none", + .init = NULL, + .close = NULL, + .write_data = NULL, + .write_ctrl = NULL, + .read_status = NULL, + .read_ctrl = NULL +}; + +static const struct { + const lpt_device_t *device; +} lpt_devices[] = { + // clang-format off + { &lpt_none_device }, + { &dss_device }, + { &lpt_dac_device }, + { &lpt_dac_stereo_device }, + { &lpt_prt_text_device }, + { &lpt_prt_escp_device }, + { &lpt_prt_ps_device }, +#ifdef USE_PCL + { &lpt_prt_pcl_device }, +#endif + { &lpt_plip_device }, + { &lpt_hasp_savquest_device }, + { NULL } + // clang-format on +}; + +#ifdef ENABLE_LPT_LOG +int lpt_do_log = ENABLE_LPT_LOG; + +static void +lpt_log(const char *fmt, ...) +{ + va_list ap; + + if (lpt_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define lpt_log(fmt, ...) +#endif + +const device_t * +lpt_device_getdevice(const int id) +{ + return (device_t *) lpt_devices[id].device->cfgdevice; +} + +int +lpt_device_has_config(const int id) +{ + int c = 0; + const device_t *dev = (device_t *) lpt_devices[id].device->cfgdevice; + const device_config_t *config; + if (dev == NULL) + return 0; + + if (dev->config == NULL) + return 0; + + config = dev->config; + + while (config->type != CONFIG_END) { + c++; + config++; + } + + return (c > 0) ? 1 : 0; +} + +const char * +lpt_device_get_name(const int id) +{ + if (lpt_devices[id].device == NULL) + return NULL; + + return lpt_devices[id].device->name; +} + +const char * +lpt_device_get_internal_name(const int id) +{ + if (lpt_devices[id].device == NULL) + return NULL; + + return lpt_devices[id].device->internal_name; +} + +int +lpt_device_get_from_internal_name(const char *str) +{ + int c = 0; + + while (lpt_devices[c].device != NULL) { + if (!strcmp(lpt_devices[c].device->internal_name, str)) + return c; + c++; + } + + return 0; +} + +void +lpt_devices_init(void) +{ + for (uint8_t i = 0; i < PARALLEL_MAX; i++) { + lpt_t *dev = lpt_devs[i].lpt; + + if (lpt_devices[lpt_ports[i].device].device != NULL) { + memcpy(&(lpt_devs[i]), (lpt_device_t *) lpt_devices[lpt_ports[i].device].device, sizeof(lpt_device_t)); + + if (lpt_devs[i].init) + lpt_devs[i].priv = lpt_devs[i].init(dev); + } else + memset(&(lpt_devs[i]), 0x00, sizeof(lpt_device_t)); + + lpt_devs[i].lpt = dev; + } +} + +void +lpt_devices_close(void) +{ + for (uint8_t i = 0; i < PARALLEL_MAX; i++) { + if (lpt_devs[i].close) + lpt_devs[i].close(lpt_devs[i].priv); + + memset(&(lpt_devs[i]), 0x00, sizeof(lpt_device_t)); + } +} + +static uint8_t +lpt_get_ctrl_raw(const lpt_t *dev) +{ + uint8_t ret; + + if (dev->dt && dev->dt->read_ctrl && dev->dt->priv) + ret = (dev->dt->read_ctrl(dev->dt->priv) & 0xef) | dev->enable_irq; + else + ret = 0xc0 | dev->ctrl | dev->enable_irq; + + return ret & 0xdf; +} + +static uint8_t +lpt_is_epp(const lpt_t *dev) +{ + return (dev->epp || ((dev->ecp) && ((dev->ecr & 0xe0) == 0x80))); +} + +static uint8_t +lpt_get_ctrl(const lpt_t *dev) +{ + uint8_t ret = lpt_get_ctrl_raw(dev); + + if (!dev->ecp && !dev->epp) + ret |= 0x20; + + return ret; +} + +static void +lpt_write_fifo(lpt_t *dev, const uint8_t val, const uint8_t tag) +{ + if (!fifo_get_full(dev->fifo)) { + fifo_write_evt_tagged(tag, val, dev->fifo); + + if (!timer_is_enabled(&dev->fifo_out_timer)) + timer_set_delay_u64(&dev->fifo_out_timer, (uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC)); + } +} + +static void +lpt_ecp_update_irq(lpt_t *dev) +{ + if (!(dev->ecr & 0x04) && ((dev->fifo_stat | dev->dma_stat) & 0x04)) + picintlevel(1 << dev->irq, &dev->irq_state); + else + picintclevel(1 << dev->irq, &dev->irq_state); +} + +static void +lpt_autofeed(lpt_t *dev, const uint8_t val) +{ + if (dev->dt && dev->dt->autofeed && dev->dt->priv) + dev->dt->autofeed(val, dev->dt->priv); + + dev->autofeed = val; +} + +static void +lpt_strobe(lpt_t *dev, const uint8_t val) +{ + if (dev->dt && dev->dt->strobe && dev->dt->priv) + dev->dt->strobe(dev->strobe, val, dev->dt->priv); + + dev->strobe = val; +} + +static void +lpt_fifo_out_callback(void *priv) +{ + lpt_t *dev = (lpt_t *) priv; + + switch (dev->state) { + default: + break; + + case LPT_STATE_READ_DMA: + ; + int ret = 0xff; + + if (dev->dma == 0xff) + ret = DMA_NODATA; + else + ret = dma_channel_read(dev->dma); + + lpt_log("DMA %02X: %08X\n", dev->dma, ret); + + if (ret != DMA_NODATA) { + fifo_write_evt_tagged(0x01, (uint8_t) (ret & 0xff), dev->fifo); + + if (ret & DMA_OVER) + /* Internal flag to indicate we have finished the DMA reads. */ + dev->dma_stat = 0x08; + } + + timer_advance_u64(&dev->fifo_out_timer, + (uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC)); + + if (dev->dma_stat || fifo_get_full(dev->fifo)) + dev->state = LPT_STATE_WRITE_FIFO; + break; + + case LPT_STATE_WRITE_FIFO: + if (!fifo_get_empty(dev->fifo)) { + uint8_t tag = 0x00; + const uint8_t val = fifo_read_evt_tagged(&tag, dev->fifo); + + lpt_log("FIFO: %02X, TAG = %02X\n", val, tag); + + /* We do not currently support sending commands. */ + if (tag == 0x01) { + if (dev->dt && dev->dt->write_data && dev->dt->priv) + dev->dt->write_data(val, dev->dt->priv); + + lpt_strobe(dev, 1); + lpt_strobe(dev, 0); + } + } + + if (dev->ecr & 0x08) { + if (fifo_get_empty(dev->fifo)) { + if (dev->dma_stat) { + /* Now actually set the external flag. */ + dev->dma_stat = 0x04; + dev->state = LPT_STATE_IDLE; + lpt_ecp_update_irq(dev); + lpt_autofeed(dev, 0); + } else { + dev->state = LPT_STATE_READ_DMA; + + timer_advance_u64(&dev->fifo_out_timer, + (uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC)); + } + } else + timer_advance_u64(&dev->fifo_out_timer, + (uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC)); + } else if (!fifo_get_empty(dev->fifo)) + timer_advance_u64(&dev->fifo_out_timer, + (uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC)); + else + lpt_autofeed(dev, 0); + break; + } +} + +void +lpt_write(const uint16_t port, const uint8_t val, void *priv) +{ + lpt_t *dev = (lpt_t *) priv; + uint16_t mask = 0x0407; + + lpt_log("[W] %04X = %02X\n", port, val); + + /* This is needed so the parallel port at 3BC works. */ + if (dev->addr & 0x0004) + mask = 0x0403; + + switch (port & mask) { + case 0x0000: + if (dev->ecp) { + if ((dev->ecr & 0xe0) == 0x60) + /* AFIFO */ + lpt_write_fifo(dev, val, 0x00); + else if (!(dev->ecr & 0xc0) && (!(dev->ecr & 0x20) || !(lpt_get_ctrl_raw(dev) & 0x20)) && + dev->dt && dev->dt->write_data && dev->dt->priv) + /* DATAR */ + dev->dt->write_data(val, dev->dt->priv); + dev->dat = val; + } else { + /* DTR */ + if ((!dev->ext || !(lpt_get_ctrl_raw(dev) & 0x20)) && dev->dt && + dev->dt->write_data && dev->dt->priv) + dev->dt->write_data(val, dev->dt->priv); + dev->dat = val; + } + break; + + case 0x0001: + break; + + case 0x0002: + if (dev->dt && dev->dt->write_ctrl && dev->dt->priv) { + if (dev->ecp) + dev->dt->write_ctrl((val & 0xfc) | dev->autofeed | dev->strobe, dev->dt->priv); + else + dev->dt->write_ctrl(val, dev->dt->priv); + } + dev->ctrl = val; + dev->enable_irq = val & 0x10; + if (!(val & 0x10) && (dev->irq != 0xff)) + picintc(1 << dev->irq); + dev->irq_state = 0; + break; + + case 0x0003: + if (lpt_is_epp(dev)) { + if (dev->dt && dev->dt->epp_write_data && dev->dt->priv) + dev->dt->epp_write_data(1, val, dev->dt->priv); + } + break; + + case 0x0004 ... 0x0007: + if (lpt_is_epp(dev)) { + if (dev->dt && dev->dt->epp_write_data && dev->dt->priv) + dev->dt->epp_write_data(0, val, dev->dt->priv); + } + break; + + case 0x0400: case 0x0404: + switch (dev->ecr >> 5) { + default: + break; + case 2: + lpt_write_fifo(dev, val, 0x01); + break; + case 3: + if (!(lpt_get_ctrl_raw(dev) & 0x20)) + lpt_write_fifo(dev, val, 0x01); + break; + case 6: + /* TFIFO */ + if (!fifo_get_full(dev->fifo)) + fifo_write_evt(val, dev->fifo); + break; + } + break; + + case 0x0402: case 0x0406: + if (!(val & 0x0c)) + lpt_autofeed(dev, 0x00); + else + lpt_autofeed(dev, 0x02); + + if ((dev->ecr & 0x04) && !(val & 0x04)) { + dev->dma_stat = 0x00; + fifo_reset(dev->fifo); + if (val & 0x08) { + dev->state = LPT_STATE_READ_DMA; + dev->fifo_stat = 0x00; + if (!timer_is_enabled(&dev->fifo_out_timer)) + timer_set_delay_u64(&dev->fifo_out_timer, (uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC)); + } else { + dev->state = LPT_STATE_WRITE_FIFO; + if (lpt_get_ctrl_raw(dev) & 0x20) + dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x04 : 0x00; + else + dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x00 : 0x04; + } + } else if ((val & 0x04) && !(dev->ecr & 0x04)) { + if (timer_is_enabled(&dev->fifo_out_timer)) + timer_disable(&dev->fifo_out_timer); + + dev->state = LPT_STATE_IDLE; + } + dev->ecr = val; + lpt_ecp_update_irq(dev); + break; + + default: + break; + } +} + +static void +lpt_fifo_d_ready_evt(void *priv) +{ + lpt_t *dev = (lpt_t *) priv; + + if (!(dev->ecr & 0x08)) { + if (lpt_get_ctrl_raw(dev) & 0x20) + dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x04 : 0x00; + else + dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x00 : 0x04; + } + + lpt_ecp_update_irq(dev); +} + +void +lpt_write_to_fifo(void *priv, const uint8_t val) +{ + lpt_t *dev = (lpt_t *) priv; + + if (dev->ecp) { + if (((dev->ecr & 0xe0) == 0x20) && (lpt_get_ctrl_raw(dev) & 0x20)) + dev->dat = val; + else if (((dev->ecr & 0xe0) == 0x60) && (lpt_get_ctrl_raw(dev) & 0x20) && + !fifo_get_full(dev->fifo)) + fifo_write_evt_tagged(0x01, val, dev->fifo); + + if (((dev->ecr & 0x0c) == 0x08) && (dev->dma != 0xff)) { + const int ret = dma_channel_write(dev->dma, val); + + if (ret & DMA_OVER) + dev->dma_stat |= 0x04; + } + } else { + if (dev->ext && (lpt_get_ctrl_raw(dev) & 0x20)) + dev->dat = val; + } +} + +void +lpt_write_to_dat(void *priv, const uint8_t val) +{ + lpt_t *dev = (lpt_t *) priv; + + dev->dat = val; +} + +static uint8_t +lpt_read_fifo(const lpt_t *dev) +{ + uint8_t ret = 0xff; + + if (!fifo_get_empty(dev->fifo)) + ret = fifo_read(dev->fifo); + + return ret; +} + +uint8_t +lpt_read_status(lpt_t *dev) +{ + uint8_t low_bits = 0x07; + uint8_t ret; + + if (dev->ext) { + low_bits = 0x03 | (dev->irq_state ? 0x00 : 0x04); + if (dev->irq != 0xff) + picintclevel(1 << dev->irq, &dev->irq_state); + dev->irq_state = 0; + } + if (dev->epp || dev->ecp) { + low_bits = lpt_is_epp(dev) ? 0x02 : 0x03; + if (lpt_get_ctrl_raw(dev) & 0x10) + low_bits |= (dev->irq_state ? 0x00 : 0x04); + else + low_bits |= 0x04; + } + + if (dev->dt && dev->dt->read_status && dev->dt->priv) + ret = (dev->dt->read_status(dev->dt->priv) & 0xf8) | low_bits; + else + ret = 0xd8 | low_bits; + + return ret; +} + +uint8_t +lpt_read(const uint16_t port, void *priv) +{ + lpt_t *dev = (lpt_t *) priv; + uint16_t mask = 0x0407; + uint8_t ret = 0xff; + + /* This is needed so the parallel port at 3BC works. */ + if (dev->addr & 0x0004) + mask = 0x0403; + + switch (port & mask) { + case 0x0000: + if (dev->ecp) { + if (!(dev->ecr & 0xc0)) + ret = dev->dat; + } else { + /* DTR */ + ret = dev->dat; + } + break; + + case 0x0001: + ret = lpt_read_status(dev); + break; + + case 0x0002: + ret = lpt_get_ctrl(dev); + if (dev->ecp) + ret = (ret & 0xfc) | (dev->ctrl & 0x03); + break; + + case 0x0003: + if (lpt_is_epp(dev)) { + if (dev->dt && dev->dt->epp_request_read && dev->dt->priv) + dev->dt->epp_request_read(1, dev->dt->priv); + ret = dev->dat; + } + break; + + case 0x0004 ... 0x0007: + if (lpt_is_epp(dev)) { + if (dev->dt && dev->dt->epp_request_read && dev->dt->priv) + dev->dt->epp_request_read(0, dev->dt->priv); + ret = dev->dat; + } + break; + + case 0x0400: case 0x0404: + switch (dev->ecr >> 5) { + default: + break; + case 3: + if (lpt_get_ctrl_raw(dev) & 0x20) + ret = lpt_read_fifo(dev); + break; + case 6: + /* TFIFO */ + if (!fifo_get_empty(dev->fifo)) + ret = fifo_read_evt(dev->fifo); + break; + case 7: + /* CNFGA */ + ret = dev->cnfga_readout; + break; + } + break; + + case 0x0401: case 0x0405: + if ((dev->ecr & 0xe0) == 0xe0) { + /* CNFGB */ + ret = 0x08; + ret |= (dev->irq_state ? 0x40 : 0x00); + ret |= ((dev->irq == 0x05) ? 0x30 : 0x00); + if ((dev->dma >= 1) && (dev->dma <= 3)) + ret |= dev->dma; + } + break; + + case 0x0402: case 0x0406: + ret = dev->ecr | dev->fifo_stat | (dev->dma_stat & 0x04); + ret |= (fifo_get_full(dev->fifo) ? 0x02 : 0x00); + ret |= (fifo_get_empty(dev->fifo) ? 0x01 : 0x00); + break; + + default: + break; + } + + lpt_log("[R] %04X = %02X\n", port, ret); + + return ret; +} + +uint8_t +lpt_read_port(lpt_t *dev, const uint16_t reg) +{ + return lpt_read(reg, dev); +} + +void +lpt_irq(void *priv, const int raise) +{ + lpt_t *dev = (lpt_t *) priv; + + if (dev->enable_irq) { + if (dev->irq != 0xff) { + if (dev->ext) { + if (raise) + picintlevel(1 << dev->irq, &dev->irq_state); + else + picintclevel(1 << dev->irq, &dev->irq_state); + } else { + if (raise) + picint(1 << dev->irq); + else + picintc(1 << dev->irq); + } + } + + if (!dev->ext || (dev->irq == 0xff)) + dev->irq_state = raise; + } else { + if (dev->irq != 0xff) { + if (dev->ext) + picintclevel(1 << dev->irq, &dev->irq_state); + else + picintc(1 << dev->irq); + } + + dev->irq_state = 0; + } +} + +void +lpt_set_ext(lpt_t *dev, const uint8_t ext) +{ + if (lpt_ports[dev->id].enabled) + dev->ext = ext; +} + +void +lpt_set_ecp(lpt_t *dev, const uint8_t ecp) +{ + if (lpt_ports[dev->id].enabled) + dev->ecp = ecp; +} + +void +lpt_set_epp(lpt_t *dev, const uint8_t epp) +{ + if (lpt_ports[dev->id].enabled) + dev->epp = epp; +} + +void +lpt_set_lv2(lpt_t *dev, const uint8_t lv2) +{ + if (lpt_ports[dev->id].enabled) + dev->lv2 = lv2; +} + +void +lpt_set_fifo_threshold(lpt_t *dev, const int threshold) +{ + if (lpt_ports[dev->id].enabled) + fifo_set_trigger_len(dev->fifo, threshold); +} + +void +lpt_set_cnfga_readout(lpt_t *dev, const uint8_t cnfga_readout) +{ + if (lpt_ports[dev->id].enabled) + dev->cnfga_readout = cnfga_readout; +} + +void +lpt_port_setup(lpt_t *dev, const uint16_t port) +{ + if (lpt_ports[dev->id].enabled) { + if ((dev->addr != 0x0000) && (dev->addr != 0xffff)) { + io_removehandler(dev->addr, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, dev); + io_removehandler(dev->addr + 0x0400, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, dev); + } + if ((port != 0x0000) && (port != 0xffff)) { + lpt_log("Set handler: %04X-%04X\n", port, port + 0x0003); + io_sethandler(port, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, dev); + if (dev->epp) + io_sethandler(port + 0x0003, 0x0005, lpt_read, NULL, NULL, lpt_write, NULL, NULL, dev); + if (dev->ecp || dev->lv2) { + io_sethandler(port + 0x0400, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, dev); + if (dev->epp) + io_sethandler(port + 0x0404, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, dev); + } + } + dev->addr = port; + } else + dev->addr = 0xffff; +} + +void +lpt_port_irq(lpt_t *dev, const uint8_t irq) +{ + if (lpt_ports[dev->id].enabled) + dev->irq = irq; + else + dev->irq = 0xff; + + lpt_log("Port %i IRQ = %02X\n", dev->id, irq); +} + +void +lpt_port_dma(lpt_t *dev, const uint8_t dma) +{ + if (lpt_ports[dev->id].enabled) + dev->dma = dma; + else + dev->dma = 0xff; + + lpt_log("Port %i DMA = %02X\n", dev->id, dma); +} + +void +lpt_port_remove(lpt_t *dev) +{ + if (lpt_ports[dev->id].enabled && (dev->addr != 0xffff)) { + io_removehandler(dev->addr, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, dev); + io_removehandler(dev->addr + 0x0400, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, dev); + + dev->addr = 0xffff; + } +} + +void +lpt1_remove_ams(lpt_t *dev) +{ + if (dev->enabled) + io_removehandler(dev->addr + 1, 0x0002, lpt_read, NULL, NULL, lpt_write, NULL, NULL, dev); +} + +void +lpt_speed_changed(void *priv) +{ + lpt_t *dev = (lpt_t *) priv; + + if (timer_is_enabled(&dev->fifo_out_timer)) { + timer_disable(&dev->fifo_out_timer); + timer_set_delay_u64(&dev->fifo_out_timer, (uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC)); + } +} + +void +lpt_port_zero(lpt_t *dev) +{ + lpt_t temp = { 0 }; + + temp.irq = dev->irq; + temp.id = dev->id; + temp.dt = dev->dt; + temp.fifo = dev->fifo; + temp.fifo_out_timer = dev->fifo_out_timer; + + if (lpt_ports[dev->id].enabled) + lpt_port_remove(dev); + + memset(dev, 0x00, sizeof(lpt_t)); + + dev->addr = 0xffff; + dev->irq = temp.irq; + dev->id = temp.id; + dev->dt = temp.dt; + dev->fifo = temp.fifo; + dev->fifo_out_timer = temp.fifo_out_timer; + + if (machine_has_bus(machine, MACHINE_BUS_MCA)) + dev->ext = 1; +} + +static void +lpt_close(void *priv) +{ + lpt_t *dev = (lpt_t *) priv; + + if (lpt_ports[dev->id].enabled) { + fifo_close(dev->fifo); + dev->fifo = NULL; + + timer_disable(&dev->fifo_out_timer); + + } + + free(dev); +} + +static void +lpt_reset(void *priv) +{ + lpt_t *dev = (lpt_t *) priv; + + if (lpt_ports[dev->id].enabled) + if (timer_is_enabled(&dev->fifo_out_timer)) + timer_disable(&dev->fifo_out_timer); + + lpt_port_zero(dev); + + if (lpt_ports[dev->id].enabled) { + if (dev->irq_state) { + if (dev->irq == 0xff) + dev->irq_state = 0x00; + else { + picintclevel(dev->irq, &dev->irq_state); + picintc(dev->irq); + } + } + + dev->enable_irq = 0x00; + dev->ext = !!(machine_has_bus(machine, MACHINE_BUS_MCA)); + dev->epp = 0; + dev->ecp = 0; + dev->ecr = 0x15; + dev->dat = 0xff; + dev->fifo_stat = 0x00; + dev->dma_stat = 0x00; + } +} + +static void * +lpt_init(const device_t *info) +{ + lpt_t *dev = (lpt_t *) calloc(1, sizeof(lpt_t)); + int orig_inst = next_inst; + + const uint16_t default_ports[PARALLEL_MAX] = { LPT1_ADDR, LPT2_ADDR, LPT_MDA_ADDR, LPT4_ADDR }; + const uint8_t default_irqs[PARALLEL_MAX] = { LPT1_IRQ, LPT2_IRQ, LPT_MDA_IRQ, LPT4_IRQ }; + + if (info->local & 0xFFF00000) + next_inst = PARALLEL_MAX - 1; + + dev->id = next_inst; + + if (lpt_ports[next_inst].enabled || (info->local & 0xFFF00000)) { + lpt_log("Adding parallel port %i...\n", next_inst); + dev->dt = &(lpt_devs[next_inst]); + dev->dt->lpt = dev; + + dev->fifo = NULL; + memset(&dev->fifo_out_timer, 0x00, sizeof(pc_timer_t)); + + lpt_port_zero(dev); + + dev->addr = 0xffff; + dev->irq = 0xff; + dev->dma = 0xff; + dev->enable_irq = 0x00; + dev->ext = 0; + dev->epp = 0; + dev->ecp = 0; + dev->ecr = 0x15; + dev->cnfga_readout = 0x14; + + if (lpt_ports[dev->id].enabled) { + if (info->local & 0xfff00000) { + lpt_port_setup(dev, info->local >> 20); + lpt_port_irq(dev, (info->local >> 16) & 0xF); + next_inst = orig_inst; + } else { + if ((dev->id == 2) && (lpt_3bc_used)) { + lpt_port_setup(dev, LPT1_ADDR); + lpt_port_irq(dev, LPT1_IRQ); + } else { + lpt_port_setup(dev, default_ports[dev->id]); + lpt_port_irq(dev, default_irqs[dev->id]); + } + } + + dev->fifo = fifo16_init(); + + fifo_set_trigger_len(dev->fifo, 8); + + fifo_set_d_ready_evt(dev->fifo, lpt_fifo_d_ready_evt); + fifo_set_priv(dev->fifo, dev); + + timer_add(&dev->fifo_out_timer, lpt_fifo_out_callback, dev, 0); + } + } + + if (!(info->local & 0xfff00000)) + next_inst++; + + return dev; +} + +void +lpt_set_next_inst(int ni) +{ + next_inst = ni; +} + +void +lpt_set_3bc_used(int is_3bc_used) +{ + lpt_3bc_used = is_3bc_used; +} + +void +lpt_standalone_init(void) +{ + while (next_inst < (PARALLEL_MAX - 1)) + device_add_inst(&lpt_port_device, next_inst + 1); +}; + +const device_t lpt_port_device = { + .name = "Parallel Port", + .internal_name = "lpt", + .flags = 0, + .local = 0, + .init = lpt_init, + .close = lpt_close, + .reset = lpt_reset, + .available = NULL, + .speed_changed = lpt_speed_changed, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/device/mouse.c b/src/device/mouse.c index 0bf87934d..2cf47c096 100644 --- a/src/device/mouse.c +++ b/src/device/mouse.c @@ -83,24 +83,29 @@ static const device_t mouse_internal_device = { static mouse_t mouse_devices[] = { // clang-format off - { &mouse_none_device }, - { &mouse_internal_device }, - { &mouse_logibus_device }, - { &mouse_msinport_device }, + { &mouse_none_device }, + { &mouse_internal_device }, + { &mouse_logibus_device }, + { &mouse_msinport_device }, #ifdef USE_GENIBUS - { &mouse_genibus_device }, + { &mouse_genibus_device }, +#endif + + { &mouse_mssystems_device }, + { &mouse_mssystems_bus_device }, + { &mouse_msserial_device }, + { &mouse_msserial_ballpoint_device }, + { &mouse_ltserial_device }, + { &mouse_ps2_device }, +#ifdef USE_STANDALONE_QUICKPORT + { &mouse_upc_standalone_device }, #endif - { &mouse_mssystems_device }, - { &mouse_mssystems_bus_device }, - { &mouse_msserial_device }, - { &mouse_ltserial_device }, - { &mouse_ps2_device }, #ifdef USE_WACOM - { &mouse_wacom_device }, - { &mouse_wacom_artpad_device }, + { &mouse_wacom_device }, + { &mouse_wacom_artpad_device }, #endif - { &mouse_mtouch_device }, - { NULL } + { &mouse_mtouch_device }, + { NULL } // clang-format on }; diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 0d34235fe..80d9f3876 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -10,7 +10,7 @@ * * Authors: Miran Grca, * - * Copyright 2023 Miran Grca. + * Copyright 2023-2025 Miran Grca. */ #include #include @@ -21,7 +21,6 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> -#include "cpu.h" #include <86box/device.h> #include <86box/keyboard.h> #include <86box/mouse.h> @@ -333,13 +332,13 @@ ps2_poll(void *priv) atkbc_dev_t *dev = (atkbc_dev_t *) priv; int packet_size = (dev->flags & FLAG_INTMODE) ? 4 : 3; - 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))); + int cond = (mouse_capture || video_fullscreen) && mouse_scan && (dev->mode == MODE_STREAM) && + mouse_state_changed() && (kbc_at_dev_queue_pos(dev, 1) < (FIFO_SIZE - packet_size)); - if (!cond && (dev->mode == MODE_STREAM)) + if (cond) ps2_report_coordinates(dev, 1); - return cond; + return !cond; } /* @@ -353,6 +352,9 @@ mouse_ps2_init(const device_t *info) atkbc_dev_t *dev = kbc_at_dev_init(DEV_AUX); int i; + if (info->local & MOUSE_TYPE_QPORT) + device_context(&mouse_upc_standalone_device); + dev->name = info->name; dev->type = info->local; @@ -382,6 +384,9 @@ mouse_ps2_init(const device_t *info) mouse_set_poll(ps2_poll, dev); + if (info->local & MOUSE_TYPE_QPORT) + device_context_restore(); + /* Return our private data to the I/O layer. */ return dev; } diff --git a/src/device/mouse_serial.c b/src/device/mouse_serial.c index 7505cf3a3..45750ef09 100644 --- a/src/device/mouse_serial.c +++ b/src/device/mouse_serial.c @@ -50,7 +50,7 @@ enum { FORMAT_MM_SERIES = 0x13, FORMAT_PB_3BYTE, FORMAT_PB_5BYTE, - FORMAT_MSYSTEMS = 0x15, /* Alias for FORMAT_PB_5BYTE. */ + FORMAT_MSYSTEMS = 0x15, /* Alias for FORMAT_PB_5BYTE. */ FORMAT_MS, FORMAT_HEX, FORMAT_MS_4BYTE, @@ -59,45 +59,46 @@ enum { }; typedef struct mouse_t { - const char *name; /* name of this device */ + const char *name; /* name of this device */ - uint8_t id[252]; - uint8_t buf[256]; + uint8_t id[252]; + uint8_t buf[256]; - uint8_t flags; /* device flags */ - uint8_t but; - uint8_t rts_toggle; - uint8_t status; - uint8_t format; - uint8_t prompt; + uint8_t flags; /* device flags */ + uint8_t but; + uint8_t rts_toggle; + uint8_t status; + uint8_t format; + uint8_t prompt; - uint8_t continuous; - uint8_t ib; - uint8_t command; - uint8_t buf_len; - uint8_t report_mode; - uint8_t id_len; - uint8_t buf_pos; - uint8_t rev; + uint8_t continuous; + uint8_t ib; + uint8_t command; + uint8_t buf_len; + uint8_t report_mode; + uint8_t id_len; + uint8_t buf_pos; + uint8_t rev; - int8_t type; /* type of this device */ - int8_t port; + int8_t type; /* type of this device */ + int8_t port; - int state; + int state; - int bps; - int rps; + int bps; + int default_bps; + int rps; - double transmit_period; - double report_period; - double cur_period; - double min_bit_period; - double acc_time; - double host_transmit_period; + double transmit_period; + double report_period; + double cur_period; + double min_bit_period; + double acc_time; + double host_transmit_period; - pc_timer_t timer; + pc_timer_t timer; - serial_t * serial; + serial_t *serial; } mouse_t; #define FLAG_INPORT 0x80 /* device is MS InPort */ @@ -128,7 +129,7 @@ mouse_serial_log(const char *fmt, ...) static void sermouse_set_period(mouse_t *dev, double period) { - dev->cur_period = period; /* Needed for the recalculation of the timings. */ + dev->cur_period = period; /* Needed for the recalculation of the timings. */ timer_stop(&dev->timer); @@ -160,7 +161,7 @@ sermouse_transmit_byte(mouse_t *dev, int do_next) 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->state = to_report ? STATE_TRANSMIT_REPORT : STATE_TRANSMIT; dev->buf_pos = 0; dev->buf_len = len; @@ -186,7 +187,7 @@ sermouse_report_msystems(mouse_t *dev) { int delta_x = 0; int delta_y = 0; - int b = mouse_get_buttons_ex(); + int b = mouse_get_buttons_ex(); mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 1, 0); @@ -195,12 +196,12 @@ sermouse_report_msystems(mouse_t *dev) if (dev->but >= 3) dev->buf[0] |= (b & 0x04) ? 0x00 : 0x02; /* middle button */ else - dev->buf[0] |= 0x02; /* middle button */ + 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 */ + dev->buf[3] = delta_x; /* same as byte 1 */ + dev->buf[4] = delta_y; /* same as byte 2 */ return 5; } @@ -210,7 +211,7 @@ sermouse_report_3bp(mouse_t *dev) { int delta_x = 0; int delta_y = 0; - int b = mouse_get_buttons_ex(); + int b = mouse_get_buttons_ex(); mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 1, 0); @@ -218,7 +219,7 @@ sermouse_report_3bp(mouse_t *dev) 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[0] |= (b & 0x02) ? 0x01 : 0x00; /* right button */ dev->buf[1] = delta_x; dev->buf[2] = delta_y; @@ -230,7 +231,7 @@ sermouse_report_mmseries(mouse_t *dev) { int delta_x = 0; int delta_y = 0; - int b = mouse_get_buttons_ex(); + int b = mouse_get_buttons_ex(); mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -127, 127, 1, 0); @@ -243,7 +244,7 @@ sermouse_report_mmseries(mouse_t *dev) 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[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]); @@ -256,7 +257,7 @@ sermouse_report_bp1(mouse_t *dev, int abs) { int delta_x = 0; int delta_y = 0; - int b = mouse_get_buttons_ex(); + int b = mouse_get_buttons_ex(); mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -2048, 2047, 1, abs); @@ -264,7 +265,7 @@ sermouse_report_bp1(mouse_t *dev, int abs) 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[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); @@ -277,17 +278,17 @@ 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(); + 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); + dev->buf[0] |= ((((delta_y & 0xFF) >> 6) & 0x03) << 2); + dev->buf[0] |= (((delta_x & 0xFF) >> 6) & 0x03); if (b & 0x01) dev->buf[0] |= 0x20; if (b & 0x02) @@ -295,7 +296,16 @@ sermouse_report_ms(mouse_t *dev) 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) { + if (dev->type == MOUSE_TYPE_MSBPOINT) { + len = 4; + dev->buf[3] = 0; + if (b & 0x4) + dev->buf[3] |= 0x8; + if (b & 0x8) + dev->buf[3] |= 0x4; + dev->buf[3] |= !!(delta_y < 0) ? 0x2 : 0; + dev->buf[3] |= !!(delta_x < 0) ? 0x1 : 0; + } else if (dev->but == 3) { len = 3; if (dev->format == FORMAT_MS) { if (b & 0x04) { @@ -325,18 +335,18 @@ sermouse_report_ms(mouse_t *dev) 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(); + 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 */ + but |= (b & 0x02) ? 0x01 : 0x00; /* right button */ sprintf(ret, "%01X%02X%02X", but & 0x0f, (int8_t) delta_x, (int8_t) delta_y); @@ -441,14 +451,14 @@ ltsermouse_set_report_period(mouse_t *dev, int rps) sermouse_set_period(dev, 0.0); dev->report_period = 0.0; - dev->continuous = 1; + dev->continuous = 1; } else { #if 0 if (rps > dev->max_rps) rps = dev->max_rps; #endif - dev->continuous = 0; + dev->continuous = 0; dev->report_period = 1000000.0 / ((double) rps); /* Actual spacing between reports. */ } @@ -470,21 +480,22 @@ ltsermouse_update_report_period(mouse_t *dev) } static void -ltsermouse_switch_baud_rate(mouse_t *dev, int next_state) +ltsermouse_switch_baud_rate(mouse_t *dev, int next_state, int prompt_off) { 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 */ + [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 */ + 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)); @@ -506,7 +517,7 @@ ltsermouse_switch_baud_rate(mouse_t *dev, int next_state) ltsermouse_set_report_period(dev, dev->rps); if (!dev->continuous && (next_state != STATE_BAUD_RATE)) { - if (dev->prompt) + if (dev->prompt && prompt_off) ltsermouse_set_prompt_mode(dev, 0); sermouse_transmit_report(dev, 0); @@ -531,18 +542,19 @@ sermouse_next_state(mouse_t *dev) static void ltsermouse_process_command(mouse_t *dev) { - int cmd_to_rps[9] = { 10, 20, 35, 70, 150, 0, -1, 100, 50 }; - int b; + 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 */ + [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); @@ -551,13 +563,13 @@ ltsermouse_process_command(mouse_t *dev) switch (dev->command) { case 0x20: /* Auto Baud Selection */ - dev->bps = (int) floor(1000000.0 / dev->host_transmit_period); + 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); + ltsermouse_switch_baud_rate(dev, STATE_BAUD_RATE, 0); break; case 0x4a: /* Report Rate Selection commands */ @@ -569,7 +581,7 @@ ltsermouse_process_command(mouse_t *dev) case 0x4e: case 0x4f: dev->report_mode = dev->command; - dev->rps = cmd_to_rps[dev->command - 0x4a]; + dev->rps = cmd_to_rps[dev->command - 0x4a]; ltsermouse_update_report_period(dev); break; @@ -593,16 +605,16 @@ ltsermouse_process_command(mouse_t *dev) /* 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) */ + 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)); + ltsermouse_switch_baud_rate(dev, sermouse_next_state(dev), 0); } break; @@ -620,7 +632,7 @@ ltsermouse_process_command(mouse_t *dev) break; case 0x05: /* Diagnostic */ - b = mouse_get_buttons_ex(); + 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); @@ -630,7 +642,7 @@ ltsermouse_process_command(mouse_t *dev) 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 */ + dev->buf[0] |= 0x10; /* Revision 3.0, 0x00 would be Revision 2.0 */ sermouse_transmit(dev, 1, 0, 0); } break; @@ -676,7 +688,7 @@ ltsermouse_process_data(mouse_t *dev) { mouse_serial_log("ltsermouse_process_data(): %02X (command = %02X)\n", dev->ib, dev->command); - switch(dev->command) { + switch (dev->command) { case 0x2a: switch (dev->ib) { default: @@ -694,7 +706,7 @@ ltsermouse_process_data(mouse_t *dev) dev->bps = 9600; break; } - ltsermouse_switch_baud_rate(dev, (dev->prompt || dev->continuous) ? STATE_IDLE : STATE_TRANSMIT_REPORT); + ltsermouse_switch_baud_rate(dev, (dev->prompt || dev->continuous) ? STATE_IDLE : STATE_TRANSMIT_REPORT, 0); break; default: dev->state = STATE_IDLE; @@ -707,25 +719,32 @@ sermouse_reset(mouse_t *dev, int callback) { sermouse_set_period(dev, 0.0); - dev->bps = 1200; - dev->rps = 0; + if (dev->default_bps) + dev->bps = dev->default_bps; + else + dev->bps = 1200; + dev->rps = 0; dev->prompt = 0; if (dev->id[0] == 'H') dev->format = FORMAT_MSYSTEMS; - else switch (dev->but) { - default: - case 2: - dev->format = FORMAT_MS; - break; - case 3: - dev->format = (dev->type == MOUSE_TYPE_LT3BUTTON) ? FORMAT_MS : FORMAT_MS_4BYTE; - break; - case 4: - dev->format = FORMAT_MS_WHEEL; - break; - } + else + switch (dev->but) { + default: + case 2: + dev->format = FORMAT_MS; + break; + case 3: + dev->format = (dev->type == MOUSE_TYPE_LT3BUTTON) ? FORMAT_MS : FORMAT_MS_4BYTE; + break; + case 4: + dev->format = FORMAT_MS_WHEEL; + break; + case 5: + dev->format = FORMAT_MS; + break; + } - ltsermouse_switch_baud_rate(dev, callback ? STATE_TRANSMIT : STATE_IDLE); + ltsermouse_switch_baud_rate(dev, callback ? STATE_TRANSMIT : STATE_IDLE, 1); } static void @@ -840,7 +859,7 @@ sermouse_close(void *priv) static void * sermouse_init(const device_t *info) { - mouse_t *dev; + mouse_t *dev = (mouse_t *) calloc(1, sizeof(mouse_t)); 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, @@ -850,34 +869,42 @@ sermouse_init(const device_t *info) uintptr_t irqbase = ((device_get_config_int("irq") << 16) | (device_get_config_hex16("addr") << 20)) | ns16450_device.local; - device_add_params(&ns16450_device, (void*)irqbase); + device_add_params(&ns16450_device, (void *) irqbase); } - dev = (mouse_t *) calloc(1, sizeof(mouse_t)); dev->name = info->name; - dev->but = device_get_config_int("buttons"); - dev->rev = device_get_config_int("revision"); + dev->but = (info->local == MOUSE_TYPE_MSBPOINT) ? 5 : device_get_config_int("buttons"); - if (info->local == 0) - dev->rts_toggle = 1; + if ((info->local == 0) || (info->local == MOUSE_TYPE_MSBPOINT)) + dev->rts_toggle = 1; else - dev->rts_toggle = device_get_config_int("rts_toggle"); + dev->rts_toggle = device_get_config_int("rts_toggle"); if (dev->but > 2) dev->flags |= FLAG_3BTN; - if (info->local == MOUSE_TYPE_MSYSTEMS || info->local == MOUSE_TYPE_MSYSTEMSB) { - dev->format = 0; - dev->type = info->local; - dev->id_len = 1; - dev->id[0] = 'H'; + if (info->local == MOUSE_TYPE_MSBPOINT) { + dev->format = 7; + dev->status = 0x0f; + dev->type = MOUSE_TYPE_MSBPOINT; + dev->id_len = 1; + dev->id[0] = 'B'; + dev->flags &= ~FLAG_3BTN; + } else if ((info->local == MOUSE_TYPE_MSYSTEMS) || (info->local == MOUSE_TYPE_MSYSTEMSB)) { + dev->format = 0; + dev->type = info->local; + dev->id_len = 1; + dev->id[0] = 'H'; } else { - dev->format = 7; - dev->status = 0x0f; - dev->id_len = 1; - dev->id[0] = 'M'; - if (info->local) - dev->rev = device_get_config_int("revision"); + dev->format = 7; + dev->status = 0x0f; + dev->id_len = 1; + dev->id[0] = 'M'; + if (info->local == 1) { + /* Logitech Serial Mouse */ + dev->rev = device_get_config_int("revision"); + dev->default_bps = device_get_config_int("default_baud"); + } switch (dev->but) { default: case 2: @@ -900,8 +927,8 @@ sermouse_init(const device_t *info) dev->port = (info->local == MOUSE_TYPE_MSYSTEMSB) ? (SERIAL_MAX - 1) : device_get_config_int("port"); /* Attach a serial port to the mouse. */ - rcr_callback = dev->rts_toggle ? sermouse_callback : NULL; - dev_write = (info->local == 1) ? ltsermouse_write : NULL; + 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, @@ -923,25 +950,28 @@ sermouse_init(const device_t *info) return dev; } +#define SERMOUSE_PORT_CONFIG_COMMON \ + { \ + .name = "port", \ + .description = "Serial Port", \ + .type = CONFIG_SELECTION, \ + .default_string = NULL, \ + .default_int = 0, \ + .file_filter = NULL, \ + .spinner = { 0 }, \ + .selection = { \ + { .description = "COM1", .value = 0 }, \ + { .description = "COM2", .value = 1 }, \ + { .description = "COM3", .value = 2 }, \ + { .description = "COM4", .value = 3 }, \ + { .description = "" } \ + }, \ + .bios = { { 0 } } \ + } + static const device_config_t msssermouse_config[] = { - // clang-format off - { - .name = "port", - .description = "Serial Port", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "COM1", .value = 0 }, - { .description = "COM2", .value = 1 }, - { .description = "COM3", .value = 2 }, - { .description = "COM4", .value = 3 }, - { .description = "" } - }, - .bios = { { 0 } } - }, + // clang-format off + SERMOUSE_PORT_CONFIG_COMMON, { .name = "buttons", .description = "Buttons", @@ -969,7 +999,7 @@ static const device_config_t msssermouse_config[] = { .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on + // clang-format on }; static const device_config_t mssbusmouse_config[] = { @@ -1042,27 +1072,11 @@ static const device_config_t mssbusmouse_config[] = { }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on - }; +}; static const device_config_t mssermouse_config[] = { - // clang-format off - { - .name = "port", - .description = "Serial Port", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "COM1", .value = 0 }, - { .description = "COM2", .value = 1 }, - { .description = "COM3", .value = 2 }, - { .description = "COM4", .value = 3 }, - { .description = "" } - }, - .bios = { { 0 } } - }, + // clang-format off + SERMOUSE_PORT_CONFIG_COMMON, { .name = "buttons", .description = "Buttons", @@ -1080,28 +1094,19 @@ static const device_config_t mssermouse_config[] = { .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on + // clang-format on +}; + +static const device_config_t msballpoint_config[] = { + // clang-format off + SERMOUSE_PORT_CONFIG_COMMON, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on }; static const device_config_t ltsermouse_config[] = { - // clang-format off - { - .name = "port", - .description = "Serial Port", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "COM1", .value = 0 }, - { .description = "COM2", .value = 1 }, - { .description = "COM3", .value = 2 }, - { .description = "COM4", .value = 3 }, - { .description = "" } - }, - .bios = { { 0 } } - }, + // clang-format off + SERMOUSE_PORT_CONFIG_COMMON, { .name = "buttons", .description = "Buttons", @@ -1134,19 +1139,36 @@ static const device_config_t ltsermouse_config[] = { }, .bios = { { 0 } } }, + { + .name = "default_baud", + .description = "Default Baud rate", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1200, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1200", .value = 1200 }, + { .description = "2400", .value = 2400 }, + { .description = "4800", .value = 4800 }, + { .description = "9600", .value = 9600 }, + { .description = "" } + }, + .bios = { { 0 } } + }, { .name = "rts_toggle", .description = "RTS toggle", .type = CONFIG_BINARY, .default_string = NULL, - .default_int = 0, + .default_int = 1, .file_filter = NULL, .spinner = { 0 }, .selection = { { 0 } }, .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on + // clang-format on }; const device_t mouse_mssystems_device = { @@ -1191,6 +1213,20 @@ const device_t mouse_msserial_device = { .config = mssermouse_config }; +const device_t mouse_msserial_ballpoint_device = { + .name = "Microsoft Serial BallPoint", + .internal_name = "msballpoint", + .flags = DEVICE_COM, + .local = MOUSE_TYPE_MSBPOINT, + .init = sermouse_init, + .close = sermouse_close, + .reset = NULL, + .available = NULL, + .speed_changed = sermouse_speed_changed, + .force_redraw = NULL, + .config = msballpoint_config +}; + const device_t mouse_ltserial_device = { .name = "Logitech Serial Mouse", .internal_name = "ltserial", diff --git a/src/device/mouse_upc.c b/src/device/mouse_upc.c new file mode 100644 index 000000000..7a8d6143e --- /dev/null +++ b/src/device/mouse_upc.c @@ -0,0 +1,444 @@ +/* + * 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 Chips & Technologies F82C710 Universal + * Peripheral Controller (UPC) PS/2 mouse port. + * + * Authors: Miran Grca, + * + * Copyright 2025 Miran Grca. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include +#include <86box/86box.h> +#include "cpu.h" +#include "x86seg.h" +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/pic.h> +#include <86box/keyboard.h> +#include <86box/mouse.h> + +#define STAT_DEV_IDLE 0x01 +#define STAT_RX_FULL 0x02 +#define STAT_TX_IDLE 0x04 +#define STAT_RESET 0x08 +#define STAT_INTS_ON 0x10 +#define STAT_ERROR_FLAG 0x20 +#define STAT_CLEAR 0x40 +#define STAT_ENABLE 0x80 + +typedef struct mouse_upc_t { + uint8_t status; + uint8_t ib; + uint8_t ob; + uint8_t state; + uint8_t ctrl_queue_start; + uint8_t ctrl_queue_end; + + uint8_t handler_enable[2]; + + uint16_t mdata_addr; + uint16_t mstat_addr; + + uint16_t irq; + + uint16_t base_addr[2]; + + /* Local copies of the pointers to both ports for easier swapping (AMI '5' MegaKey). */ + kbc_at_port_t *port; + + /* Main timers. */ + pc_timer_t poll_timer; + pc_timer_t dev_poll_timer; + + struct { + uint8_t (*read)(uint16_t port, void *priv); + void (*write)(uint16_t port, uint8_t val, void *priv); + } handlers[2]; + + void *mouse_ps2; +} mouse_upc_t; + +enum { + STATE_MAIN_IBF, /* UPC checking if the input buffer is full. */ + STATE_MAIN, /* UPC checking if the auxiliary has anything to send. */ + STATE_OUT, /* UPC is sending multiple bytes. */ + STATE_SEND, /* UPC is sending command to the auxiliary device. */ + STATE_SCAN /* UPC is waiting for the auxiliary command response. */ +}; + +#ifdef ENABLE_MOUSE_UPC_LOG +int mouse_upc_do_log = ENABLE_MOUSE_UPC_LOG; + +static void +mouse_upc_log(const char *fmt, ...) +{ + va_list ap; + + if (mouse_upc_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define mouse_upc_log(fmt, ...) +#endif + +static void +mouse_upc_send_to_ob(mouse_upc_t *dev, uint8_t val) +{ + dev->status = (dev->status & ~STAT_DEV_IDLE) | STAT_RX_FULL; + + if (dev->status & STAT_INTS_ON) { + picint_common(1 << dev->irq, 0, 0, NULL); + picint_common(1 << dev->irq, 0, 1, NULL); + } + + dev->ob = val; +} + +static void +set_enable_aux(mouse_upc_t *dev, uint8_t enable) +{ + dev->status &= ~STAT_ENABLE; + dev->status |= (enable ? STAT_ENABLE : 0x00); +} + +static void +mouse_upc_ibf_process(mouse_upc_t *dev) +{ + /* IBF set, process both commands and data. */ + dev->status |= STAT_TX_IDLE; + dev->state = STATE_MAIN_IBF; + + set_enable_aux(dev, 1); + + if (dev->port != NULL) { + dev->port->wantcmd = 1; + dev->port->dat = dev->ib; + dev->state = STATE_SEND; + } +} + +/* + Correct Procedure: + 1. Controller asks the device (keyboard or auxiliary device) for a byte. + 2. The device, unless it's in the reset or command states, sees if there's anything to give it, + and if yes, begins the transfer. + 3. The controller checks if there is a transfer, if yes, transfers the byte and sends it to the host, + otherwise, checks the next device, or if there is no device left to check, checks if IBF is full + and if yes, processes it. + */ +static int +mouse_upc_scan(mouse_upc_t *dev) +{ + if ((dev->port != NULL) && (dev->port->out_new != -1)) { + mouse_upc_log("UPC Mouse: %02X coming\n", dev->port->out_new & 0xff); + mouse_upc_send_to_ob(dev, dev->port->out_new); + dev->port->out_new = -1; + dev->state = STATE_MAIN_IBF; + return 1; + } + + return 0; +} + +static void +mouse_upc_poll(void *priv) +{ + mouse_upc_t *dev = (mouse_upc_t *) priv; + + timer_advance_u64(&dev->poll_timer, (100ULL * TIMER_USEC)); + + switch (dev->state) { + case STATE_MAIN_IBF: + default: + if (!(dev->status & STAT_TX_IDLE)) + mouse_upc_ibf_process(dev); + else if (!(dev->status & STAT_RX_FULL)) { + if (dev->status & STAT_ENABLE) + dev->state = STATE_MAIN; + } + break; + case STATE_MAIN: + if (!(dev->status & STAT_TX_IDLE)) + mouse_upc_ibf_process(dev); + else { + (void) mouse_upc_scan(dev); + dev->state = STATE_MAIN_IBF; + } + break; + case STATE_SEND: + if (!dev->port->wantcmd) + dev->state = STATE_SCAN; + break; + case STATE_SCAN: + (void) mouse_upc_scan(dev); + break; + } +} + +static void +mouse_upc_dev_poll(void *priv) +{ + mouse_upc_t *dev = (mouse_upc_t *) priv; + + timer_advance_u64(&dev->dev_poll_timer, (100ULL * TIMER_USEC)); + + if ((dev->port != NULL) && (dev->port->priv != NULL)) + dev->port->poll(dev->port->priv); +} + +static void +mouse_upc_port_1_write(uint16_t port, uint8_t val, void *priv) +{ + mouse_upc_t *dev = (mouse_upc_t *) priv; + + mouse_upc_log("UPC Mouse: [%04X:%08X] write(%04X) = %02X\n", CS, cpu_state.pc, port, val); + + if ((dev->status & STAT_TX_IDLE) && (dev->status & STAT_ENABLE)) { + dev->ib = val; + dev->status &= ~STAT_TX_IDLE; + } +} + +static void +mouse_upc_port_2_write(uint16_t port, uint8_t val, void *priv) +{ + mouse_upc_t *dev = (mouse_upc_t *) priv; + + mouse_upc_log("UPC Mouse: [%04X:%08X] write(%04X) = %02X\n", CS, cpu_state.pc, port, val); + + dev->status = (dev->status & 0x27) | (val & 0xd8); + + if (dev->status & (STAT_CLEAR | STAT_RESET)) { + /* TODO: Silently reset the mouse. */ + } +} + +static uint8_t +mouse_upc_port_1_read(uint16_t port, void *priv) +{ + mouse_upc_t *dev = (mouse_upc_t *) priv; + uint8_t ret = 0xff; + + cycles -= ISA_CYCLES(8); + + ret = dev->ob; + dev->ob = 0xff; + dev->status &= ~STAT_RX_FULL; + dev->status |= STAT_DEV_IDLE; + + mouse_upc_log("UPC Mouse: [%04X:%08X] read (%04X) = %02X\n", CS, cpu_state.pc, port, ret); + + return ret; +} + +static uint8_t +mouse_upc_port_2_read(uint16_t port, void *priv) +{ + mouse_upc_t *dev = (mouse_upc_t *) priv; + uint8_t ret = 0xff; + + cycles -= ISA_CYCLES(8); + + ret = dev->status; + + mouse_upc_log("UPC Mouse: [%04X:%08X] read (%04X) = %02X\n", CS, cpu_state.pc, port, ret); + + return ret; +} + +static void +mouse_upc_reset(void *priv) +{ + mouse_upc_t *dev = (mouse_upc_t *) priv; + + dev->status = STAT_DEV_IDLE | STAT_TX_IDLE; + dev->ob = 0xff; + + dev->state = STATE_MAIN_IBF; +} + +static void +mouse_upc_close(void *priv) +{ + mouse_upc_t *dev = (mouse_upc_t *) priv; + + /* Stop timers. */ + timer_disable(&dev->dev_poll_timer); + timer_disable(&dev->poll_timer); + + if (kbc_at_ports[1] != NULL) { + free(kbc_at_ports[1]); + kbc_at_ports[1] = NULL; + } + + free(dev); +} + +void +mouse_upc_port_handler(int num, int set, uint16_t port, void *priv) +{ + mouse_upc_t *dev = (mouse_upc_t *) priv; + + if (dev->handler_enable[num] && (dev->base_addr[num] != 0x0000)) + io_removehandler(dev->base_addr[num], 1, + dev->handlers[num].read, NULL, NULL, + dev->handlers[num].write, NULL, NULL, priv); + + dev->handler_enable[num] = set; + dev->base_addr[num] = port; + + if (dev->handler_enable[num] && (dev->base_addr[num] != 0x0000)) + io_sethandler(dev->base_addr[num], 1, + dev->handlers[num].read, NULL, NULL, + dev->handlers[num].write, NULL, NULL, priv); +} + +void +mouse_upc_handler(int set, uint16_t port, void *priv) +{ + mouse_upc_port_handler(0, set, port, priv); + mouse_upc_port_handler(1, set, port + 0x0001, priv); +} + +void +mouse_upc_set_irq(int num, uint16_t irq, void *priv) +{ + mouse_upc_t *dev = (mouse_upc_t *) priv; + + if (dev->irq != 0xffff) + picintc(1 << dev->irq); + + dev->irq = irq; +} + +static void * +mouse_upc_init_common(int standalone, int irq) +{ + mouse_upc_t *dev; + + dev = (mouse_upc_t *) calloc(1, sizeof(mouse_upc_t)); + + mouse_upc_reset(dev); + + dev->handlers[0].read = mouse_upc_port_1_read; + dev->handlers[0].write = mouse_upc_port_1_write; + dev->handlers[1].read = mouse_upc_port_2_read; + dev->handlers[1].write = mouse_upc_port_2_write; + + dev->irq = irq; + + if (kbc_at_ports[1] == NULL) { + kbc_at_ports[1] = (kbc_at_port_t *) calloc(1, sizeof(kbc_at_port_t)); + kbc_at_ports[1]->out_new = -1; + } + + dev->port = kbc_at_ports[1]; + + timer_add(&dev->poll_timer, mouse_upc_poll, dev, 1); + timer_add(&dev->dev_poll_timer, mouse_upc_dev_poll, dev, 1); + + if (standalone) { + mouse_upc_handler(1, 0x02d4, dev); + dev->mouse_ps2 = device_add_params(&mouse_ps2_device, (void *) (uintptr_t) MOUSE_TYPE_PS2_QPORT); + } + + return dev; +} + +static void * +mouse_upc_init(const device_t *info) +{ + void *dev = NULL; + + if (info->local == 1) + dev = mouse_upc_init_common(1, device_get_config_int("irq")); + else + dev = mouse_upc_init_common(0, info->local); + + return dev; +} + +static const device_config_t upc_config[] = { + // clang-format off + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 12, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 12", .value = 12 }, + { .description = "IRQ 2/9", .value = 2 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "buttons", + .description = "Buttons", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Two", .value = 2 }, + { .description = "Three", .value = 3 }, + { .description = "Wheel", .value = 4 }, + { .description = "Five + Wheel", .value = 5 }, + { .description = "Five + 2 Wheels", .value = 6 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "", .description = "", .type = CONFIG_END + } + // clang-format on +}; + +const device_t mouse_upc_device = { + .name = "PS/2 QuickPort Mouse (F82C710)", + .internal_name = "mouse_upc", + .flags = DEVICE_ISA, + .local = 0, + .init = mouse_upc_init, + .close = mouse_upc_close, + .reset = mouse_upc_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t mouse_upc_standalone_device = { + .name = "PS/2 QuickPort Mouse", + .internal_name = "mouse_upc_standalone", + .flags = DEVICE_ISA, + .local = 1, + .init = mouse_upc_init, + .close = mouse_upc_close, + .reset = mouse_upc_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = upc_config +}; diff --git a/src/device/novell_cardkey.c b/src/device/novell_cardkey.c index 8820addde..edc32b879 100644 --- a/src/device/novell_cardkey.c +++ b/src/device/novell_cardkey.c @@ -37,24 +37,29 @@ novell_cardkey_read(uint16_t port, void *priv) novell_cardkey_t* cardkey = (novell_cardkey_t*)priv; uint8_t val = 0x00; switch (port) { + /* Byte 5 high nibble + byte 4 high nibble */ case 0x23A: - val = (((cardkey->serial_number_str[11] > 'A') ? ((cardkey->serial_number_str[11] - 'A') + 10) : (cardkey->serial_number_str[11] - '0')) << 4) | (((cardkey->serial_number_str[9] > 'A') ? ((cardkey->serial_number_str[9] - 'A') + 10) : (cardkey->serial_number_str[9] - '0')) << 4); - break; - case 0x23B: val = (((cardkey->serial_number_str[10] > 'A') ? ((cardkey->serial_number_str[10] - 'A') + 10) : (cardkey->serial_number_str[10] - '0')) << 4) | (((cardkey->serial_number_str[8] > 'A') ? ((cardkey->serial_number_str[8] - 'A') + 10) : (cardkey->serial_number_str[8] - '0')) << 4); break; - + /* Byte 5 low nibble + byte 4 low nibble */ + case 0x23B: + val = (((cardkey->serial_number_str[11] > 'A') ? ((cardkey->serial_number_str[11] - 'A') + 10) : (cardkey->serial_number_str[11] - '0')) << 4) | (((cardkey->serial_number_str[9] > 'A') ? ((cardkey->serial_number_str[9] - 'A') + 10) : (cardkey->serial_number_str[9] - '0')) << 4); + break; + /* Byte 2 low nibble + byte 1 low nibble */ case 0x23C: - val = ((cardkey->serial_number_str[4] - '0') << 4) | ((cardkey->serial_number_str[2] - '0')); + val = ((cardkey->serial_number_str[5] - '0') << 4) | ((cardkey->serial_number_str[3] - '0')); break; + /* Byte 0 high nibble + byte 3 low nibble*/ case 0x23D: - val = ((cardkey->serial_number_str[1] - '0') << 4) | ((cardkey->serial_number_str[6] - '0')); - break; - case 0x23E: val = ((cardkey->serial_number_str[0] - '0') << 4) | ((cardkey->serial_number_str[7] - '0')); break; + /* Byte 0 low nibble + byte 3 high nibble */ + case 0x23E: + val = ((cardkey->serial_number_str[1] - '0') << 4) | ((cardkey->serial_number_str[6] - '0')); + break; + /* Byte 1 high nibble + byte 2 high nibble*/ case 0x23F: - val = ((cardkey->serial_number_str[3] - '0') << 4) | ((cardkey->serial_number_str[5] - '0')); + val = ((cardkey->serial_number_str[2] - '0') << 4) | ((cardkey->serial_number_str[4] - '0')); break; } return val ^ 0xFF; @@ -109,8 +114,8 @@ static const device_config_t keycard_config[] = { }; const device_t novell_keycard_device = { - .name = "Novell Netware 2.x Key Card", - .internal_name = "mssystems", + .name = "Novell NetWare 2.x Key Card", + .internal_name = "novellkeycard", .flags = DEVICE_ISA, .local = 0, .init = novell_cardkey_init, diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index 7dda00aee..bf49baf14 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -30,8 +30,10 @@ #include <86box/mem.h> #include <86box/device.h> #include <86box/pci.h> +#include <86box/plat_fallthrough.h> #define PCI_BRIDGE_DEC_21150 0x10110022 +#define PCI_BRIDGE_DEC_21152 0x10110024 #define AGP_BRIDGE_ALI_M5243 0x10b95243 #define AGP_BRIDGE_ALI_M5247 0x10b95247 #define AGP_BRIDGE_INTEL_440LX 0x80867181 @@ -85,6 +87,14 @@ pci_bridge_set_ctl(void *priv, uint8_t ctl) dev->ctl = ctl; } +uint8_t +pci_bridge_get_bus_index(void *priv) +{ + pci_bridge_t *dev = (pci_bridge_t *) priv; + + return dev->bus_index; +} + static void pci_bridge_write(int func, int addr, uint8_t val, void *priv) { @@ -242,12 +252,15 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) case 0x40: if (dev->local == PCI_BRIDGE_DEC_21150) val &= 0x32; + else if (dev->local == PCI_BRIDGE_DEC_21152) + val &= 0x12; break; case 0x41: if (AGP_BRIDGE_VIA(dev->local)) val &= 0x7e; - else if (dev->local == PCI_BRIDGE_DEC_21150) + else if ((dev->local == PCI_BRIDGE_DEC_21150) || + (dev->local == PCI_BRIDGE_DEC_21152)) val &= 0x07; break; @@ -257,18 +270,22 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) break; case 0x43: - if (dev->local == PCI_BRIDGE_DEC_21150) + if ((dev->local == PCI_BRIDGE_DEC_21150) || + (dev->local == PCI_BRIDGE_DEC_21152)) val &= 0x03; break; case 0x64: - if (dev->local == PCI_BRIDGE_DEC_21150) + if ((dev->local == PCI_BRIDGE_DEC_21150) || + (dev->local == PCI_BRIDGE_DEC_21152)) val &= 0x7e; break; case 0x69: if (dev->local == PCI_BRIDGE_DEC_21150) val &= 0x3f; + else if (dev->local == PCI_BRIDGE_DEC_21152) + val = (val & 0x01) | 0x3e; break; case 0x86: @@ -302,6 +319,15 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) break; case 0xe0: + if (AGP_BRIDGE_ALI(dev->local)) { + if (!(dev->ctl & 0x20)) + return; + } else if (dev->local == PCI_BRIDGE_DEC_21152) + val &= 0x03; + else + return; + break; + case 0xe1: if (AGP_BRIDGE_ALI(dev->local)) { if (!(dev->ctl & 0x20)) @@ -399,6 +425,14 @@ pci_bridge_reset(void *priv) /* command and status */ switch (dev->local) { + case PCI_BRIDGE_DEC_21152: + dev->regs[0x08] = 0x03; + dev->regs[0x34] = 0xdc; + dev->regs[0x69] = 0x3e; + dev->regs[0xdc] = 0x01; + dev->regs[0xde] = 0x01; + dev->regs[0xe2] = 0x80; + fallthrough; case PCI_BRIDGE_DEC_21150: dev->regs[0x06] = 0x80; dev->regs[0x07] = 0x02; @@ -487,8 +521,8 @@ static void * pci_bridge_init(const device_t *info) { uint8_t interrupts[4]; - uint8_t interrupt_count; uint8_t interrupt_mask; + uint8_t add_type; uint8_t slot_count; pci_bridge_t *dev = (pci_bridge_t *) calloc(1, sizeof(pci_bridge_t)); @@ -499,22 +533,27 @@ pci_bridge_init(const device_t *info) pci_bridge_reset(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; + interrupt_mask = sizeof(interrupts) - 1; if (dev->slot < 32) { - for (uint8_t i = 0; i < interrupt_count; i++) + for (uint8_t i = 0; i <= interrupt_mask; 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]); - if (info->local == PCI_BRIDGE_DEC_21150) + if (info->local == PCI_BRIDGE_DEC_21150) { slot_count = 9; /* 9 bus masters */ - else + add_type = PCI_ADD_NORMAL; + } else if (info->local == PCI_BRIDGE_DEC_21152) { + slot_count = 0; /* 4 bus masters, but slots are added by the Dell machines */ + add_type = PCI_ADD_BRIDGE; + } else { slot_count = 1; /* AGP bridges always have 1 slot */ + add_type = PCI_ADD_AGPBRIDGE; + } + + pci_add_bridge(add_type, pci_bridge_read, pci_bridge_write, dev, &dev->slot); for (uint8_t i = 0; i < slot_count; i++) { /* Interrupts for bridge slots are assigned in round-robin: ABCD, BCDA, CDAB and so on. */ @@ -547,6 +586,20 @@ const device_t dec21150_device = { .config = NULL }; +const device_t dec21152_device = { + .name = "DEC 21152 PCI Bridge", + .internal_name = "dec21152", + .flags = DEVICE_PCI, + .local = PCI_BRIDGE_DEC_21152, + .init = pci_bridge_init, + .close = NULL, + .reset = pci_bridge_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + /* AGP bridges */ const device_t ali5243_agp_device = { .name = "ALi M5243 AGP Bridge", diff --git a/src/device/postcard.c b/src/device/postcard.c index 9e2c629c1..ec031c2b8 100644 --- a/src/device/postcard.c +++ b/src/device/postcard.c @@ -30,11 +30,14 @@ #include "cpu.h" uint8_t postcard_codes[POSTCARDS_NUM]; +char postcard_diags[5] = { 0 }; static uint16_t postcard_port; static uint8_t postcard_written[POSTCARDS_NUM]; static uint8_t postcard_ports_num = 1; static uint8_t postcard_prev_codes[POSTCARDS_NUM]; +static uint8_t postcard_dell_mode = 0; +static char postcard_prev_diags[5] = { 0 }; #define UISTR_LEN 32 static char postcard_str[UISTR_LEN]; /* UI output string */ @@ -98,12 +101,22 @@ postcard_setui(void) break; } } else { + char dell_diags[11] = { 0 }; + if (postcard_dell_mode) { + if (!postcard_written[1]) + snprintf(dell_diags, sizeof(dell_diags), " ---- ----"); + else if (postcard_written[1] == 1) + snprintf(dell_diags, sizeof(dell_diags), " %s ----", postcard_diags); + else + snprintf(dell_diags, sizeof(dell_diags), " %s %s", postcard_diags, postcard_prev_diags); + } + if (!postcard_written[0]) - snprintf(postcard_str, sizeof(postcard_str), "POST: -- --"); + snprintf(postcard_str, sizeof(postcard_str), "POST: -- --%s", dell_diags); else if (postcard_written[0] == 1) - snprintf(postcard_str, sizeof(postcard_str), "POST: %02X --", postcard_codes[0]); + snprintf(postcard_str, sizeof(postcard_str), "POST: %02X --%s", postcard_codes[0], dell_diags); else - snprintf(postcard_str, sizeof(postcard_str), "POST: %02X %02X", postcard_codes[0], postcard_prev_codes[0]); + snprintf(postcard_str, sizeof(postcard_str), "POST: %02X %02X%s", postcard_codes[0], postcard_prev_codes[0], dell_diags); } ui_sb_bugui(postcard_str); @@ -122,6 +135,9 @@ postcard_reset(void) memset(postcard_codes, 0x00, POSTCARDS_NUM * sizeof(uint8_t)); memset(postcard_prev_codes, 0x00, POSTCARDS_NUM * sizeof(uint8_t)); + memset(postcard_diags, 0x00, 5 * sizeof(char)); + memset(postcard_prev_diags, 0x00, 5 * sizeof(char)); + postcard_setui(); } @@ -140,6 +156,35 @@ postcard_write(uint16_t port, uint8_t val, UNUSED(void *priv)) postcard_setui(); } +static int +postcard_cmp_diags(uint32_t val) +{ + int ret = 0; + char *pv = (char *) &val; + + for (int i = 0; i < 4; i++) + ret = ret || (pv[i] != postcard_diags[3 - i]); + + return ret; +} + +static void +postcard_writel(uint16_t port, uint32_t val, UNUSED(void *priv)) +{ + char *pv = (char *) &val; + + if (postcard_written[1] && !postcard_cmp_diags(val)) + return; + + *(uint32_t *) postcard_prev_diags = *(uint32_t *) postcard_diags; + for (int i = 0; i < 4; i++) + postcard_diags[i] = pv[3 - i]; + if (postcard_written[1] < 2) + postcard_written[1]++; + + postcard_setui(); +} + static void * postcard_init(UNUSED(const device_t *info)) { @@ -147,17 +192,22 @@ postcard_init(UNUSED(const device_t *info)) if (machine_has_bus(machine, MACHINE_BUS_MCA)) postcard_port = 0x680; /* MCA machines */ - else if (strstr(machines[machine].name, " PS/2 ") || strstr(machine_getname_ex(machine), " PS/1 ")) + else if (strstr(machines[machine].name, " PS/2 ") || + strstr(machine_getname_ex(machine), " PS/1 ")) 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")) { postcard_port = 0x10; /* IBM PCjr */ 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)) + } else if (strstr(machines[machine].name, " Compaq ") && + !strstr(machines[machine].name, " Presario ") && + !strstr(machines[machine].name, " ProSignia ")) postcard_port = 0x84; /* ISA Compaq machines */ else if (strstr(machines[machine].name, "Olivetti")) postcard_port = 0x378; /* Olivetti machines */ + else if (!strcmp(machines[machine].internal_name, "isa486c")) + postcard_port = 0x5080; /* ASUS ISA-486C */ else postcard_port = 0x80; /* AT and clone machines */ postcard_log("POST card initializing on port %04Xh\n", postcard_port); @@ -168,6 +218,12 @@ postcard_init(UNUSED(const device_t *info)) io_sethandler(postcard_port, postcard_ports_num, NULL, NULL, NULL, postcard_write, NULL, NULL, NULL); + postcard_dell_mode = strstr(machines[machine].name, " Dell ") && + (machine_get_chipset(machine) >= MACHINE_CHIPSET_INTEL_430FX); + if (postcard_dell_mode) + io_sethandler(is486 ? 0x00e0 : 0x00e4, 0x0001, + NULL, NULL, NULL, NULL, NULL, postcard_writel, NULL); + return postcard_write; } diff --git a/src/device/serial.c b/src/device/serial.c index 71be924c1..8e2071064 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -746,6 +746,14 @@ serial_read(uint16_t addr, void *priv) return ret; } +uint8_t +serial_get_shadow(serial_t *dev) +{ + uint8_t ret = dev->fcr; + + return ret; +} + void serial_remove(serial_t *dev) { diff --git a/src/device/serial_passthrough.c b/src/device/serial_passthrough.c index 25db29096..426bfbc7b 100644 --- a/src/device/serial_passthrough.c +++ b/src/device/serial_passthrough.c @@ -13,7 +13,7 @@ * Jasmine Iwanek * * Copyright 2021 Andreas J. Reichel. - * Copyright 2021-2022 Jasmine Iwanek. + * Copyright 2021-2025 Jasmine Iwanek. */ #include @@ -222,10 +222,15 @@ serial_passthrough_dev_init(const device_t *info) } const char *serpt_mode_names[SERPT_MODES_MAX] = { - [SERPT_MODE_VCON] = "vcon", - [SERPT_MODE_TCPSRV] = "tcpsrv", - [SERPT_MODE_TCPCLNT] = "tcpclnt", - [SERPT_MODE_HOSTSER] = "hostser", +#ifdef _WIN32 + [SERPT_MODE_NPIPE_SRV] = "npipesrv", + [SERPT_MODE_NPIPE_CLNT] = "npipeclnt", +#else + [SERPT_MODE_VCON] = "vcon", +#endif + [SERPT_MODE_TCP_SRV] = "tcpsrv", + [SERPT_MODE_TCP_CLNT] = "tcpclnt", + [SERPT_MODE_HOSTSER] = "hostser", }; // clang-format off @@ -240,19 +245,17 @@ static const device_config_t serial_passthrough_config[] = { .spinner = { 0 }, .selection = { #ifdef _WIN32 - { .description = "Named Pipe (Server)", .value = SERPT_MODE_VCON }, -#if 0 /* TODO */ - { .description = "Named Pipe (Client)", .value = SERPT_MODE_VCON }, -#endif + { .description = "Named Pipe (Server)", .value = SERPT_MODE_NPIPE_SRV }, + { .description = "Named Pipe (Client)", .value = SERPT_MODE_NPIPE_CLNT }, #else /* _WIN32 */ - { .description = "Pseudo Terminal/Virtual Console", .value = SERPT_MODE_VCON }, + { .description = "Pseudo Terminal/Virtual Console", .value = SERPT_MODE_VCON }, #endif /* _WIN32 */ #if 0 /* TODO */ - { .description = "TCP Server", .value = SERPT_MODE_TCPSRV }, - { .description = "TCP Client", .value = SERPT_MODE_TCPCLNT }, + { .description = "TCP Server", .value = SERPT_MODE_TCP_SRV }, + { .description = "TCP Client", .value = SERPT_MODE_TCP_CLNT }, #endif - { .description = "Host Serial Passthrough", .value = SERPT_MODE_HOSTSER }, - { .description = "" } + { .description = "Host Serial Passthrough", .value = SERPT_MODE_HOSTSER }, + { .description = "" } }, .bios = { { 0 } } }, diff --git a/src/device/tulip_jumper.c b/src/device/tulip_jumper.c new file mode 100644 index 000000000..1974129e3 --- /dev/null +++ b/src/device/tulip_jumper.c @@ -0,0 +1,103 @@ +/* + * 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 Tulip Jumper Readout. + * + * Bits 7-5 = board number, 0-5 valid, 6, 7 invalid. + * + * Authors: Miran Grca, + * + * Copyright 2025 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/machine.h> +#include <86box/sound.h> +#include <86box/chipset.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> + +typedef struct tulip_jumper_t { + uint8_t jumper; +} tulip_jumper_t; + +#ifdef ENABLE_TULIP_JUMPER_LOG +int tulip_jumper_do_log = ENABLE_TULIP_JUMPER_LOG; + +static void +tulip_jumper_log(const char *fmt, ...) +{ + va_list ap; + + if (tulip_jumper_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define tulip_jumper_log(fmt, ...) +#endif + +static uint8_t +tulip_jumper_read(uint16_t addr, void *priv) +{ + const tulip_jumper_t *dev = (tulip_jumper_t *) priv; + uint8_t ret = 0xff; + + tulip_jumper_log("Tulip Jumper: Read %02x\n", dev->jumper); + + ret = dev->jumper; + + return ret; +} + +static void +tulip_jumper_close(void *priv) +{ + tulip_jumper_t *dev = (tulip_jumper_t *) priv; + + free(dev); +} + +static void * +tulip_jumper_init(const device_t *info) +{ + tulip_jumper_t *dev = (tulip_jumper_t *) calloc(1, sizeof(tulip_jumper_t)); + + /* Return board number 05. */ + dev->jumper = 0xbf; + + io_sethandler(0x0d80, 0x0001, tulip_jumper_read, NULL, NULL, NULL, NULL, NULL, dev); + + return dev; +} + +const device_t tulip_jumper_device = { + .name = "Tulip Jumper Readout", + .internal_name = "tulip_jumper", + .flags = 0, + .local = 0, + .init = tulip_jumper_init, + .close = tulip_jumper_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index 3f6a4d018..1cccfe2da 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -31,13 +31,13 @@ add_library(hdd OBJECT hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c + hdc_ide_rz1000.c hdc_ide_sff8038i.c hdc_ide_um8673f.c hdc_ide_w83769f.c - lba_enhancer.c ) -add_library(zip OBJECT zip.c) +add_library(rdisk OBJECT rdisk.c) add_library(mo OBJECT mo.c) diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 582c33428..135528401 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -56,35 +56,46 @@ static const struct { // clang-format off { &device_none }, { &device_internal }, - { &st506_xt_xebec_device }, - { &st506_xt_wdxt_gen_device }, + /* ISA */ + { &xtide_acculogic_device }, { &st506_xt_dtc5150x_device }, + { &st506_xt_xebec_device }, + { &xtide_device }, { &st506_xt_st11_m_device }, - { &st506_xt_wd1002a_wx1_device }, - { &st506_xt_wd1004a_wx1_device }, - { &st506_at_wd1003_device }, { &st506_xt_st11_r_device }, + { &xta_st50x_device }, + { &st506_xt_victor_v86p_device }, { &st506_xt_wd1002a_27x_device }, + { &st506_xt_wd1002a_wx1_device }, { &st506_xt_wd1004_27x_device }, { &st506_xt_wd1004a_27x_device }, - { &st506_xt_victor_v86p_device }, - { &esdi_at_wd1007vse1_device }, + { &st506_xt_wd1004a_wx1_device }, + { &xta_wdxt150_device }, + { &st506_xt_wdxt_gen_device }, + /* ISA16 */ { &ide_isa_device }, { &ide_isa_2ch_device }, { &xtide_at_device }, { &xtide_at_2ch_device }, { &xtide_at_ps2_device }, { &xtide_at_ps2_2ch_device }, - { &xta_wdxt150_device }, - { &xtide_acculogic_device }, - { &xtide_device }, + { &ide_ter_device }, + { &ide_qua_device }, + { &st506_at_wd1003_device }, + { &esdi_at_wd1007vse1_device }, + /* MCA */ { &esdi_ps2_device }, { &esdi_integrated_device }, - { &ide_pci_device }, - { &ide_pci_2ch_device }, + { &mcide_device }, + /* VLB */ { &ide_vlb_device }, { &ide_vlb_2ch_device }, - { &mcide_device }, + /* PCI */ + { &ide_cmd646_ter_qua_device }, + { &ide_cmd648_ter_qua_device }, + { &ide_cmd649_ter_qua_device }, + { &ide_pci_device }, + { &ide_pci_2ch_device }, { NULL } // clang-format on }; @@ -103,18 +114,14 @@ hdc_init(void) void hdc_reset(void) { - hdc_log("HDC: reset(current=%d, internal=%d)\n", - hdc_current[0], (machines[machine].flags & MACHINE_HDC) ? 1 : 0); + for (int i = 0; i < HDC_MAX; i++) { + hdc_log("HDC %i: reset(current=%d, internal=%d)\n", i, + hdc_current[i], hdc_current[i] == HDC_INTERNAL); - /* If we have a valid controller, add its device. */ - if (hdc_current[0] > HDC_INTERNAL) - device_add(controllers[hdc_current[0]].device); - - /* Now, add the tertiary and/or quaternary IDE controllers. */ - if (ide_ter_enabled) - device_add(&ide_ter_device); - if (ide_qua_enabled) - device_add(&ide_qua_device); + /* If we have a valid controller, add its device. */ + if (hdc_current[i] > HDC_INTERNAL) + device_add_inst(controllers[hdc_current[i]].device, i + 1); + } } const char * @@ -124,7 +131,7 @@ hdc_get_internal_name(int hdc) } int -hdc_get_from_internal_name(char *s) +hdc_get_from_internal_name(const char *s) { int c = 0; diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index d725b2ace..367a6f3ac 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -46,7 +46,7 @@ #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdd.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/version.h> /* Bits of 'atastat' */ @@ -234,9 +234,7 @@ static uint8_t ide_qua_pnp_rom[] = { 0x79, 0x00 }; -ide_t *ide_drives[IDE_NUM]; -int ide_ter_enabled = 0; -int ide_qua_enabled = 0; +ide_t *ide_drives[IDE_NUM] = { 0 }; static void ide_atapi_callback(ide_t *ide); static void ide_callback(void *priv); @@ -2828,20 +2826,23 @@ ide_board_close(int board) ide_log("ide_board_close(%i)\n", board); - if ((ide_boards[board] == NULL) || !ide_boards[board]->inited) + if (ide_boards[board] == NULL) return; ide_log("IDE: Closing board %i...\n", board); - timer_stop(&ide_boards[board]->timer); + if (ide_boards[board]->inited) { + timer_stop(&ide_boards[board]->timer); - ide_clear_bus_master(board); + ide_clear_bus_master(board); + } /* Close hard disk image files (if previously open) */ for (uint8_t d = 0; d < 2; d++) { c = (board << 1) + d; - ide_boards[board]->ide[d] = NULL; + if (ide_boards[board]->inited) + ide_boards[board]->ide[d] = NULL; dev = ide_drives[c]; @@ -3265,6 +3266,16 @@ ide_close(UNUSED(void *priv)) } } +void +ide_hard_reset(void) +{ + for (int i = 0; i < IDE_BUS_MAX; i++) + ide_boards[i] = NULL; + + for (int i = 0; i < IDE_NUM; i++) + ide_drives[i] = NULL; +} + static uint8_t mcide_mca_read(const int port, void *priv) { diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index 84a40efa4..9674063d2 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -34,7 +34,7 @@ #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/mo.h> typedef struct cmd640_t { @@ -417,10 +417,10 @@ cmd640_reset(void *priv) (cdrom[i].ide_channel <= max_channel) && cdrom[i].priv) scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); } - for (i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel >= min_channel) && - (zip_drives[i].ide_channel <= max_channel) && zip_drives[i].priv) - zip_reset((scsi_common_t *) zip_drives[i].priv); + for (i = 0; i < RDISK_NUM; i++) { + if ((rdisk_drives[i].bus_type == RDISK_BUS_ATAPI) && (rdisk_drives[i].ide_channel >= min_channel) && + (rdisk_drives[i].ide_channel <= max_channel) && rdisk_drives[i].priv) + rdisk_reset((scsi_common_t *) rdisk_drives[i].priv); } for (i = 0; i < MO_NUM; i++) { if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel >= min_channel) && @@ -667,7 +667,7 @@ const device_t ide_cmd640_pci_legacy_only_device = { }; const device_t ide_cmd640_pci_single_channel_device = { - .name = "CMD PCI-0640B PCI", + .name = "CMD PCI-0640B PCI (Single Channel)", .internal_name = "ide_cmd640_pci_single_channel", .flags = DEVICE_PCI, .local = 0x2000a, @@ -681,7 +681,7 @@ const device_t ide_cmd640_pci_single_channel_device = { }; const device_t ide_cmd640_pci_single_channel_sec_device = { - .name = "CMD PCI-0640B PCI", + .name = "CMD PCI-0640B PCI (Single Channel, Secondary)", .internal_name = "ide_cmd640_pci_single_channel_sec", .flags = DEVICE_PCI, .local = 0x4000a, diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c index a60962ba8..7aa920e22 100644 --- a/src/disk/hdc_ide_cmd646.c +++ b/src/disk/hdc_ide_cmd646.c @@ -34,8 +34,26 @@ #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> -#include <86box/zip.h> +#include <86box/rdisk.h> +#include <86box/rom.h> +#include <86box/hdd.h> +#include <86box/scsi_disk.h> #include <86box/mo.h> +#include "cpu.h" +#include "x86.h" + +#define CMD_TYPE_646 0x0000000 +#define CMD_TYPE_648 0x0100000 +#define CMD_TYPE_649 0x0200000 + +#define CMD648_JP7 0x0400000 /* Reload subsystem ID on reset. */ +#define CMD648_RAID 0x0800000 + +#define CMD64X_ONBOARD 0x1000000 + +#define CMD648_BIOS_FILE "roms/hdd/ide/648_1910.bin" +#define CMD649_REV_1914_BIOS_FILE "roms/hdd/ide/649_1914.bin" +#define CMD649_REV_2301_BIOS_FILE "roms/hdd/ide/649_2301.bin" typedef struct cmd646_t { uint8_t vlb_idx; @@ -46,11 +64,17 @@ typedef struct cmd646_t { uint8_t regs[256]; uint32_t local; + uint32_t rom_addr; + uint32_t rom_addr_size; + uint32_t rom_addr_mask; int irq_pin; + int has_bios; int irq_mode[2]; + rom_t bios_rom; + sff8038i_t *bm[2]; } cmd646_t; @@ -80,7 +104,8 @@ cmd646_set_irq_0(uint8_t status, void *priv) if (!(dev->regs[0x50] & 0x04) || (status & 0x04)) dev->regs[0x50] = (dev->regs[0x50] & ~0x04) | status; - sff_bus_master_set_irq(status, dev->bm[0]); + if (!(dev->local & CMD_TYPE_648) || !(dev->regs[0x71] & 0x10)) + sff_bus_master_set_irq(status, dev->bm[0]); } static void @@ -91,7 +116,8 @@ cmd646_set_irq_1(uint8_t status, void *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]); + if (!(dev->local & CMD_TYPE_648) || !(dev->regs[0x71] & 0x20)) + sff_bus_master_set_irq(status, dev->bm[1]); } static int @@ -116,13 +142,24 @@ cmd646_ide_handlers(cmd646_t *dev) uint16_t main; uint16_t side; int irq_mode[2] = { IRQ_MODE_LEGACY, IRQ_MODE_LEGACY }; + int first = 0; + int reg09 = dev->regs[0x09]; + int reg50 = dev->regs[0x50]; + + if ((dev->local & CMD_TYPE_648) && (dev->local & CMD648_RAID)) { + reg09 = 0xff; + reg50 |= 0x40; + } + + if (dev->local & 0x80000) + first += 2; sff_set_slot(dev->bm[0], dev->pci_slot); sff_set_slot(dev->bm[1], dev->pci_slot); - ide_pri_disable(); + ide_handlers(first, 0); - if ((dev->regs[0x09] & 0x01) && (dev->regs[0x50] & 0x40)) { + if ((reg09 & 0x01) && (reg50 & 0x40)) { main = (dev->regs[0x11] << 8) | (dev->regs[0x10] & 0xf8); side = ((dev->regs[0x15] << 8) | (dev->regs[0x14] & 0xfc)) + 2; } else { @@ -130,23 +167,28 @@ cmd646_ide_handlers(cmd646_t *dev) side = 0x3f6; } - ide_set_base(0, main); - ide_set_side(0, side); + ide_set_base(first, main); + ide_set_side(first, side); - if (dev->regs[0x09] & 0x01) + if (reg09 & 0x01) irq_mode[0] = IRQ_MODE_PCI_IRQ_PIN; sff_set_irq_mode(dev->bm[0], irq_mode[0]); + cmd646_log("IDE %i: %04X, %04X, %i\n", first, main, side, irq_mode[0]); - if (dev->regs[0x04] & 0x01) - ide_pri_enable(); + int pri_enabled = (dev->regs[0x04] & 0x01); + if (dev->local & CMD_TYPE_648) + pri_enabled = pri_enabled && (dev->regs[0x51] & 0x04); + + if (pri_enabled) + ide_handlers(first, 1); if (dev->single_channel) return; - ide_sec_disable(); + ide_handlers(first + 1, 0); - if ((dev->regs[0x09] & 0x04) && (dev->regs[0x50] & 0x40)) { + if ((reg09 & 0x04) && (reg50 & 0x40)) { main = (dev->regs[0x19] << 8) | (dev->regs[0x18] & 0xf8); side = ((dev->regs[0x1d] << 8) | (dev->regs[0x1c] & 0xfc)) + 2; } else { @@ -154,16 +196,17 @@ cmd646_ide_handlers(cmd646_t *dev) side = 0x376; } - ide_set_base(1, main); - ide_set_side(1, side); + ide_set_base(first + 1, main); + ide_set_side(first + 1, side); - if (dev->regs[0x09] & 0x04) - irq_mode[1] = 1; + if (reg09 & 0x04) + irq_mode[1] = IRQ_MODE_PCI_IRQ_PIN; sff_set_irq_mode(dev->bm[1], irq_mode[1]); + cmd646_log("IDE %i: %04X, %04X, %i\n", first + 1, main, side, irq_mode[1]); if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08)) - ide_sec_enable(); + ide_handlers(first + 1, 1); } static void @@ -175,74 +218,176 @@ cmd646_ide_bm_handlers(cmd646_t *dev) sff_bus_master_handler(dev->bm[1], (dev->regs[0x04] & 1), base + 8); } +uint8_t +cmd646_bm_write(uint16_t port, uint8_t val, void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + uint8_t ret = val; + + switch (port & 0x000f) { + case 0x0001: + dev->regs[(port & 0x000f) | 0x70] = val & 0xf0; + if (val & 0x04) + dev->regs[0x50] &= ~0x04; + if (val & 0x08) + dev->regs[0x57] &= ~0x10; + ret &= 0x03; + break; + case 0x0003: + dev->regs[0x73] = val; + break; + case 0x0009: + dev->regs[(port & 0x000f) | 0x70] = (dev->regs[(port & 0x000f) | 0x70] & 0x0f) | (val & 0xf0); + ret &= 0x03; + break; + case 0x000b: + dev->regs[0x7b] = val; + break; + } + + return ret; +} + +uint8_t +cmd646_bm_read(uint16_t port, uint8_t val, void *priv) +{ + cmd646_t *dev = (cmd646_t *) priv; + uint8_t ret = val; + + switch (port & 0x000f) { + case 0x0001: + ret = (dev->regs[(port & 0x000f) | 0x70] & 0xf3) | (dev->regs[0x50] & 0x04) | ((dev->regs[0x57] & 0x10) >> 1); + break; + case 0x0002: case 0x000a: + ret |= 0x08; + break; + case 0x0003: + ret = dev->regs[0x73]; + break; + case 0x0009: + ret = dev->regs[(port & 0x000f) | 0x70]; + break; + case 0x000b: + ret = dev->regs[0x7b]; + break; + } + + return ret; +} + +static void +cmd646_bios_handler(cmd646_t *dev) +{ + if ((dev->local & CMD_TYPE_648) && dev->has_bios) { + uint32_t *addr = (uint32_t *) &(dev->regs[0x30]); + + *addr &= (~dev->rom_addr_mask) | 0x00000001; + dev->rom_addr = *addr & 0xfffffff0; + + cmd646_log("ROM address now: %08X\n", dev->rom_addr); + + if ((dev->regs[0x04] & 0x02) && (*addr & 0x00000001)) + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->rom_addr, dev->rom_addr_size); + else + mem_mapping_disable(&dev->bios_rom.mapping); + } +} + static void cmd646_pci_write(int func, int addr, uint8_t val, void *priv) { - cmd646_t *dev = (cmd646_t *) priv; + cmd646_t *dev = (cmd646_t *) priv; + int reg50 = dev->regs[0x50]; + + if ((dev->local & CMD_TYPE_648) && (dev->regs[0x0a] == 0x04) && (dev->regs[0x0b] == 0x01)) + reg50 |= 0x40; cmd646_log("[%04X:%08X] (%08X) cmd646_pci_write(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, val); if (func == 0x00) switch (addr) { case 0x04: - dev->regs[addr] = (val & 0x45); + if (dev->has_bios) + dev->regs[addr] = (val & 0x47); + else + dev->regs[addr] = (val & 0x45); + cmd646_ide_handlers(dev); + cmd646_ide_bm_handlers(dev); + + cmd646_bios_handler(dev); + break; + case 0x05: + if (dev->local & CMD_TYPE_648) + dev->regs[addr] = (dev->regs[addr] & 0x7e) | (val & 0x01); break; case 0x07: - dev->regs[addr] &= ~(val & 0xb1); + if (dev->local & CMD_TYPE_648) + dev->regs[addr] = ((dev->regs[addr] & ~(val & 0xb9)) & 0xbf) | (val & 0x40); + else + dev->regs[addr] &= ~(val & 0xb1); break; case 0x09: - if ((dev->regs[addr] & 0x0a) == 0x0a) { - dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05); - dev->irq_mode[0] = !!(val & 0x01); - dev->irq_mode[1] = !!(val & 0x04); + if (!(dev->local & CMD_TYPE_648) || + ((dev->regs[0x0a] == 0x01) && (dev->regs[0x0b] == 0x01))) { + if ((dev->regs[addr] & 0x0a) == 0x0a) { + dev->regs[addr] = (dev->regs[addr] & 0x8a) | (val & 0x05); + dev->irq_mode[0] = !!(val & 0x01); + dev->irq_mode[1] = !!(val & 0x04); + cmd646_ide_handlers(dev); + } + } + break; + case 0x0a: case 0x0b: + if ((dev->local & CMD_TYPE_648) && (dev->regs[0x4f] & 0x04)) { + dev->regs[addr] = val; cmd646_ide_handlers(dev); } break; case 0x10: - if (dev->regs[0x50] & 0x40) { + if (reg50 & 0x40) { dev->regs[0x10] = (val & 0xf8) | 1; cmd646_ide_handlers(dev); } break; case 0x11: - if (dev->regs[0x50] & 0x40) { + if (reg50 & 0x40) { dev->regs[0x11] = val; cmd646_ide_handlers(dev); } break; case 0x14: - if (dev->regs[0x50] & 0x40) { + if (reg50 & 0x40) { dev->regs[0x14] = (val & 0xfc) | 1; cmd646_ide_handlers(dev); } break; case 0x15: - if (dev->regs[0x50] & 0x40) { + if (reg50 & 0x40) { dev->regs[0x15] = val; cmd646_ide_handlers(dev); } break; case 0x18: - if (dev->regs[0x50] & 0x40) { + if (reg50 & 0x40) { dev->regs[0x18] = (val & 0xf8) | 1; cmd646_ide_handlers(dev); } break; case 0x19: - if (dev->regs[0x50] & 0x40) { + if (reg50 & 0x40) { dev->regs[0x19] = val; cmd646_ide_handlers(dev); } break; case 0x1c: - if (dev->regs[0x50] & 0x40) { + if (reg50 & 0x40) { dev->regs[0x1c] = (val & 0xfc) | 1; cmd646_ide_handlers(dev); } break; case 0x1d: - if (dev->regs[0x50] & 0x40) { + if (reg50 & 0x40) { dev->regs[0x1d] = val; cmd646_ide_handlers(dev); } @@ -255,18 +400,42 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv) dev->regs[0x21] = val; cmd646_ide_bm_handlers(dev); break; + case 0x2c ... 0x2f: + case 0x8c ... 0x8f: + if (dev->local & CMD_TYPE_648) + dev->regs[(addr & 0x0f) | 0x20] = val; + break; + case 0x30 ... 0x33: + if ((dev->local & CMD_TYPE_648) && dev->has_bios) { + dev->regs[addr] = val; + cmd646_bios_handler(dev); + } + break; + case 0x3c: + dev->regs[0x3c] = val; + break; + case 0x4f: + if (dev->local & CMD_TYPE_648) + dev->regs[addr] = (dev->regs[addr] & 0xfa) | (val & 0x05); + break; case 0x51: - dev->regs[addr] = val & 0xc8; + if (dev->local & CMD_TYPE_648) + dev->regs[addr] = val & 0xcc; + else + dev->regs[addr] = val & 0xc8; cmd646_ide_handlers(dev); break; case 0x52: case 0x54: case 0x56: case 0x58: - case 0x59: case 0x5b: dev->regs[addr] = val; break; + case 0x59: + if ((dev->local & CMD_TYPE_649) || !(dev->local & CMD_TYPE_648)) + dev->regs[addr] = val; + break; case 0x53: case 0x55: dev->regs[addr] = val & 0xc0; @@ -274,10 +443,32 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv) case 0x57: dev->regs[addr] = (dev->regs[addr] & 0x10) | (val & 0xcc); break; - case 0x70 ... 0x77: + case 0x64: + if (dev->local & CMD_TYPE_648) + dev->regs[addr] = (dev->regs[addr] & 0xfc) | (val & 0x03); + break; + case 0x65: + if (dev->local & CMD_TYPE_648) + dev->regs[addr] = (dev->regs[addr] & 0x7f) | (val & 0x80); + break; + case 0x71: + if (dev->local & CMD_TYPE_648) + sff_bus_master_write(addr & 0x0f, val, dev->bm[0]); + else + sff_bus_master_write(addr & 0x0f, val & 0x03, dev->bm[0]); + break; + case 0x70: + case 0x72 ... 0x77: sff_bus_master_write(addr & 0x0f, val, dev->bm[0]); break; - case 0x78 ... 0x7f: + case 0x79: + if (dev->local & CMD_TYPE_648) + sff_bus_master_write(addr & 0x0f, val, dev->bm[1]); + else + sff_bus_master_write(addr & 0x0f, val & 0x03, dev->bm[1]); + break; + case 0x78: + case 0x7a ... 0x7f: sff_bus_master_write(addr & 0x0f, val, dev->bm[1]); break; @@ -295,14 +486,18 @@ cmd646_pci_read(int func, int addr, void *priv) if (func == 0x00) { ret = dev->regs[addr]; - if (addr == 0x50) + if ((addr == 0x09) && (dev->local & CMD_TYPE_648) && (dev->regs[0x0a] == 0x04)) + ret = 0x00; + else if (addr == 0x50) dev->regs[0x50] &= ~0x04; else if (addr == 0x57) dev->regs[0x57] &= ~0x10; else if ((addr >= 0x70) && (addr <= 0x77)) ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]); else if ((addr >= 0x78) && (addr <= 0x7f)) - ret = sff_bus_master_read(addr & 0x0f, dev->bm[0]); + ret = sff_bus_master_read(addr & 0x0f, dev->bm[1]); + else if ((dev->local & CMD_TYPE_648) && (addr >= 0x8c) && (addr <= 0x8f)) + ret = dev->regs[(addr & 0x0f) | 0x20]; } cmd646_log("[%04X:%08X] (%08X) cmd646_pci_read(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, ret); @@ -310,22 +505,44 @@ cmd646_pci_read(int func, int addr, void *priv) return ret; } +static int +check_ch(cmd646_t *dev, int channel) +{ + int ret = 0; + int min = 0; + int max = dev->single_channel ? 1 : 3; + + if (dev->local & 0x80000) { + min += 4; + max += 4; + } + + if ((channel >= min) && (channel <= max)) + ret = 1; + + return ret; +} + static void cmd646_reset(void *priv) { cmd646_t *dev = (cmd646_t *) priv; int i = 0; + for (i = 0; i < HDD_NUM; i++) { + if ((hdd[i].bus_type == HDD_BUS_ATAPI) && check_ch(dev, hdd[i].ide_channel) && hdd[i].priv) + scsi_disk_reset((scsi_common_t *) hdd[i].priv); + } for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv) + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && check_ch(dev, cdrom[i].ide_channel) && cdrom[i].priv) scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); } - for (i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && zip_drives[i].priv) - zip_reset((scsi_common_t *) zip_drives[i].priv); + for (i = 0; i < RDISK_NUM; i++) { + if ((rdisk_drives[i].bus_type == RDISK_BUS_ATAPI) && check_ch(dev, rdisk_drives[i].ide_channel) && rdisk_drives[i].priv) + rdisk_reset((scsi_common_t *) rdisk_drives[i].priv); } for (i = 0; i < MO_NUM; i++) { - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv) + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && check_ch(dev, mo_drives[i].ide_channel) && mo_drives[i].priv) mo_reset((scsi_common_t *) mo_drives[i].priv); } @@ -336,16 +553,40 @@ cmd646_reset(void *priv) dev->regs[0x00] = 0x95; /* CMD */ dev->regs[0x01] = 0x10; - dev->regs[0x02] = 0x46; /* PCI-0646 */ + if (dev->local & CMD_TYPE_649) + dev->regs[0x02] = 0x49; /* PCI-0649 */ + else if (dev->local & CMD_TYPE_648) + dev->regs[0x02] = 0x48; /* PCI-0648 */ + else + dev->regs[0x02] = 0x46; /* PCI-0646 */ dev->regs[0x03] = 0x06; dev->regs[0x04] = 0x00; - dev->regs[0x06] = 0x80; dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ dev->regs[0x09] = dev->local; /* Programming interface */ - dev->regs[0x0a] = 0x01; /* IDE controller */ + if ((dev->local & CMD_TYPE_648) && (dev->local & CMD648_RAID)) { + dev->regs[0x06] = 0x90; + dev->regs[0x08] = 0x02; + dev->regs[0x0a] = 0x04; /* RAID controller */ + + dev->regs[0x50] = 0x40; /* Enable Base address register R/W; + If 0, they return 0 and are read-only 8 */ + + /* Blank base addresses */ + dev->regs[0x10] = 0x01; + dev->regs[0x14] = 0x01; + dev->regs[0x18] = 0x01; + dev->regs[0x1c] = 0x01; + } else { + dev->regs[0x06] = 0x80; + dev->regs[0x0a] = 0x01; /* IDE controller */ + } dev->regs[0x0b] = 0x01; /* Mass storage controller */ - if ((dev->local & 0xffff) == 0x8a) { + if ((dev->local & CMD_TYPE_648) && (dev->local & CMD648_JP7)) + for (int i = 0; i < 4; i++) + dev->regs[0x2c + i] = dev->regs[i]; + + if ((dev->regs[0x0a] == 0x01) && ((dev->regs[0x09] & 0x8a) == 0x8a)) { dev->regs[0x50] = 0x40; /* Enable Base address register R/W; If 0, they return 0 and are read-only 8 */ @@ -371,13 +612,47 @@ cmd646_reset(void *priv) dev->regs[0x51] = 0x08; dev->regs[0x57] = 0x0c; - dev->regs[0x59] = 0x40; - dev->irq_mode[0] = dev->irq_mode[1] = 0; + if (dev->local & CMD_TYPE_648) { + dev->regs[0x34] = 0x60; + + dev->regs[0x4f] = (dev->local & CMD648_JP7) ? 0x02 : 0x00; + dev->regs[0x51] |= 0x04; + + if (dev->local & CMD_TYPE_649) { + dev->regs[0x57] |= 0x80; + dev->regs[0x59] = 0x40; + } else + dev->regs[0x57] |= 0xc0; + + dev->regs[0x60] = 0x01; + dev->regs[0x62] = 0x21; + dev->regs[0x63] = 0x06; + dev->regs[0x65] = 0x60; + dev->regs[0x67] = 0xf0; + + /* 80-pin stuff. */ + dev->regs[0x72] = 0x08; + dev->regs[0x7a] = 0x08; + dev->regs[0x79] = 0x83; + } else + dev->regs[0x59] = 0x40; + dev->irq_pin = PCI_INTA; + if ((dev->local & CMD_TYPE_648) && (dev->local & CMD648_RAID)) + dev->irq_mode[0] = dev->irq_mode[1] = IRQ_MODE_PCI_IRQ_PIN; + else { + dev->irq_mode[0] = (dev->regs[0x09] & 0x01) ? IRQ_MODE_PCI_IRQ_PIN : IRQ_MODE_LEGACY; + dev->irq_mode[1] = (dev->regs[0x09] & 0x04) ? IRQ_MODE_PCI_IRQ_PIN : IRQ_MODE_LEGACY; + } + + dev->irq_pin = PCI_INTA; + cmd646_ide_handlers(dev); cmd646_ide_bm_handlers(dev); + + cmd646_bios_handler(dev); } static void @@ -391,42 +666,147 @@ cmd646_close(void *priv) static void * cmd646_init(const device_t *info) { - cmd646_t *dev = (cmd646_t *) calloc(1, sizeof(cmd646_t)); + cmd646_t *dev = (cmd646_t *) calloc(1, sizeof(cmd646_t)); + int first = 0; dev->local = info->local; device_add(&ide_pci_2ch_device); - if (info->local & 0x80000) - pci_add_card(PCI_ADD_NORMAL, cmd646_pci_read, cmd646_pci_write, dev, &dev->pci_slot); - else + if (info->local & 0x80000) { + first = 2; + device_add(&ide_pci_ter_qua_2ch_device); + } else + device_add(&ide_pci_2ch_device); + + if (info->local & CMD64X_ONBOARD) pci_add_card(PCI_ADD_IDE, cmd646_pci_read, cmd646_pci_write, dev, &dev->pci_slot); + else + pci_add_card(PCI_ADD_NORMAL, cmd646_pci_read, cmd646_pci_write, dev, &dev->pci_slot); dev->single_channel = !!(info->local & 0x20000); - dev->bm[0] = device_add_inst(&sff8038i_device, 1); + dev->bm[0] = device_add_inst(&sff8038i_device, first + 1); if (!dev->single_channel) - dev->bm[1] = device_add_inst(&sff8038i_device, 2); + dev->bm[1] = device_add_inst(&sff8038i_device, first + 2); - ide_set_bus_master(0, cmd646_bus_master_dma_0, cmd646_set_irq_0, dev); + ide_set_bus_master(first, cmd646_bus_master_dma_0, cmd646_set_irq_0, dev); if (!dev->single_channel) - ide_set_bus_master(1, cmd646_bus_master_dma_1, cmd646_set_irq_1, dev); + ide_set_bus_master(first + 1, cmd646_bus_master_dma_1, cmd646_set_irq_1, dev); sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); if (!dev->single_channel) sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); + sff_set_slot(dev->bm[0], dev->pci_slot); + sff_set_slot(dev->bm[1], dev->pci_slot); + + if (dev->local & CMD_TYPE_648) { + sff_set_ven_handlers(dev->bm[0], cmd646_bm_write, cmd646_bm_read, dev); + sff_set_ven_handlers(dev->bm[1], cmd646_bm_write, cmd646_bm_read, dev); + + dev->has_bios = device_get_config_int("bios"); + + if (dev->has_bios) { + char *fn = NULL; + + if (dev->local & CMD_TYPE_649) { + const char *bios_rev = (char *) device_get_config_bios("bios_rev"); + fn = (char *) device_get_bios_file(info, bios_rev, 0); + + dev->rom_addr_size = device_get_bios_file_size(info, bios_rev); + } else { + fn = CMD648_BIOS_FILE; + + dev->rom_addr_size = 0x00004000; + } + + dev->rom_addr_mask = dev->rom_addr_size - 1; + + rom_init(&dev->bios_rom, fn, + 0x000d0000, dev->rom_addr_size, dev->rom_addr_mask, 0, MEM_MAPPING_EXTERNAL); + + mem_mapping_disable(&dev->bios_rom.mapping); + } + } + cmd646_reset(dev); + if (dev->local & CMD_TYPE_648) + for (int i = 0; i < 4; i++) + dev->regs[0x2c + i] = dev->regs[i]; + return dev; } +static const device_config_t cmd648_config[] = { + { + .name = "bios", + .description = "Enable BIOS", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +static const device_config_t cmd649_config[] = { + { + .name = "bios", + .description = "Enable BIOS", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "bios_rev", + .description = "BIOS Revision", + .type = CONFIG_BIOS, + .default_string = "rev_2301", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "Revision 1.9.14", + .internal_name = "rev_1914", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { CMD649_REV_2301_BIOS_FILE, "" } + }, + { + .name = "Revision 2.3.01", + .internal_name = "rev_2301", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 65536, + .files = { CMD649_REV_2301_BIOS_FILE, "" } + }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + const device_t ide_cmd646_device = { .name = "CMD PCI-0646", .internal_name = "ide_cmd646", .flags = DEVICE_PCI, - .local = 0x8a, + .local = 0x000008a | CMD64X_ONBOARD, .init = cmd646_init, .close = cmd646_close, .reset = cmd646_reset, @@ -440,7 +820,7 @@ const device_t ide_cmd646_legacy_only_device = { .name = "CMD PCI-0646 (Legacy Mode Only)", .internal_name = "ide_cmd646_legacy_only", .flags = DEVICE_PCI, - .local = 0x80, + .local = 0x0000080 | CMD64X_ONBOARD, .init = cmd646_init, .close = cmd646_close, .reset = cmd646_reset, @@ -451,10 +831,10 @@ const device_t ide_cmd646_legacy_only_device = { }; const device_t ide_cmd646_single_channel_device = { - .name = "CMD PCI-0646", + .name = "CMD PCI-0646 (Single Channel)", .internal_name = "ide_cmd646_single_channel", .flags = DEVICE_PCI, - .local = 0x2008a, + .local = 0x002008a | CMD64X_ONBOARD, .init = cmd646_init, .close = cmd646_close, .reset = cmd646_reset, @@ -463,3 +843,59 @@ const device_t ide_cmd646_single_channel_device = { .force_redraw = NULL, .config = NULL }; + +const device_t ide_cmd646_ter_qua_device = { + .name = "CMD PCI-0646 (Tertiary and Quaternary)", + .internal_name = "ide_cmd646_ter_qua", + .flags = DEVICE_PCI, + .local = 0x008008f, + .init = cmd646_init, + .close = cmd646_close, + .reset = cmd646_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_cmd648_ter_qua_device = { + .name = "CMD PCI-0648 (Tertiary and Quaternary)", + .internal_name = "ide_cmd648_ter_qua", + .flags = DEVICE_PCI, + .local = 0x0d8008f, + .init = cmd646_init, + .close = cmd646_close, + .reset = cmd646_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = cmd648_config +}; + +const device_t ide_cmd648_ter_qua_onboard_device = { + .name = "CMD PCI-0648 (Tertiary and Quaternary) On-Board", + .internal_name = "ide_cmd648_ter_qua_onboard", + .flags = DEVICE_PCI, + .local = 0x0d8008f | CMD64X_ONBOARD, + .init = cmd646_init, + .close = cmd646_close, + .reset = cmd646_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_cmd649_ter_qua_device = { + .name = "CMD PCI-0649 (Tertiary and Quaternary)", + .internal_name = "ide_cmd649_ter_qua", + .flags = DEVICE_PCI, + .local = 0x0f8008f, + .init = cmd646_init, + .close = cmd646_close, + .reset = cmd646_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = cmd649_config +}; diff --git a/src/disk/hdc_ide_rz1000.c b/src/disk/hdc_ide_rz1000.c new file mode 100644 index 000000000..8e664dd92 --- /dev/null +++ b/src/disk/hdc_ide_rz1000.c @@ -0,0 +1,289 @@ +/* + * 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 PC Technology RZ-1000 controller. + * + * Authors: Miran Grca, + * + * Copyright 2025 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/cdrom.h> +#include <86box/scsi_device.h> +#include <86box/scsi_cdrom.h> +#include <86box/dma.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/pic.h> +#include <86box/timer.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/rdisk.h> +#include <86box/mo.h> + +typedef struct rz1000_t { + uint8_t vlb_idx; + uint8_t id; + uint8_t in_cfg; + uint8_t channels; + uint8_t pci; + uint8_t irq_state; + uint8_t pci_slot; + uint8_t pad0; + uint8_t regs[256]; + uint32_t local; + int irq_mode[2]; + int irq_pin; + int irq_line; +} rz1000_t; + +static int next_id = 0; + +#ifdef ENABLE_RZ1000_LOG +int rz1000_do_log = ENABLE_RZ1000_LOG; + +static void +rz1000_log(const char *fmt, ...) +{ + va_list ap; + + if (rz1000_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define rz1000_log(fmt, ...) +#endif + +static void +rz1000_ide_handlers(rz1000_t *dev) +{ + uint16_t main; + uint16_t side; + + if (dev->channels & 0x01) { + ide_pri_disable(); + + main = 0x1f0; + side = 0x3f6; + + ide_set_base(0, main); + ide_set_side(0, side); + + if (dev->regs[0x04] & 0x01) + ide_pri_enable(); + } + + if (dev->channels & 0x02) { + ide_sec_disable(); + + main = 0x170; + side = 0x376; + + ide_set_base(1, main); + ide_set_side(1, side); + + if (dev->regs[0x04] & 0x01) + ide_sec_enable(); + } +} + +static void +rz1000_pci_write(int func, int addr, uint8_t val, void *priv) +{ + rz1000_t *dev = (rz1000_t *) priv; + + rz1000_log("rz1000_pci_write(%i, %02X, %02X)\n", func, addr, val); + + if (func == 0x00) + switch (addr) { + case 0x04: + dev->regs[addr] = (val & 0x41); + rz1000_ide_handlers(dev); + break; + case 0x07: + dev->regs[addr] &= ~(val & 0x80); + break; + case 0x09: + if ((dev->regs[addr] & 0x0a) == 0x0a) { + dev->regs[addr] = (dev->regs[addr] & 0x0a) | (val & 0x05); + dev->irq_mode[0] = !!(val & 0x01); + dev->irq_mode[1] = !!(val & 0x04); + rz1000_ide_handlers(dev); + } + break; + case 0x40 ... 0x4f: + dev->regs[addr] = val; + break; + } +} + +static uint8_t +rz1000_pci_read(int func, int addr, void *priv) +{ + rz1000_t *dev = (rz1000_t *) priv; + uint8_t ret = 0xff; + + if (func == 0x00) + ret = dev->regs[addr]; + + rz1000_log("rz1000_pci_read(%i, %02X, %02X)\n", func, addr, ret); + + return ret; +} + +static void +rz1000_reset(void *priv) +{ + rz1000_t *dev = (rz1000_t *) priv; + int i = 0; + int min_channel; + int max_channel; + + switch (dev->channels) { + default: + case 0x00: + min_channel = max_channel = 0; + break; + case 0x01: + min_channel = 0; + max_channel = 1; + break; + case 0x02: + min_channel = 2; + max_channel = 3; + break; + case 0x03: + min_channel = 0; + max_channel = 3; + break; + } + + for (i = 0; i < CDROM_NUM; i++) { + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel >= min_channel) && + (cdrom[i].ide_channel <= max_channel) && cdrom[i].priv) + scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); + } + for (i = 0; i < RDISK_NUM; i++) { + if ((rdisk_drives[i].bus_type == RDISK_BUS_ATAPI) && (rdisk_drives[i].ide_channel >= min_channel) && + (rdisk_drives[i].ide_channel <= max_channel) && rdisk_drives[i].priv) + rdisk_reset((scsi_common_t *) rdisk_drives[i].priv); + } + for (i = 0; i < MO_NUM; i++) { + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel >= min_channel) && + (mo_drives[i].ide_channel <= max_channel) && mo_drives[i].priv) + mo_reset((scsi_common_t *) mo_drives[i].priv); + } + + memset(dev->regs, 0x00, sizeof(dev->regs)); + + rz1000_log("dev->local = %08X\n", dev->local); + + dev->regs[0x00] = 0x42; /* PC Technology */ + dev->regs[0x01] = 0x10; + dev->regs[0x02] = 0x00; /* RZ-1000 */ + dev->regs[0x03] = 0x10; + dev->regs[0x04] = 0x00; + dev->regs[0x07] = 0x02; /* DEVSEL timing: 01 medium */ + dev->regs[0x08] = 0x02; /* Revision 02 */ + dev->regs[0x09] = dev->local; /* Programming interface */ + dev->regs[0x0a] = 0x01; /* IDE controller */ + dev->regs[0x0b] = 0x01; /* Mass storage controller */ + + dev->irq_mode[0] = dev->irq_mode[1] = 0; + dev->irq_pin = PCI_INTA; + dev->irq_line = 14; + + rz1000_ide_handlers(dev); +} + +static void +rz1000_close(void *priv) +{ + rz1000_t *dev = (rz1000_t *) priv; + + free(dev); + + next_id = 0; +} + +static void * +rz1000_init(const device_t *info) +{ + rz1000_t *dev = (rz1000_t *) calloc(1, sizeof(rz1000_t)); + + dev->id = next_id | 0x60; + + dev->pci = !!(info->flags & DEVICE_PCI); + dev->local = info->local; + + dev->channels = ((info->local & 0x60000) >> 17) & 0x03; + + if (dev->channels & 0x02) + device_add(&ide_pci_2ch_device); + else + device_add(&ide_pci_device); + + if (info->local & 0x80000) + pci_add_card(PCI_ADD_NORMAL, rz1000_pci_read, rz1000_pci_write, dev, &dev->pci_slot); + else + pci_add_card(PCI_ADD_IDE, rz1000_pci_read, rz1000_pci_write, dev, &dev->pci_slot); + + if (dev->channels & 0x01) + ide_board_set_force_ata3(0, 1); + + if (dev->channels & 0x02) + ide_board_set_force_ata3(1, 1); + + next_id++; + + rz1000_reset(dev); + + return dev; +} + +const device_t ide_rz1000_pci_device = { + .name = "PC Technology RZ-1000 PCI", + .internal_name = "ide_rz1000_pci", + .flags = DEVICE_PCI, + .local = 0x60000, + .init = rz1000_init, + .close = rz1000_close, + .reset = rz1000_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_rz1000_pci_single_channel_device = { + .name = "PC Technology RZ-1000 PCI (Single Channel)", + .internal_name = "ide_rz1000_pci_single_channel", + .flags = DEVICE_PCI, + .local = 0x20000, + .init = rz1000_init, + .close = rz1000_close, + .reset = rz1000_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index 7ded4372f..50deac38a 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -42,7 +42,7 @@ #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/mo.h> #include <86box/plat_unused.h> @@ -118,6 +118,9 @@ sff_bus_master_write(uint16_t port, uint8_t val, void *priv) sff_log("SFF-8038i Bus master BYTE write: %04X %02X\n", port, val); + if (dev->ven_write != NULL) + val = dev->ven_write(port, val, dev->priv); + switch (port & 7) { case 0: sff_log("sff Cmd : val = %02X, old = %02X\n", val, dev->command); @@ -255,6 +258,9 @@ sff_bus_master_read(uint16_t port, void *priv) break; } + if (dev->ven_read != NULL) + ret= dev->ven_read(port, ret, dev->priv); + sff_log("SFF-8038i Bus master BYTE read : %04X %02X\n", port, ret); return ret; @@ -489,10 +495,10 @@ sff_reset(void *priv) cdrom[i].priv) scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); } - for (uint8_t i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel < 4) && - zip_drives[i].priv) - zip_reset((scsi_common_t *) zip_drives[i].priv); + for (uint8_t i = 0; i < RDISK_NUM; i++) { + if ((rdisk_drives[i].bus_type == RDISK_BUS_ATAPI) && (rdisk_drives[i].ide_channel < 4) && + rdisk_drives[i].priv) + rdisk_reset((scsi_common_t *) rdisk_drives[i].priv); } for (uint8_t i = 0; i < MO_NUM; i++) { if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && @@ -569,6 +575,16 @@ sff_set_mirq(sff8038i_t *dev, uint8_t mirq) dev->mirq = mirq; } +void +sff_set_ven_handlers(sff8038i_t *dev, uint8_t (*ven_write)(uint16_t port, uint8_t val, void *priv), + uint8_t (*ven_read)(uint16_t port, uint8_t val, void *priv), void *priv) +{ + dev->ven_write = ven_write; + dev->ven_read = ven_read; + + dev->priv = priv; +} + static void sff_close(void *priv) { diff --git a/src/disk/hdc_ide_w83769f.c b/src/disk/hdc_ide_w83769f.c index 7829c5b92..25ee16d10 100644 --- a/src/disk/hdc_ide_w83769f.c +++ b/src/disk/hdc_ide_w83769f.c @@ -34,7 +34,7 @@ #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/mo.h> typedef struct w83769f_t { @@ -297,10 +297,10 @@ w83769f_reset(void *priv) (cdrom[i].ide_channel <= max_channel) && cdrom[i].priv) scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); } - for (i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel >= min_channel) && - (zip_drives[i].ide_channel <= max_channel) && zip_drives[i].priv) - zip_reset((scsi_common_t *) zip_drives[i].priv); + for (i = 0; i < RDISK_NUM; i++) { + if ((rdisk_drives[i].bus_type == RDISK_BUS_ATAPI) && (rdisk_drives[i].ide_channel >= min_channel) && + (rdisk_drives[i].ide_channel <= max_channel) && rdisk_drives[i].priv) + rdisk_reset((scsi_common_t *) rdisk_drives[i].priv); } for (i = 0; i < MO_NUM; i++) { if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel >= min_channel) && diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index b3a07fa5a..a7313ca63 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -1915,7 +1915,7 @@ victor_v86p_available(void) static const device_config_t dtc_config[] = { { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xc8000, @@ -1969,7 +1969,7 @@ static const device_config_t st11_config[] = { }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xc8000, @@ -2006,7 +2006,7 @@ static const device_config_t st11_config[] = { static const device_config_t wd_config[] = { { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xc8000, @@ -2089,7 +2089,7 @@ static const device_config_t wd_nobios_config[] = { static const device_config_t wd_rll_config[] = { { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xc8000, @@ -2153,7 +2153,7 @@ static const device_config_t wd_rll_config[] = { static const device_config_t wd1004a_config[] = { { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xc8000, @@ -2202,7 +2202,7 @@ static const device_config_t wd1004a_config[] = { static const device_config_t wd1004_rll_config[] = { { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xc8000, diff --git a/src/disk/hdc_xta.c b/src/disk/hdc_xta.c index 85581af2d..426be9a67 100644 --- a/src/disk/hdc_xta.c +++ b/src/disk/hdc_xta.c @@ -82,6 +82,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -101,11 +102,14 @@ #include <86box/ui.h> #include <86box/hdc.h> #include <86box/hdd.h> +#include "cpu.h" #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" +#define ST50X_BIOS_FILE "roms/hdd/xta/ST05XBIO.BIN" +#define PC5086_BIOS_FILE "roms/machines/pc5086/c800.bin" enum { STATE_IDLE = 0, @@ -236,6 +240,7 @@ typedef struct hdc_t { const char *name; /* controller name */ uint16_t base; /* controller base I/O address */ + uint8_t sw; /* controller switches */ int8_t irq; /* controller IRQ channel */ int8_t dma; /* controller DMA channel */ int8_t type; /* controller type ID */ @@ -269,6 +274,10 @@ typedef struct hdc_t { uint8_t sector_buf[512]; /* sector buffer */ } hdc_t; +typedef struct hdc_dual_t { + hdc_t *hdc[2]; +} hdc_dual_t; + #ifdef ENABLE_XTA_LOG int xta_do_log = ENABLE_XTA_LOG; @@ -882,7 +891,7 @@ hdc_read(uint16_t port, void *priv) hdc_t *dev = (hdc_t *) priv; uint8_t ret = 0xff; - switch (port & 7) { + switch (port & 3) { case 0: /* DATA register */ dev->status &= ~STAT_IRQ; @@ -915,7 +924,7 @@ hdc_read(uint16_t port, void *priv) break; case 2: /* "read option jumpers" */ - ret = 0xff; /* all switches off */ + ret = dev->sw; break; default: @@ -931,7 +940,7 @@ hdc_write(uint16_t port, uint8_t val, void *priv) { hdc_t *dev = (hdc_t *) priv; - switch (port & 7) { + switch (port & 3) { case 0: /* DATA register */ if (dev->state == STATE_RDATA) { if (!(dev->status & STAT_REQ)) { @@ -989,38 +998,85 @@ hdc_write(uint16_t port, uint8_t val, void *priv) } } +void +xta_handler(void *priv, int set) +{ + hdc_t *dev = (hdc_t *) priv; + + io_handler(set, dev->base, 4, + hdc_read, NULL, NULL, hdc_write, NULL, NULL, dev); +} + static void * -xta_init(const device_t *info) +xta_init_common(const device_t *info, int type) { drive_t *drive; const char *bios_rev = NULL; const char *fn = NULL; hdc_t *dev; int c; - int max = XTA_NUM; + int min = 0; + int max = XTA_NUM; /* Allocate and initialize device block. */ dev = calloc(1, sizeof(hdc_t)); - dev->type = info->local; + + dev->sw = 0xff; /* all switches off */ + dev->type = type; /* Do per-controller-type setup. */ switch (dev->type) { case 0: /* WDXT-150, with BIOS */ dev->name = "WDXT-150"; + bios_rev = (char *) device_get_config_bios("bios_rev"); + fn = (char *) device_get_bios_file(info, bios_rev, 0); + /* Revision 2 actually supports 2 drives using drive select. */ + if (!strcmp(bios_rev, "rev_1")) + max = 1; +#ifdef SELECTABLE_BASE dev->base = device_get_config_hex16("base"); +#else + dev->base = 0x0320; +#endif dev->irq = device_get_config_int("irq"); 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, bios_rev, 0); - max = 1; break; case 1: /* EuroPC */ - dev->name = "HD20"; - dev->base = 0x0320; - dev->irq = 5; - dev->dma = 3; + case 3: /* Amstrad PC5086 */ + switch (dev->type) { + case 1: + dev->name = "HD20"; + break; + case 3: + dev->name = "ST-50X PC5086"; + dev->rom_addr = 0xc8000; + fn = PC5086_BIOS_FILE; + max = 1; + break; + } + dev->base = 0x0320; + dev->irq = 5; + dev->dma = 3; + break; + case 2: /* Seagate ST-05X Standalone */ + case 4: /* Seagate ST-05X Standalone secondary device */ + switch (dev->type) { + case 2: + dev->name = "ST-50X PRI"; + dev->rom_addr = device_get_config_hex20("bios_addr"); + fn = ST50X_BIOS_FILE; + max = 1; + break; + case 4: + dev->name = "ST-50X SEC"; + min = 1; + break; + } + dev->base = 0x0320 + (dev->type & 4); + dev->irq = 5; + dev->dma = 3; break; default: @@ -1031,14 +1087,16 @@ xta_init(const device_t *info) dev->name, dev->base, dev->irq, dev->dma); if (dev->rom_addr != 0x000000) xta_log(", BIOS=%06X", dev->rom_addr); - xta_log(")\n"); /* Load any disks for this device class. */ c = 0; for (uint8_t i = 0; i < HDD_NUM; i++) { - if ((hdd[i].bus_type == HDD_BUS_XTA) && (hdd[i].xta_channel < max)) { - drive = &dev->drives[hdd[i].xta_channel]; + if ((hdd[i].bus_type == HDD_BUS_XTA) && (hdd[i].xta_channel >= min) && (hdd[i].xta_channel < max)) { + if (dev->type == 4) + drive = &dev->drives[0]; + else + drive = &dev->drives[hdd[i].xta_channel]; if (!hdd_image_load(i)) { drive->present = 0; @@ -1058,6 +1116,112 @@ xta_init(const device_t *info) drive->hpc = drive->cfg_hpc; drive->tracks = drive->cfg_tracks; + if (dev->type == 0) { + if (!strcmp(bios_rev, "rev_1")) { + /* + WDXT-150, Revision 1 switches: + - Bit 6: 1 = IBM (INT 13h), 0 = Tandy (INT 0Ah). + - Bit 5: 1 = 17 sectors per track, 0 = 27 sectors per track. + - Drive 0, bits 1,0: + - With bit 4 set: + - 0,0 = 820/4/17; + - 0,1 = 615/4/17; + - 1,0 = 782/4/17; + - 1,1 = 782/2/17. + - With bit 4 clear: + - 0,0 = 1024/4/17; + - 0,1 = 940/4/17; + - 1,0 = 1024/4/17; + - 1,1 = 1024/2/17. + - Drive 1, bits 3,2: + - With bit 4 set: + - 0,0 = 820/4/17; + - 0,1 = 615/4/17; + - 1,0 = 782/4/17; + - 1,1 = 782/2/17. + - With bit 4 clear: + - 0,0 = 1024/4/17; + - 0,1 = 940/4/17; + - 1,0 = 1024/4/17; + - 1,1 = 1024/2/17. + */ + if (drive->tracks == 940) + dev->sw = ((dev->sw & 0xef) & (c ? 0xf3 : 0xfc)) | (0x01 << (c << 1)); + else if (drive->tracks == 1024) { + if (drive->hpc == 4) + dev->sw = ((dev->sw & 0xef) & (c ? 0xf3 : 0xfc)) | (0x00 << (c << 1)); + else + dev->sw = ((dev->sw & 0xef) & (c ? 0xf3 : 0xfc)) | (0x03 << (c << 1)); + } else if (drive->tracks == 782) { + if (drive->hpc == 4) + dev->sw = (dev->sw & (c ? 0xf3 : 0xfc)) | (0x02 << (c << 1)); + else + dev->sw = (dev->sw & (c ? 0xf3 : 0xfc)) | (0x03 << (c << 1)); + } else if (drive->tracks == 820) + dev->sw = (dev->sw & (c ? 0xf3 : 0xfc)) | (0x00 << (c << 1)); + else + dev->sw = (dev->sw & (c ? 0xf3 : 0xfc)) | (0x01 << (c << 1)); + } else { + /* + WDXT-150, Revision 2 switches: + - Drive 0, bits 1,0: + - With bit 4 set: + - 0,0 = 612/4/17; + - 0,1 = 615/6/17; + - 1,0 = 977/5/17; + - 1,1 = 615/4/17. + - With bit 4 clear: + - 0,0 = 976/4/17; + - 0,1 = 1024/3/17; + - 1,0 = 1024/4/17; + - 1,1 = 1024/2/17. + - Drive 1, bits 3,2: + - With bit 4 set: + - 0,0 = 612/4/17; + - 0,1 = 615/6/17; + - 1,0 = 977/5/17; + - 1,1 = 615/4/17. + - With bit 4 clear: + - 0,0 = 976/4/17; + - 0,1 = 1024/3/17; + - 1,0 = 1024/4/17; + - 1,1 = 1024/2/17. + */ + if (drive->tracks == 976) + dev->sw = ((dev->sw & 0xef) & (c ? 0xf3 : 0xfc)) | (0x00 << (c << 1)); + else if (drive->tracks == 1024) { + if (drive->hpc == 3) + dev->sw = ((dev->sw & 0xef) & (c ? 0xf3 : 0xfc)) | (0x01 << (c << 1)); + else if (drive->hpc == 4) + dev->sw = ((dev->sw & 0xef) & (c ? 0xf3 : 0xfc)) | (0x02 << (c << 1)); + else + dev->sw = ((dev->sw & 0xef) & (c ? 0xf3 : 0xfc)) | (0x03 << (c << 1)); + } else if (drive->tracks == 615) { + if (drive->hpc == 6) + dev->sw = (dev->sw & (c ? 0xf3 : 0xfc)) | (0x01 << (c << 1)); + else + dev->sw = (dev->sw & (c ? 0xf3 : 0xfc)) | (0x03 << (c << 1)); + } else if (drive->tracks == 612) + dev->sw = (dev->sw & (c ? 0xf3 : 0xfc)) | (0x00 << (c << 1)); + else + dev->sw = (dev->sw & (c ? 0xf3 : 0xfc)) | (0x02 << (c << 1)); + } + } else if ((dev->type >= 2) && (dev->type <= 4)) { + /* + Bits 1, 0: + - 1, 1 = 615/4/17 (20 MB); + - 1, 0 or 0, 0 = 980/5/17 (40 MB); + - 0, 1 = 615/6/17 (30 MB). + - 0, 0 is actually no hard disk present - switch port supposed to be readable always? + */ + if (drive->tracks == 980) + dev->sw = 0xfe; + else if (drive->hpc == 6) + dev->sw = 0xfd; + else + dev->sw = 0xff; + } + xta_log("%s: drive%d (cyl=%d,hd=%d,spt=%d), disk %d\n", dev->name, hdd[i].xta_channel, drive->tracks, drive->hpc, drive->spt, i); @@ -1083,6 +1247,23 @@ xta_init(const device_t *info) return dev; } +static void * +xta_init(const device_t *info) +{ + return xta_init_common(info, info->local); +} + +static void * +xta_st50x_init(const device_t *info) +{ + hdc_dual_t *dev = (hdc_dual_t *) calloc(1, sizeof(hdc_dual_t)); + + dev->hdc[0] = xta_init_common(info, info->local); + dev->hdc[1] = xta_init_common(info, 4); + + return dev; +} + static void xta_close(void *priv) { @@ -1104,53 +1285,23 @@ xta_close(void *priv) free(dev); } +static void +xta_st50x_close(void *priv) +{ + hdc_dual_t *dev = (hdc_dual_t *) priv; + + xta_close(dev->hdc[1]); + xta_close(dev->hdc[0]); +} + +static int +st50x_available(void) +{ + return (rom_present(ST50X_BIOS_FILE)); +} + static const device_config_t wdxt150_config[] = { // clang-format off - { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = NULL, - .default_int = 0x0320, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "320H", .value = 0x0320 }, - { .description = "324H", .value = 0x0324 }, - { .description = "" } - }, - .bios = { { 0 } } - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 5, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 4", .value = 4 }, - { .description = "" } - }, - .bios = { { 0 } } - }, - { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = NULL, - .default_int = 0xc8000, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "C800H", .value = 0xc8000 }, - { .description = "CA00H", .value = 0xca000 }, - { .description = "" } - }, - .bios = { { 0 } } - }, { .name = "bios_rev", .description = "BIOS Revision", @@ -1181,6 +1332,74 @@ static const device_config_t wdxt150_config[] = { { .files_no = 0 } }, }, +#ifdef SELECTABLE_BASE + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0320, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "320H", .value = 0x0320 }, + { .description = "324H", .value = 0x0324 }, + { .description = "" } + }, + .bios = { { 0 } } + }, +#endif + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "bios_addr", + .description = "BIOS address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xc8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "C800H", .value = 0xc8000 }, + { .description = "CA00H", .value = 0xca000 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format off +}; + +static const device_config_t st50x_config[] = { + // clang-format off + { + .name = "bios_addr", + .description = "BIOS address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xc8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "C800H", .value = 0xc8000 }, + { .description = "CA00H", .value = 0xca000 }, + { .description = "" } + }, + .bios = { { 0 } } + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format off }; @@ -1212,3 +1431,31 @@ const device_t xta_hd20_device = { .force_redraw = NULL, .config = NULL }; + +const device_t xta_st50x_device = { + .name = "ST-50X Fixed Disk Controller", + .internal_name = "xta_st50x", + .flags = DEVICE_ISA, + .local = 2, + .init = xta_st50x_init, + .close = xta_st50x_close, + .reset = NULL, + .available = st50x_available, + .speed_changed = NULL, + .force_redraw = NULL, + .config = st50x_config +}; + +const device_t xta_st50x_pc5086_device = { + .name = "ST-50X Fixed Disk Controller (PC5086)", + .internal_name = "xta_st50x_pc5086", + .flags = DEVICE_ISA, + .local = 3, + .init = xta_init, + .close = xta_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/disk/hdc_xtide.c b/src/disk/hdc_xtide.c index 154a28cec..63067f579 100644 --- a/src/disk/hdc_xtide.c +++ b/src/disk/hdc_xtide.c @@ -154,7 +154,7 @@ xtide_init(const device_t *info) sprintf(xtide->nvr_path, "xtide_%i.nvr", device_get_instance()); FILE *fp = nvr_fopen(xtide->nvr_path, "rb"); if (fp != NULL) { - fread(xtide->bios_rom.rom, 1, 0x2000, fp); + (void) !fread(xtide->bios_rom.rom, 1, 0x2000, fp); fclose(fp); } } @@ -252,6 +252,37 @@ xtide_at_close(void *priv) // clang-format off static const device_config_t xtide_config[] = { + { + .name = "bios", + .description = "BIOS Revision", + .type = CONFIG_BIOS, + .default_string = "xt", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "Regular XT", + .internal_name = "xt", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { ROM_PATH_XT, "" } + }, + { + .name = "XT+ (V20/V30/8018x)", + .internal_name = "xt_plus", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { ROM_PATH_XTP, "" } + }, + { .files_no = 0 } + }, + }, { .name = "base", .description = "Address", @@ -310,7 +341,7 @@ static const device_config_t xtide_config[] = { }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xd0000, @@ -348,37 +379,6 @@ static const device_config_t xtide_config[] = { }, .bios = { { 0 } } }, - { - .name = "bios", - .description = "BIOS Revision", - .type = CONFIG_BIOS, - .default_string = "xt", - .default_int = 0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { { 0 } }, - .bios = { - { - .name = "Regular XT", - .internal_name = "xt", - .bios_type = BIOS_NORMAL, - .files_no = 1, - .local = 0, - .size = 8192, - .files = { ROM_PATH_XT, "" } - }, - { - .name = "XT+ (V20/V30/8018x)", - .internal_name = "xt_plus", - .bios_type = BIOS_NORMAL, - .files_no = 1, - .local = 0, - .size = 8192, - .files = { ROM_PATH_XTP, "" } - }, - { .files_no = 0 } - }, - }, { .name = "", .description = "", .type = CONFIG_END } }; diff --git a/src/disk/hdd.c b/src/disk/hdd.c index e051cc841..e48af6b20 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -78,6 +78,12 @@ no_cdrom: if (!strcmp(str, "scsi")) return HDD_BUS_SCSI; + + if (!strcmp(str, "mitsumi")) + return CDROM_BUS_MITSUMI; + + if (!strcmp(str, "mke")) + return CDROM_BUS_MKE; return 0; } @@ -89,6 +95,17 @@ hdd_bus_to_string(int bus, UNUSED(int cdrom)) switch (bus) { default: + if (cdrom) { + switch (bus) { + case CDROM_BUS_MITSUMI: + s = "mitsumi"; + break; + case CDROM_BUS_MKE: + s = "mke"; + break; + } + break; + } case HDD_BUS_DISABLED: break; @@ -143,8 +160,12 @@ hdd_seek_get_time(hard_disk_t *hdd, uint32_t dst_addr, uint8_t operation, uint8_ const hdd_zone_t *zone = NULL; if (hdd->num_zones <= 0) { +#ifdef DO_FATAL fatal("hdd_seek_get_time(): hdd->num_zones < 0)\n"); return 0.0; +#else + return 1000.0; +#endif } for (uint32_t i = 0; i < hdd->num_zones; i++) { zone = &hdd->zones[i]; diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index 09f48ad50..75c27f4d1 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -56,7 +56,9 @@ typedef struct hdd_image_t { hdd_image_t hdd_images[HDD_NUM]; static char empty_sector[512]; +#ifndef __unix__ static char *empty_sector_1mb; +#endif #ifdef ENABLE_HDD_IMAGE_LOG int hdd_image_do_log = ENABLE_HDD_IMAGE_LOG; diff --git a/src/disk/lba_enhancer.c b/src/disk/lba_enhancer.c deleted file mode 100644 index ef9e167d3..000000000 --- a/src/disk/lba_enhancer.c +++ /dev/null @@ -1,100 +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. - * - * Vision Systems LBA Enhancer emulation. - * - * - * - * Authors: Cacodemon345 - * - * Copyright 2024 Cacodemon345 - */ - -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/io.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/rom.h> -#include <86box/plat_unused.h> - -typedef struct lba_enhancer_t -{ - rom_t rom; -} lba_enhancer_t; - -#define BIOS_LBA_ENHANCER "roms/hdd/misc/lbaenhancer.bin" - -void -lba_enhancer_close(void* priv) -{ - free(priv); - - return; -} - -void * -lba_enhancer_init(UNUSED(const device_t *info)) -{ - lba_enhancer_t *dev = (lba_enhancer_t *) calloc(1, sizeof(lba_enhancer_t)); - - rom_init(&dev->rom, BIOS_LBA_ENHANCER, - device_get_config_hex20("bios_addr"), 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - return dev; -} - -static int -lba_enhancer_available(void) -{ - return rom_present(BIOS_LBA_ENHANCER); -} - -// clang-format off -static const device_config_t lba_enhancer_config[] = { - { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = NULL, - .default_int = 0xc8000, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "C800H", .value = 0xc8000 }, - { .description = "CC00H", .value = 0xcc000 }, - { .description = "D000H", .value = 0xd0000 }, - { .description = "D400H", .value = 0xd4000 }, - { .description = "D800H", .value = 0xd8000 }, - { .description = "DC00H", .value = 0xdc000 }, - { .description = "" } - }, - .bios = { { 0 } } - }, - { .name = "", .description = "", .type = CONFIG_END } -}; -// clang-format on - -const device_t lba_enhancer_device = { - .name = "Vision Systems LBA Enhancer", - .internal_name = "lba_enhancer", - .flags = DEVICE_ISA16, - .local = 0, - .init = lba_enhancer_init, - .close = lba_enhancer_close, - .reset = NULL, - .available = lba_enhancer_available, - .speed_changed = NULL, - .force_redraw = NULL, - .config = lba_enhancer_config -}; diff --git a/src/disk/mo.c b/src/disk/mo.c index 1a2db0443..c1f95c073 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -152,6 +152,14 @@ mo_load(const mo_t *dev, const char *fn, const int skip_insert) { const int was_empty = mo_is_empty(dev->id); int ret = 0; + int offs = 0; + + if (strstr(fn, "wp://") == fn) { + offs = 5; + dev->drv->read_only = 1; + } + + fn += offs; if (dev->drv == NULL) mo_eject(dev->id); @@ -202,7 +210,7 @@ mo_load(const mo_t *dev, const char *fn, const int skip_insert) log_fatal(dev->log, "mo_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 - offs, sizeof(dev->drv->image_path) - 1); ret = 1; } else @@ -218,6 +226,9 @@ mo_load(const mo_t *dev, const char *fn, const int skip_insert) if (was_empty) mo_insert((mo_t *) dev); } + + if (ret) + ui_sb_update_icon_wp(SB_MO | dev->id, dev->drv->read_only); } void diff --git a/src/disk/zip.c b/src/disk/rdisk.c similarity index 65% rename from src/disk/zip.c rename to src/disk/rdisk.c index 55cf901a4..5780740ad 100644 --- a/src/disk/zip.c +++ b/src/disk/rdisk.c @@ -13,7 +13,7 @@ * * Copyright 2018-2025 Miran Grca. */ -#ifdef ENABLE_ZIP_LOG +#ifdef ENABLE_RDISK_LOG #include #endif #include @@ -31,18 +31,19 @@ #include <86box/plat.h> #include <86box/ui.h> #include <86box/hdc_ide.h> -#include <86box/zip.h> +#include <86box/rdisk.h> +#include <86box/version.h> #define IDE_ATAPI_IS_EARLY id->sc->pad0 -zip_drive_t zip_drives[ZIP_NUM]; +rdisk_drive_t rdisk_drives[RDISK_NUM]; // clang-format off /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ -const uint8_t zip_command_flags[0x100] = { +const uint8_t rdisk_command_flags[0x100] = { [0x00] = IMPLEMENTED | CHECK_READY, [0x01] = IMPLEMENTED | ALLOW_UA | SCSI_ONLY, [0x03] = IMPLEMENTED | ALLOW_UA, @@ -139,35 +140,35 @@ static const mode_sense_pages_t zip_250_mode_sense_pages_changeable = { }; // clang-format on -static void zip_command_complete(zip_t *dev); -static void zip_init(zip_t *dev); +static void rdisk_command_complete(rdisk_t *dev); +static void rdisk_init(rdisk_t *dev); -#ifdef ENABLE_ZIP_LOG -int zip_do_log = ENABLE_ZIP_LOG; +#ifdef ENABLE_RDISK_LOG +int rdisk_do_log = ENABLE_RDISK_LOG; static void -zip_log(void *priv, const char *fmt, ...) +rdisk_log(void *priv, const char *fmt, ...) { va_list ap; - if (zip_do_log) { + if (rdisk_do_log) { va_start(ap, fmt); log_out(priv, fmt, ap); va_end(ap); } } #else -# define zip_log(priv, fmt, ...) +# define rdisk_log(priv, fmt, ...) #endif static int -zip_load_abort(const zip_t *dev) +rdisk_load_abort(const rdisk_t *dev) { 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. */ + rdisk_eject(dev->id); /* Make sure the host OS knows we've rejected (and ejected) the image. */ return 0; } @@ -178,9 +179,9 @@ image_is_zdi(const char *s) } int -zip_is_empty(const uint8_t id) +rdisk_is_empty(const uint8_t id) { - const zip_t *dev = (const zip_t *) zip_drives[id].priv; + const rdisk_t *dev = (const rdisk_t *) rdisk_drives[id].priv; int ret = 0; if ((dev->drv == NULL) || (dev->drv->fp == NULL)) @@ -190,13 +191,21 @@ zip_is_empty(const uint8_t id) } void -zip_load(const zip_t *dev, const char *fn, const int skip_insert) +rdisk_load(const rdisk_t *dev, const char *fn, const int skip_insert) { - const int was_empty = zip_is_empty(dev->id); + const int was_empty = rdisk_is_empty(dev->id); int ret = 0; + int offs = 0; + + if (strstr(fn, "wp://") == fn) { + offs = 5; + dev->drv->read_only = 1; + } + + fn += offs; if (dev->drv == NULL) - zip_eject(dev->id); + rdisk_eject(dev->id); else { const int is_zdi = image_is_zdi(fn); @@ -207,11 +216,11 @@ zip_load(const zip_t *dev, const char *fn, const int skip_insert) if (!dev->drv->read_only) { dev->drv->fp = plat_fopen(fn, "rb"); if (dev->drv->fp == NULL) - ret = zip_load_abort(dev); + ret = rdisk_load_abort(dev); else dev->drv->read_only = 1; } else - ret = zip_load_abort(dev); + ret = rdisk_load_abort(dev); } if (ret) { @@ -225,17 +234,17 @@ zip_load(const zip_t *dev, const char *fn, const int skip_insert) } else dev->drv->base = 0; - if (dev->drv->is_250) { + if (dev->drv->type != RDISK_TYPE_ZIP_100) { if ((size != (ZIP_250_SECTORS << 9)) && (size != (ZIP_SECTORS << 9))) { - zip_log(dev->log, "File is incorrect size for a ZIP image\n"); - zip_log(dev->log, "Must be exactly %i or %i bytes\n", + rdisk_log(dev->log, "File is incorrect size for a RDISK image\n"); + rdisk_log(dev->log, "Must be exactly %i or %i bytes\n", ZIP_250_SECTORS << 9, ZIP_SECTORS << 9); - ret = zip_load_abort(dev); + ret = rdisk_load_abort(dev); } } else if (size != (ZIP_SECTORS << 9)) { - zip_log(dev->log, "File is incorrect size for a ZIP image\n"); - zip_log(dev->log, "Must be exactly %i bytes\n", ZIP_SECTORS << 9); - ret = zip_load_abort(dev); + rdisk_log(dev->log, "File is incorrect size for a RDISK image\n"); + rdisk_log(dev->log, "Must be exactly %i bytes\n", ZIP_SECTORS << 9); + ret = rdisk_load_abort(dev); } if (ret) @@ -244,10 +253,10 @@ zip_load(const zip_t *dev, const char *fn, const int skip_insert) if (ret) { if (fseek(dev->drv->fp, dev->drv->base, SEEK_SET) == -1) - log_fatal(dev->log, "zip_load(): Error seeking to the beginning of " + log_fatal(dev->log, "rdisk_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 - offs, sizeof(dev->drv->image_path) - 1); /* After using strncpy, dev->drv->image_path needs to be explicitly null terminated to make gcc happy. @@ -264,23 +273,26 @@ zip_load(const zip_t *dev, const char *fn, const int skip_insert) if (ret && !skip_insert) { /* Signal media change to the emulated machine. */ - zip_insert((zip_t *) dev); + rdisk_insert((rdisk_t *) dev); /* The drive was previously empty, transition directly to UNIT ATTENTION. */ if (was_empty) - zip_insert((zip_t *) dev); + rdisk_insert((rdisk_t *) dev); } + + if (ret) + ui_sb_update_icon_wp(SB_RDISK | dev->id, dev->drv->read_only); } void -zip_disk_reload(const zip_t *dev) +rdisk_disk_reload(const rdisk_t *dev) { if (strlen(dev->drv->prev_image_path) != 0) - (void) zip_load(dev, dev->drv->prev_image_path, 0); + (void) rdisk_load(dev, dev->drv->prev_image_path, 0); } static void -zip_disk_unload(const zip_t *dev) +rdisk_disk_unload(const rdisk_t *dev) { if ((dev->drv != NULL) && (dev->drv->fp != NULL)) { fclose(dev->drv->fp); @@ -289,10 +301,10 @@ zip_disk_unload(const zip_t *dev) } void -zip_disk_close(const zip_t *dev) +rdisk_disk_close(const rdisk_t *dev) { if ((dev->drv != NULL) && (dev->drv->fp != NULL)) { - zip_disk_unload(dev); + rdisk_disk_unload(dev); memcpy(dev->drv->prev_image_path, dev->drv->image_path, sizeof(dev->drv->prev_image_path)); @@ -300,68 +312,68 @@ zip_disk_close(const zip_t *dev) dev->drv->medium_size = 0; - zip_insert((zip_t *) dev); + rdisk_insert((rdisk_t *) dev); } } static void -zip_set_callback(const zip_t *dev) +rdisk_set_callback(const rdisk_t *dev) { - if (dev->drv->bus_type != ZIP_BUS_SCSI) + if (dev->drv->bus_type != RDISK_BUS_SCSI) ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); } static void -zip_init(zip_t *dev) +rdisk_init(rdisk_t *dev) { - if (dev->id < ZIP_NUM) { + if (dev->id < RDISK_NUM) { dev->requested_blocks = 1; dev->sense[0] = 0xf0; dev->sense[7] = 10; dev->drv->bus_mode = 0; - if (dev->drv->bus_type >= ZIP_BUS_ATAPI) + if (dev->drv->bus_type >= RDISK_BUS_ATAPI) dev->drv->bus_mode |= 2; - if (dev->drv->bus_type < ZIP_BUS_SCSI) + if (dev->drv->bus_type < RDISK_BUS_SCSI) dev->drv->bus_mode |= 1; - zip_log(dev->log, "Bus type %i, bus mode %i\n", dev->drv->bus_type, dev->drv->bus_mode); - if (dev->drv->bus_type < ZIP_BUS_SCSI) { + rdisk_log(dev->log, "Bus type %i, bus mode %i\n", dev->drv->bus_type, dev->drv->bus_mode); + if (dev->drv->bus_type < RDISK_BUS_SCSI) { dev->tf->phase = 1; dev->tf->request_length = 0xEB14; } 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 = dev->transition = 0; - zip_info = 0x00000000; + rdisk_sense_key = rdisk_asc = rdisk_ascq = dev->unit_attention = dev->transition = 0; + rdisk_info = 0x00000000; } } static int -zip_supports_pio(const zip_t *dev) +rdisk_supports_pio(const rdisk_t *dev) { return (dev->drv->bus_mode & 1); } static int -zip_supports_dma(const zip_t *dev) +rdisk_supports_dma(const rdisk_t *dev) { return (dev->drv->bus_mode & 2); } /* Returns: 0 for none, 1 for PIO, 2 for DMA. */ static int -zip_current_mode(const zip_t *dev) +rdisk_current_mode(const rdisk_t *dev) { - if (!zip_supports_pio(dev) && !zip_supports_dma(dev)) + if (!rdisk_supports_pio(dev) && !rdisk_supports_dma(dev)) return 0; - if (zip_supports_pio(dev) && !zip_supports_dma(dev)) { - zip_log(dev->log, "Drive does not support DMA, setting to PIO\n"); + if (rdisk_supports_pio(dev) && !rdisk_supports_dma(dev)) { + rdisk_log(dev->log, "Drive does not support DMA, setting to PIO\n"); return 1; } - if (!zip_supports_pio(dev) && zip_supports_dma(dev)) + if (!rdisk_supports_pio(dev) && rdisk_supports_dma(dev)) return 2; - if (zip_supports_pio(dev) && zip_supports_dma(dev)) { - zip_log(dev->log, "Drive supports both, setting to %s\n", + if (rdisk_supports_pio(dev) && rdisk_supports_dma(dev)) { + rdisk_log(dev->log, "Drive supports both, setting to %s\n", (dev->tf->features & 1) ? "DMA" : "PIO"); return (dev->tf->features & 1) ? 2 : 1; } @@ -370,80 +382,81 @@ zip_current_mode(const zip_t *dev) } static void -zip_mode_sense_load(zip_t *dev) +rdisk_mode_sense_load(rdisk_t *dev) { char fn[512] = { 0 }; memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); - if (dev->drv->is_250) { - if (zip_drives[dev->id].bus_type == ZIP_BUS_SCSI) - memcpy(&dev->ms_pages_saved, &zip_250_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t)); - else - memcpy(&dev->ms_pages_saved, &zip_250_mode_sense_pages_default, sizeof(mode_sense_pages_t)); - } else { - if (zip_drives[dev->id].bus_type == ZIP_BUS_SCSI) + + if (dev->drv->type == RDISK_TYPE_ZIP_100) { + if (rdisk_drives[dev->id].bus_type == RDISK_BUS_SCSI) memcpy(&dev->ms_pages_saved, &zip_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t)); else memcpy(&dev->ms_pages_saved, &zip_mode_sense_pages_default, sizeof(mode_sense_pages_t)); + } else { + if (rdisk_drives[dev->id].bus_type == RDISK_BUS_SCSI) + memcpy(&dev->ms_pages_saved, &zip_250_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t)); + else + memcpy(&dev->ms_pages_saved, &zip_250_mode_sense_pages_default, sizeof(mode_sense_pages_t)); } - if (dev->drv->bus_type == ZIP_BUS_SCSI) - sprintf(fn, "scsi_zip_%02i_mode_sense_bin", dev->id); + if (dev->drv->bus_type == RDISK_BUS_SCSI) + sprintf(fn, "scsi_rdisk_%02i_mode_sense_bin", dev->id); else - sprintf(fn, "zip_%02i_mode_sense_bin", dev->id); + sprintf(fn, "rdisk_%02i_mode_sense_bin", dev->id); FILE *fp = plat_fopen(nvr_path(fn), "rb"); if (fp) { - /* Nothing to read, not used by ZIP. */ + /* Nothing to read, not used by RDISK. */ fclose(fp); } } static void -zip_mode_sense_save(const zip_t *dev) +rdisk_mode_sense_save(const rdisk_t *dev) { char fn[512] = { 0 }; - if (dev->drv->bus_type == ZIP_BUS_SCSI) - sprintf(fn, "scsi_zip_%02i_mode_sense_bin", dev->id); + if (dev->drv->bus_type == RDISK_BUS_SCSI) + sprintf(fn, "scsi_rdisk_%02i_mode_sense_bin", dev->id); else - sprintf(fn, "zip_%02i_mode_sense_bin", dev->id); + sprintf(fn, "rdisk_%02i_mode_sense_bin", dev->id); FILE *fp = plat_fopen(nvr_path(fn), "wb"); if (fp) { - /* Nothing to write, not used by ZIP. */ + /* Nothing to write, not used by RDISK. */ fclose(fp); } } /* SCSI Mode Sense 6/10. */ static uint8_t -zip_mode_sense_read(const zip_t *dev, const uint8_t pgctl, +zip_mode_sense_read(const rdisk_t *dev, const uint8_t pgctl, const uint8_t page, const uint8_t pos) { switch (pgctl) { case 0: case 3: - if (dev->drv->is_250 && (page == 5) && (pos == 9) && + if ((dev->drv->type != RDISK_TYPE_ZIP_100) && (page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) return 0x60; return dev->ms_pages_saved.pages[page][pos]; case 1: - if (dev->drv->is_250) - return zip_250_mode_sense_pages_changeable.pages[page][pos]; - else + if (dev->drv->type == RDISK_TYPE_ZIP_100) return zip_mode_sense_pages_changeable.pages[page][pos]; + else + return zip_250_mode_sense_pages_changeable.pages[page][pos]; case 2: - if (dev->drv->is_250) { - if ((page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) - return 0x60; - if (dev->drv->bus_type == ZIP_BUS_SCSI) - return zip_250_mode_sense_pages_default_scsi.pages[page][pos]; - else - return zip_250_mode_sense_pages_default.pages[page][pos]; - } else { - if (dev->drv->bus_type == ZIP_BUS_SCSI) + if (dev->drv->type == RDISK_TYPE_ZIP_100) { + if (dev->drv->bus_type == RDISK_BUS_SCSI) return zip_mode_sense_pages_default_scsi.pages[page][pos]; else return zip_mode_sense_pages_default.pages[page][pos]; + } else { + if ((page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) + return 0x60; + if (dev->drv->bus_type == RDISK_BUS_SCSI) + return zip_250_mode_sense_pages_default_scsi.pages[page][pos]; + else + return zip_250_mode_sense_pages_default.pages[page][pos]; } default: @@ -454,16 +467,16 @@ zip_mode_sense_read(const zip_t *dev, const uint8_t pgctl, } static uint32_t -zip_mode_sense(const zip_t *dev, uint8_t *buf, uint32_t pos, +rdisk_mode_sense(const rdisk_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, const uint8_t block_descriptor_len) { uint64_t pf; const uint8_t pgctl = (page >> 6) & 3; - if (dev->drv->is_250) - pf = zip_250_mode_sense_page_flags; - else + if (dev->drv->type == RDISK_TYPE_ZIP_100) pf = zip_mode_sense_page_flags; + else + pf = zip_250_mode_sense_page_flags; page &= 0x3f; @@ -484,7 +497,7 @@ zip_mode_sense(const zip_t *dev, uint8_t *buf, uint32_t pos, const uint8_t msplen = zip_mode_sense_read(dev, pgctl, i, 1); buf[pos++] = zip_mode_sense_read(dev, pgctl, i, 0); buf[pos++] = msplen; - zip_log(dev->log, "MODE SENSE: Page [%02X] length %i\n", i, msplen); + rdisk_log(dev->log, "MODE SENSE: Page [%02X] length %i\n", i, msplen); for (uint8_t j = 0; j < msplen; j++) buf[pos++] = zip_mode_sense_read(dev, pgctl, i, 2 + j); } @@ -495,7 +508,7 @@ zip_mode_sense(const zip_t *dev, uint8_t *buf, uint32_t pos, } static void -zip_update_request_length(zip_t *dev, int len, int block_len) +rdisk_update_request_length(rdisk_t *dev, int len, int block_len) { int bt; int min_len = 0; @@ -563,7 +576,7 @@ zip_update_request_length(zip_t *dev, int len, int block_len) } static double -zip_bus_speed(zip_t *dev) +rdisk_bus_speed(rdisk_t *dev) { double ret = -1.0; @@ -580,68 +593,68 @@ zip_bus_speed(zip_t *dev) } static void -zip_command_common(zip_t *dev) +rdisk_command_common(rdisk_t *dev) { dev->tf->status = BUSY_STAT; dev->tf->phase = 1; dev->tf->pos = 0; if (dev->packet_status == PHASE_COMPLETE) dev->callback = 0.0; - else if (dev->drv->bus_type == ZIP_BUS_SCSI) + else if (dev->drv->bus_type == RDISK_BUS_SCSI) dev->callback = -1.0; /* Speed depends on SCSI controller */ else - dev->callback = zip_bus_speed(dev) * (double) (dev->packet_len); + dev->callback = rdisk_bus_speed(dev) * (double) (dev->packet_len); - zip_set_callback(dev); + rdisk_set_callback(dev); } static void -zip_command_complete(zip_t *dev) +rdisk_command_complete(rdisk_t *dev) { dev->packet_status = PHASE_COMPLETE; - zip_command_common(dev); + rdisk_command_common(dev); } static void -zip_command_read(zip_t *dev) +rdisk_command_read(rdisk_t *dev) { dev->packet_status = PHASE_DATA_IN; - zip_command_common(dev); + rdisk_command_common(dev); } static void -zip_command_read_dma(zip_t *dev) +rdisk_command_read_dma(rdisk_t *dev) { dev->packet_status = PHASE_DATA_IN_DMA; - zip_command_common(dev); + rdisk_command_common(dev); } static void -zip_command_write(zip_t *dev) +rdisk_command_write(rdisk_t *dev) { dev->packet_status = PHASE_DATA_OUT; - zip_command_common(dev); + rdisk_command_common(dev); } static void -zip_command_write_dma(zip_t *dev) +rdisk_command_write_dma(rdisk_t *dev) { dev->packet_status = PHASE_DATA_OUT_DMA; - zip_command_common(dev); + rdisk_command_common(dev); } /* - dev = Pointer to current ZIP device; + dev = Pointer to current RDISK device; 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 -zip_data_command_finish(zip_t *dev, int len, const int block_len, +rdisk_data_command_finish(rdisk_t *dev, int len, const int block_len, const int alloc_len, const int direction) { - zip_log(dev->log, "Finishing command (%02X): %i, %i, %i, %i, %i\n", + rdisk_log(dev->log, "Finishing command (%02X): %i, %i, %i, %i, %i\n", dev->current_cdb[0], len, block_len, alloc_len, direction, dev->tf->request_length); dev->tf->pos = 0; @@ -649,256 +662,256 @@ zip_data_command_finish(zip_t *dev, int len, const int block_len, if (alloc_len < len) len = alloc_len; } - if ((len == 0) || (zip_current_mode(dev) == 0)) { - if (dev->drv->bus_type != ZIP_BUS_SCSI) + if ((len == 0) || (rdisk_current_mode(dev) == 0)) { + if (dev->drv->bus_type != RDISK_BUS_SCSI) dev->packet_len = 0; - zip_command_complete(dev); + rdisk_command_complete(dev); } else { - if (zip_current_mode(dev) == 2) { - if (dev->drv->bus_type != ZIP_BUS_SCSI) + if (rdisk_current_mode(dev) == 2) { + if (dev->drv->bus_type != RDISK_BUS_SCSI) dev->packet_len = alloc_len; if (direction == 0) - zip_command_read_dma(dev); + rdisk_command_read_dma(dev); else - zip_command_write_dma(dev); + rdisk_command_write_dma(dev); } else { - zip_update_request_length(dev, len, block_len); - if ((dev->drv->bus_type != ZIP_BUS_SCSI) && + rdisk_update_request_length(dev, len, block_len); + if ((dev->drv->bus_type != RDISK_BUS_SCSI) && (dev->tf->request_length == 0)) - zip_command_complete(dev); + rdisk_command_complete(dev); else if (direction == 0) - zip_command_read(dev); + rdisk_command_read(dev); else - zip_command_write(dev); + rdisk_command_write(dev); } } - zip_log(dev->log, "Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", + rdisk_log(dev->log, "Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos, dev->tf->phase); } static void -zip_sense_clear(zip_t *dev, UNUSED(int command)) +rdisk_sense_clear(rdisk_t *dev, UNUSED(int command)) { - zip_sense_key = zip_asc = zip_ascq = 0; - zip_info = 0x00000000; + rdisk_sense_key = rdisk_asc = rdisk_ascq = 0; + rdisk_info = 0x00000000; } static void -zip_set_phase(const zip_t *dev, const uint8_t phase) +rdisk_set_phase(const rdisk_t *dev, const uint8_t phase) { const uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; const uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; - if (dev->drv->bus_type == ZIP_BUS_SCSI) + if (dev->drv->bus_type == RDISK_BUS_SCSI) scsi_devices[scsi_bus][scsi_id].phase = phase; } static void -zip_cmd_error(zip_t *dev) +rdisk_cmd_error(rdisk_t *dev) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - dev->tf->error = ((zip_sense_key & 0xf) << 4) | ABRT_ERR; + rdisk_set_phase(dev, SCSI_PHASE_STATUS); + dev->tf->error = ((rdisk_sense_key & 0xf) << 4) | ABRT_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); - ui_sb_update_icon(SB_ZIP | dev->id, 0); - ui_sb_update_icon_write(SB_ZIP | dev->id, 0); - zip_log(dev->log, "[%02X] ERROR: %02X/%02X/%02X\n", dev->current_cdb[0], zip_sense_key, - zip_asc, zip_ascq); + dev->callback = 50.0 * RDISK_TIME; + rdisk_set_callback(dev); + ui_sb_update_icon(SB_RDISK | dev->id, 0); + ui_sb_update_icon_write(SB_RDISK | dev->id, 0); + rdisk_log(dev->log, "[%02X] ERROR: %02X/%02X/%02X\n", dev->current_cdb[0], rdisk_sense_key, + rdisk_asc, rdisk_ascq); } static void -zip_unit_attention(zip_t *dev) +rdisk_unit_attention(rdisk_t *dev) { - zip_set_phase(dev, SCSI_PHASE_STATUS); + rdisk_set_phase(dev, SCSI_PHASE_STATUS); dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_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); - ui_sb_update_icon(SB_ZIP | dev->id, 0); - ui_sb_update_icon_write(SB_ZIP | dev->id, 0); - zip_log(dev->log, "UNIT ATTENTION\n", dev->id); + dev->callback = 50.0 * RDISK_TIME; + rdisk_set_callback(dev); + ui_sb_update_icon(SB_RDISK | dev->id, 0); + ui_sb_update_icon_write(SB_RDISK | dev->id, 0); + rdisk_log(dev->log, "UNIT ATTENTION\n", dev->id); } static void -zip_buf_alloc(zip_t *dev, const uint32_t len) +rdisk_buf_alloc(rdisk_t *dev, const uint32_t len) { - zip_log(dev->log, "Allocated buffer length: %i\n", len); + rdisk_log(dev->log, "Allocated buffer length: %i\n", len); if (dev->buffer == NULL) dev->buffer = (uint8_t *) malloc(len); } static void -zip_buf_free(zip_t *dev) +rdisk_buf_free(rdisk_t *dev) { if (dev->buffer != NULL) { - zip_log(dev->log, "ZIP %i: Freeing buffer...\n"); + rdisk_log(dev->log, "Removable Disk %i: Freeing buffer...\n"); free(dev->buffer); dev->buffer = NULL; } } static void -zip_bus_master_error(scsi_common_t *sc) +rdisk_bus_master_error(scsi_common_t *sc) { - zip_t *dev = (zip_t *) sc; + rdisk_t *dev = (rdisk_t *) sc; - zip_buf_free(dev); - zip_sense_key = zip_asc = zip_ascq = 0; - zip_info = (dev->sector_pos >> 24) | + rdisk_buf_free(dev); + rdisk_sense_key = rdisk_asc = rdisk_ascq = 0; + rdisk_info = (dev->sector_pos >> 24) | ((dev->sector_pos >> 16) << 8) | ((dev->sector_pos >> 8) << 16) | ( dev->sector_pos << 24); - zip_cmd_error(dev); + rdisk_cmd_error(dev); } static void -zip_not_ready(zip_t *dev) +rdisk_not_ready(rdisk_t *dev) { - zip_sense_key = SENSE_NOT_READY; - zip_asc = ASC_MEDIUM_NOT_PRESENT; - zip_ascq = 0; - zip_info = 0x00000000; - zip_cmd_error(dev); + rdisk_sense_key = SENSE_NOT_READY; + rdisk_asc = ASC_MEDIUM_NOT_PRESENT; + rdisk_ascq = 0; + rdisk_info = 0x00000000; + rdisk_cmd_error(dev); } static void -zip_write_protected(zip_t *dev) +rdisk_write_protected(rdisk_t *dev) { - zip_sense_key = SENSE_UNIT_ATTENTION; - zip_asc = ASC_WRITE_PROTECTED; - zip_ascq = 0; - zip_info = (dev->sector_pos >> 24) | + rdisk_sense_key = SENSE_UNIT_ATTENTION; + rdisk_asc = ASC_WRITE_PROTECTED; + rdisk_ascq = 0; + rdisk_info = (dev->sector_pos >> 24) | ((dev->sector_pos >> 16) << 8) | ((dev->sector_pos >> 8) << 16) | ( dev->sector_pos << 24); - zip_cmd_error(dev); + rdisk_cmd_error(dev); } static void -zip_write_error(zip_t *dev) +rdisk_write_error(rdisk_t *dev) { - zip_sense_key = SENSE_MEDIUM_ERROR; - zip_asc = ASC_WRITE_ERROR; - zip_ascq = 0; - zip_info = (dev->sector_pos >> 24) | + rdisk_sense_key = SENSE_MEDIUM_ERROR; + rdisk_asc = ASC_WRITE_ERROR; + rdisk_ascq = 0; + rdisk_info = (dev->sector_pos >> 24) | ((dev->sector_pos >> 16) << 8) | ((dev->sector_pos >> 8) << 16) | ( dev->sector_pos << 24); - zip_cmd_error(dev); + rdisk_cmd_error(dev); } static void -zip_read_error(zip_t *dev) +rdisk_read_error(rdisk_t *dev) { - zip_sense_key = SENSE_MEDIUM_ERROR; - zip_asc = ASC_UNRECOVERED_READ_ERROR; - zip_ascq = 0; - zip_info = (dev->sector_pos >> 24) | + rdisk_sense_key = SENSE_MEDIUM_ERROR; + rdisk_asc = ASC_UNRECOVERED_READ_ERROR; + rdisk_ascq = 0; + rdisk_info = (dev->sector_pos >> 24) | ((dev->sector_pos >> 16) << 8) | ((dev->sector_pos >> 8) << 16) | ( dev->sector_pos << 24); - zip_cmd_error(dev); + rdisk_cmd_error(dev); } static void -zip_invalid_lun(zip_t *dev, const uint8_t lun) +rdisk_invalid_lun(rdisk_t *dev, const uint8_t lun) { - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_INV_LUN; - zip_ascq = 0; - zip_info = lun << 24; - zip_cmd_error(dev); + rdisk_sense_key = SENSE_ILLEGAL_REQUEST; + rdisk_asc = ASC_INV_LUN; + rdisk_ascq = 0; + rdisk_info = lun << 24; + rdisk_cmd_error(dev); } static void -zip_illegal_opcode(zip_t *dev, const uint8_t opcode) +rdisk_illegal_opcode(rdisk_t *dev, const uint8_t opcode) { - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_ILLEGAL_OPCODE; - zip_ascq = 0; - zip_info = opcode << 24; - zip_cmd_error(dev); + rdisk_sense_key = SENSE_ILLEGAL_REQUEST; + rdisk_asc = ASC_ILLEGAL_OPCODE; + rdisk_ascq = 0; + rdisk_info = opcode << 24; + rdisk_cmd_error(dev); } static void -zip_lba_out_of_range(zip_t *dev) +rdisk_lba_out_of_range(rdisk_t *dev) { - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_LBA_OUT_OF_RANGE; - zip_ascq = 0; - zip_info = (dev->sector_pos >> 24) | + rdisk_sense_key = SENSE_ILLEGAL_REQUEST; + rdisk_asc = ASC_LBA_OUT_OF_RANGE; + rdisk_ascq = 0; + rdisk_info = (dev->sector_pos >> 24) | ((dev->sector_pos >> 16) << 8) | ((dev->sector_pos >> 8) << 16) | ( dev->sector_pos << 24); - zip_cmd_error(dev); + rdisk_cmd_error(dev); } static void -zip_invalid_field(zip_t *dev, const uint32_t field) +rdisk_invalid_field(rdisk_t *dev, const uint32_t field) { - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_INV_FIELD_IN_CMD_PACKET; - zip_ascq = 0; - zip_info = (field >> 24) | + rdisk_sense_key = SENSE_ILLEGAL_REQUEST; + rdisk_asc = ASC_INV_FIELD_IN_CMD_PACKET; + rdisk_ascq = 0; + rdisk_info = (field >> 24) | ((field >> 16) << 8) | ((field >> 8) << 16) | ( field << 24); - zip_cmd_error(dev); + rdisk_cmd_error(dev); dev->tf->status = 0x53; } static void -zip_invalid_field_pl(zip_t *dev, const uint32_t field) +rdisk_invalid_field_pl(rdisk_t *dev, const uint32_t field) { - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; - zip_ascq = 0; - zip_info = (field >> 24) | + rdisk_sense_key = SENSE_ILLEGAL_REQUEST; + rdisk_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; + rdisk_ascq = 0; + rdisk_info = (field >> 24) | ((field >> 16) << 8) | ((field >> 8) << 16) | ( field << 24); - zip_cmd_error(dev); + rdisk_cmd_error(dev); dev->tf->status = 0x53; } static void -zip_data_phase_error(zip_t *dev, const uint32_t info) +rdisk_data_phase_error(rdisk_t *dev, const uint32_t info) { - zip_sense_key = SENSE_ILLEGAL_REQUEST; - zip_asc = ASC_DATA_PHASE_ERROR; - zip_ascq = 0; - zip_info = (info >> 24) | + rdisk_sense_key = SENSE_ILLEGAL_REQUEST; + rdisk_asc = ASC_DATA_PHASE_ERROR; + rdisk_ascq = 0; + rdisk_info = (info >> 24) | ((info >> 16) << 8) | ((info >> 8) << 16) | ( info << 24); - zip_cmd_error(dev); + rdisk_cmd_error(dev); } static int -zip_blocks(zip_t *dev, int32_t *len, const int out) +rdisk_blocks(rdisk_t *dev, int32_t *len, const int out) { int ret = 1; *len = 0; if (dev->sector_len > 0) { - zip_log(dev->log, "%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", + rdisk_log(dev->log, "%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", dev->requested_blocks, dev->sector_pos); if (dev->sector_pos >= dev->drv->medium_size) { - zip_log(dev->log, "Trying to %s beyond the end of disk\n", + rdisk_log(dev->log, "Trying to %s beyond the end of disk\n", out ? "write" : "read"); - zip_lba_out_of_range(dev); + rdisk_lba_out_of_range(dev); ret = 0; } else { *len = dev->requested_blocks << 9; @@ -907,9 +920,9 @@ zip_blocks(zip_t *dev, int32_t *len, const int out) if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos << 9), SEEK_SET) == -1) { if (out) - zip_write_error(dev); + rdisk_write_error(dev); else - zip_read_error(dev); + rdisk_read_error(dev); ret = -1; } else { if (feof(dev->drv->fp)) @@ -918,15 +931,15 @@ zip_blocks(zip_t *dev, int32_t *len, const int out) if (out) { if (fwrite(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512) { - zip_log(dev->log, "zip_blocks(): Error writing data\n"); - zip_write_error(dev); + rdisk_log(dev->log, "rdisk_blocks(): Error writing data\n"); + rdisk_write_error(dev); ret = -1; } else fflush(dev->drv->fp); } else if (fread(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512) { - zip_log(dev->log, "zip_blocks(): Error reading data\n"); - zip_read_error(dev); + rdisk_log(dev->log, "rdisk_blocks(): Error reading data\n"); + rdisk_read_error(dev); ret = -1; } } @@ -938,14 +951,14 @@ zip_blocks(zip_t *dev, int32_t *len, const int out) } if (ret == 1) { - zip_log(dev->log, "%s %i bytes of blocks...\n", out ? "Written" : + rdisk_log(dev->log, "%s %i bytes of blocks...\n", out ? "Written" : "Read", *len); dev->sector_len -= dev->requested_blocks; } } } else { - zip_command_complete(dev); + rdisk_command_complete(dev); ret = 0; } @@ -953,61 +966,61 @@ zip_blocks(zip_t *dev, int32_t *len, const int out) } void -zip_insert(zip_t *dev) +rdisk_insert(rdisk_t *dev) { if ((dev != NULL) && (dev->drv != NULL)) { if (dev->drv->fp == NULL) { dev->unit_attention = 0; dev->transition = 0; - zip_log(dev->log, "Media removal\n"); + rdisk_log(dev->log, "Media removal\n"); } else if (dev->transition) { dev->unit_attention = 1; /* Turn off the medium changed status. */ dev->transition = 0; - zip_log(dev->log, "Media insert\n"); + rdisk_log(dev->log, "Media insert\n"); } else { dev->unit_attention = 0; dev->transition = 1; - zip_log(dev->log, "Media transition\n"); + rdisk_log(dev->log, "Media transition\n"); } } } static int -zip_pre_execution_check(zip_t *dev, const uint8_t *cdb) +rdisk_pre_execution_check(rdisk_t *dev, const uint8_t *cdb) { int ready; if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { - zip_log(dev->log, "Attempting to execute a unknown command targeted at SCSI LUN %i\n", + rdisk_log(dev->log, "Attempting to execute a unknown command targeted at SCSI LUN %i\n", ((dev->tf->request_length >> 5) & 7)); - zip_invalid_lun(dev, cdb[1] >> 5); + rdisk_invalid_lun(dev, cdb[1] >> 5); return 0; } - if (!(zip_command_flags[cdb[0]] & IMPLEMENTED)) { - zip_log(dev->log, "Attempting to execute unknown command %02X over %s\n", - cdb[0], (dev->drv->bus_type == ZIP_BUS_SCSI) ? + if (!(rdisk_command_flags[cdb[0]] & IMPLEMENTED)) { + rdisk_log(dev->log, "Attempting to execute unknown command %02X over %s\n", + cdb[0], (dev->drv->bus_type == RDISK_BUS_SCSI) ? "SCSI" : "ATAPI"); - zip_illegal_opcode(dev, cdb[0]); + rdisk_illegal_opcode(dev, cdb[0]); return 0; } - if ((dev->drv->bus_type < ZIP_BUS_SCSI) && - (zip_command_flags[cdb[0]] & SCSI_ONLY)) { - zip_log(dev->log, "Attempting to execute SCSI-only command %02X " + if ((dev->drv->bus_type < RDISK_BUS_SCSI) && + (rdisk_command_flags[cdb[0]] & SCSI_ONLY)) { + rdisk_log(dev->log, "Attempting to execute SCSI-only command %02X " "over ATAPI\n", cdb[0]); - zip_illegal_opcode(dev, cdb[0]); + rdisk_illegal_opcode(dev, cdb[0]); return 0; } - if ((dev->drv->bus_type == ZIP_BUS_SCSI) && - (zip_command_flags[cdb[0]] & ATAPI_ONLY)) { - zip_log(dev->log, "Attempting to execute ATAPI-only command %02X " + if ((dev->drv->bus_type == RDISK_BUS_SCSI) && + (rdisk_command_flags[cdb[0]] & ATAPI_ONLY)) { + rdisk_log(dev->log, "Attempting to execute ATAPI-only command %02X " "over SCSI\n", cdb[0]); - zip_illegal_opcode(dev, cdb[0]); + rdisk_illegal_opcode(dev, cdb[0]); return 0; } @@ -1015,9 +1028,9 @@ zip_pre_execution_check(zip_t *dev, const uint8_t *cdb) if ((cdb[0] == GPCMD_TEST_UNIT_READY) || (cdb[0] == GPCMD_REQUEST_SENSE)) ready = 0; else { - if (!(zip_command_flags[cdb[0]] & ALLOW_UA)) { - zip_log(dev->log, "(ext_medium_changed != 0): zip_insert()\n"); - zip_insert((void *) dev); + if (!(rdisk_command_flags[cdb[0]] & ALLOW_UA)) { + rdisk_log(dev->log, "(ext_medium_changed != 0): rdisk_insert()\n"); + rdisk_insert((void *) dev); } ready = (dev->drv->fp != NULL); @@ -1042,17 +1055,17 @@ zip_pre_execution_check(zip_t *dev, const uint8_t *cdb) Only increment the unit attention phase if the command can not pass through it. */ - if (!(zip_command_flags[cdb[0]] & ALLOW_UA)) { - zip_log(dev->log, "Unit attention now 2\n"); + if (!(rdisk_command_flags[cdb[0]] & ALLOW_UA)) { + rdisk_log(dev->log, "Unit attention now 2\n"); dev->unit_attention++; - zip_log(dev->log, "UNIT ATTENTION: Command %02X not allowed to pass through\n", + rdisk_log(dev->log, "UNIT ATTENTION: Command %02X not allowed to pass through\n", cdb[0]); - zip_unit_attention(dev); + rdisk_unit_attention(dev); return 0; } } else if (dev->unit_attention == 2) { if (cdb[0] != GPCMD_REQUEST_SENSE) { - zip_log(dev->log, "Unit attention now 0\n"); + rdisk_log(dev->log, "Unit attention now 0\n"); dev->unit_attention = 0; } } @@ -1062,51 +1075,51 @@ zip_pre_execution_check(zip_t *dev, const uint8_t *cdb) the UNIT ATTENTION condition if it's set. */ if (cdb[0] != GPCMD_REQUEST_SENSE) - zip_sense_clear(dev, cdb[0]); + rdisk_sense_clear(dev, cdb[0]); - if (!ready && (zip_command_flags[cdb[0]] & CHECK_READY)) { - zip_log(dev->log, "Not ready (%02X)\n", cdb[0]); - zip_not_ready(dev); + if (!ready && (rdisk_command_flags[cdb[0]] & CHECK_READY)) { + rdisk_log(dev->log, "Not ready (%02X)\n", cdb[0]); + rdisk_not_ready(dev); return 0; } - zip_log(dev->log, "Continuing with command %02X\n", cdb[0]); + rdisk_log(dev->log, "Continuing with command %02X\n", cdb[0]); return 1; } static void -zip_seek(zip_t *dev, const uint32_t pos) +rdisk_seek(rdisk_t *dev, const uint32_t pos) { dev->sector_pos = pos; } static void -zip_rezero(zip_t *dev) +rdisk_rezero(rdisk_t *dev) { dev->sector_pos = dev->sector_len = 0; - zip_seek(dev, 0); + rdisk_seek(dev, 0); } void -zip_reset(scsi_common_t *sc) +rdisk_reset(scsi_common_t *sc) { - zip_t *dev = (zip_t *) sc; + rdisk_t *dev = (rdisk_t *) sc; - zip_rezero(dev); + rdisk_rezero(dev); dev->tf->status = 0; dev->callback = 0.0; - zip_set_callback(dev); + rdisk_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; - zip_sense_key = zip_asc = zip_ascq = dev->unit_attention = dev->transition = 0; - zip_info = 0x00000000; + rdisk_sense_key = rdisk_asc = rdisk_ascq = dev->unit_attention = dev->transition = 0; + rdisk_info = 0x00000000; } static void -zip_request_sense(zip_t *dev, uint8_t *buffer, const uint8_t alloc_length, const int desc) +rdisk_request_sense(rdisk_t *dev, uint8_t *buffer, const uint8_t alloc_length, const int desc) { /*Will return 18 bytes of 0*/ if (alloc_length != 0) { @@ -1114,9 +1127,9 @@ zip_request_sense(zip_t *dev, uint8_t *buffer, const uint8_t alloc_length, const if (!desc) memcpy(buffer, dev->sense, alloc_length); else { - buffer[1] = zip_sense_key; - buffer[2] = zip_asc; - buffer[3] = zip_ascq; + buffer[1] = rdisk_sense_key; + buffer[2] = rdisk_asc; + buffer[3] = rdisk_ascq; } } @@ -1124,13 +1137,13 @@ zip_request_sense(zip_t *dev, uint8_t *buffer, const uint8_t alloc_length, const if (!desc) buffer[7] = 10; - if (dev->unit_attention && (zip_sense_key == 0)) { + if (dev->unit_attention && (rdisk_sense_key == 0)) { buffer[desc ? 1 : 2] = SENSE_UNIT_ATTENTION; buffer[desc ? 2 : 12] = ASC_MEDIUM_MAY_HAVE_CHANGED; buffer[desc ? 3 : 13] = 0; } - zip_log(dev->log, "Reporting sense: %02X %02X %02X\n", buffer[2], + rdisk_log(dev->log, "Reporting sense: %02X %02X %02X\n", buffer[2], buffer[12], buffer[13]); if (buffer[desc ? 1 : 2] == SENSE_UNIT_ATTENTION) { @@ -1140,18 +1153,18 @@ zip_request_sense(zip_t *dev, uint8_t *buffer, const uint8_t alloc_length, const } /* Clear the sense stuff as per the spec. */ - zip_sense_clear(dev, GPCMD_REQUEST_SENSE); + rdisk_sense_clear(dev, GPCMD_REQUEST_SENSE); if (dev->transition) { - zip_log(dev->log, "ZIP_TRANSITION: zip_insert()\n"); - zip_insert((void *) dev); + rdisk_log(dev->log, "Removable Disk_TRANSITION: rdisk_insert()\n"); + rdisk_insert((void *) dev); } } static void -zip_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, const uint8_t alloc_length) +rdisk_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, const uint8_t alloc_length) { - zip_t *dev = (zip_t *) sc; + rdisk_t *dev = (rdisk_t *) sc; const int ready = (dev->drv->fp != NULL); if (!ready && dev->unit_attention) { @@ -1163,32 +1176,33 @@ zip_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, const uint8_t all } /* Do *NOT* advance the unit attention phase. */ - zip_request_sense(dev, buffer, alloc_length, 0); + rdisk_request_sense(dev, buffer, alloc_length, 0); } static void -zip_set_buf_len(const zip_t *dev, int32_t *BufLen, int32_t *src_len) +rdisk_set_buf_len(const rdisk_t *dev, int32_t *BufLen, int32_t *src_len) { - if (dev->drv->bus_type == ZIP_BUS_SCSI) { + if (dev->drv->bus_type == RDISK_BUS_SCSI) { if (*BufLen == -1) *BufLen = *src_len; else { *BufLen = MIN(*src_len, *BufLen); *src_len = *BufLen; } - zip_log(dev->log, "Actual transfer length: %i\n", *BufLen); + rdisk_log(dev->log, "Actual transfer length: %i\n", *BufLen); } } static void -zip_command(scsi_common_t *sc, const uint8_t *cdb) +rdisk_command(scsi_common_t *sc, const uint8_t *cdb) { - zip_t *dev = (zip_t *) sc; - const uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - const uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; - int pos = 0; - int idx = 0; - int32_t blen = 0; + rdisk_t *dev = (rdisk_t *) sc; + char device_identify[9] = { '8', '6', 'B', '_', 'R', 'D', '0', '0', 0 }; + const uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; + const uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + int pos = 0; + int idx = 0; + int32_t blen = 0; uint32_t i; unsigned preamble_len; int32_t len; @@ -1198,7 +1212,7 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) int size_idx; int32_t * BufLen; - if (dev->drv->bus_type == ZIP_BUS_SCSI) { + if (dev->drv->bus_type == RDISK_BUS_SCSI) { BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; dev->tf->status &= ~ERR_STAT; } else { @@ -1209,15 +1223,17 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) dev->packet_len = 0; dev->request_pos = 0; + device_identify[7] = dev->id + 0x30; + memcpy(dev->current_cdb, cdb, 12); if (cdb[0] != 0) { - zip_log(dev->log, "Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, " + rdisk_log(dev->log, "Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, " "Unit attention: %i\n", - cdb[0], zip_sense_key, zip_asc, zip_ascq, dev->unit_attention); - zip_log(dev->log, "Request length: %04X\n", dev->tf->request_length); + cdb[0], rdisk_sense_key, rdisk_asc, rdisk_ascq, dev->unit_attention); + rdisk_log(dev->log, "Request length: %04X\n", dev->tf->request_length); - zip_log(dev->log, "CDB: %02X %02X %02X %02X %02X %02X %02X %02X " + rdisk_log(dev->log, "CDB: %02X %02X %02X %02X %02X %02X %02X %02X " "%02X %02X %02X %02X\n", cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9], cdb[10], cdb[11]); @@ -1225,43 +1241,43 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) dev->sector_len = 0; - zip_set_phase(dev, SCSI_PHASE_STATUS); + rdisk_set_phase(dev, SCSI_PHASE_STATUS); /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ - if (zip_pre_execution_check(dev, cdb) == 0) + if (rdisk_pre_execution_check(dev, cdb) == 0) return; switch (cdb[0]) { case GPCMD_SEND_DIAGNOSTIC: if (!(cdb[1] & (1 << 2))) { - zip_invalid_field(dev, cdb[1]); + rdisk_invalid_field(dev, cdb[1]); return; } fallthrough; case GPCMD_SCSI_RESERVE: case GPCMD_SCSI_RELEASE: case GPCMD_TEST_UNIT_READY: - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_command_complete(dev); + rdisk_set_phase(dev, SCSI_PHASE_STATUS); + rdisk_command_complete(dev); break; case GPCMD_FORMAT_UNIT: if (dev->drv->read_only) - zip_write_protected(dev); + rdisk_write_protected(dev); else { - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_command_complete(dev); + rdisk_set_phase(dev, SCSI_PHASE_STATUS); + rdisk_command_complete(dev); } break; case GPCMD_IOMEGA_SENSE: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); + rdisk_set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[4]; - zip_buf_alloc(dev, 256); - zip_set_buf_len(dev, BufLen, &max_len); + rdisk_buf_alloc(dev, 256); + rdisk_set_buf_len(dev, BufLen, &max_len); memset(dev->buffer, 0, 256); if (cdb[2] == 1) { /* @@ -1283,17 +1299,17 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) for (i = 0x00; i < 0x27; i++) dev->buffer[i + 0x16] = 0x00; } else { - zip_invalid_field(dev, cdb[2]); - zip_buf_free(dev); + rdisk_invalid_field(dev, cdb[2]); + rdisk_buf_free(dev); return; } - zip_data_command_finish(dev, 18, 18, cdb[4], 0); + rdisk_data_command_finish(dev, 18, 18, cdb[4], 0); break; case GPCMD_REZERO_UNIT: dev->sector_pos = dev->sector_len = 0; - zip_seek(dev, 0); - zip_set_phase(dev, SCSI_PHASE_STATUS); + rdisk_seek(dev, 0); + rdisk_set_phase(dev, SCSI_PHASE_STATUS); break; case GPCMD_REQUEST_SENSE: @@ -1302,41 +1318,41 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) standalone REQUEST SENSE should forget about the not ready, and report unit attention straight away. */ - zip_set_phase(dev, SCSI_PHASE_DATA_IN); + rdisk_set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[4]; if (!max_len) { - zip_set_phase(dev, SCSI_PHASE_STATUS); + rdisk_set_phase(dev, SCSI_PHASE_STATUS); dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * ZIP_TIME; - zip_set_callback(dev); + dev->callback = 20.0 * RDISK_TIME; + rdisk_set_callback(dev); break; } - zip_buf_alloc(dev, 256); - zip_set_buf_len(dev, BufLen, &max_len); + rdisk_buf_alloc(dev, 256); + rdisk_set_buf_len(dev, BufLen, &max_len); len = (cdb[1] & 1) ? 8 : 18; - zip_request_sense(dev, dev->buffer, max_len, cdb[1] & 1); - zip_data_command_finish(dev, len, len, cdb[4], 0); + rdisk_request_sense(dev, dev->buffer, max_len, cdb[1] & 1); + rdisk_data_command_finish(dev, len, len, cdb[4], 0); break; case GPCMD_MECHANISM_STATUS: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); + rdisk_set_phase(dev, SCSI_PHASE_DATA_IN); len = (cdb[8] << 8) | cdb[9]; - zip_buf_alloc(dev, 8); - zip_set_buf_len(dev, BufLen, &len); + rdisk_buf_alloc(dev, 8); + rdisk_set_buf_len(dev, BufLen, &len); memset(dev->buffer, 0, 8); dev->buffer[5] = 1; - zip_data_command_finish(dev, 8, 8, len, 0); + rdisk_data_command_finish(dev, 8, 8, len, 0); break; case GPCMD_READ_6: case GPCMD_READ_10: case GPCMD_READ_12: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); + rdisk_set_phase(dev, SCSI_PHASE_DATA_IN); alloc_length = 512; switch (cdb[0]) { @@ -1350,13 +1366,13 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) dev->sector_len = 256; dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - zip_log(dev->log, "Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); + rdisk_log(dev->log, "Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); 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]; - zip_log(dev->log, "Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); + rdisk_log(dev->log, "Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; case GPCMD_READ_12: dev->sector_len = (((uint32_t) cdb[6]) << 24) | @@ -1372,41 +1388,41 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) } if (dev->sector_pos >= dev->drv->medium_size) - zip_lba_out_of_range(dev); + rdisk_lba_out_of_range(dev); else if (dev->sector_len) { max_len = dev->sector_len; dev->requested_blocks = max_len; dev->packet_len = max_len * alloc_length; - zip_buf_alloc(dev, dev->packet_len); + rdisk_buf_alloc(dev, dev->packet_len); - const int ret = zip_blocks(dev, &alloc_length, 0); + const int ret = rdisk_blocks(dev, &alloc_length, 0); alloc_length = dev->requested_blocks * 512; if (ret > 0) { dev->requested_blocks = max_len; dev->packet_len = alloc_length; - zip_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + rdisk_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - zip_data_command_finish(dev, alloc_length, 512, + rdisk_data_command_finish(dev, alloc_length, 512, alloc_length, 0); - ui_sb_update_icon(SB_ZIP | dev->id, + ui_sb_update_icon(SB_RDISK | dev->id, dev->packet_status != PHASE_COMPLETE); } else { - zip_set_phase(dev, SCSI_PHASE_STATUS); + rdisk_set_phase(dev, SCSI_PHASE_STATUS); dev->packet_status = (ret < 0) ? PHASE_ERROR : PHASE_COMPLETE; - dev->callback = 20.0 * ZIP_TIME; - zip_set_callback(dev); - zip_buf_free(dev); + dev->callback = 20.0 * RDISK_TIME; + rdisk_set_callback(dev); + rdisk_buf_free(dev); } } else { - zip_set_phase(dev, SCSI_PHASE_STATUS); - /* zip_log(dev->log, "All done - callback set\n"); */ + rdisk_set_phase(dev, SCSI_PHASE_STATUS); + /* rdisk_log(dev->log, "All done - callback set\n"); */ dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * ZIP_TIME; - zip_set_callback(dev); + dev->callback = 20.0 * RDISK_TIME; + rdisk_set_callback(dev); break; } break; @@ -1415,8 +1431,8 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) case GPCMD_VERIFY_10: case GPCMD_VERIFY_12: if (!(cdb[1] & 2)) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_command_complete(dev); + rdisk_set_phase(dev, SCSI_PHASE_STATUS); + rdisk_command_complete(dev); break; } fallthrough; @@ -1425,11 +1441,11 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) case GPCMD_WRITE_AND_VERIFY_10: case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: - zip_set_phase(dev, SCSI_PHASE_DATA_OUT); + rdisk_set_phase(dev, SCSI_PHASE_DATA_OUT); alloc_length = 512; if (dev->drv->read_only) { - zip_write_protected(dev); + rdisk_write_protected(dev); break; } @@ -1452,7 +1468,7 @@ zip_command(scsi_common_t *sc, const 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]; - zip_log(dev->log, "Length: %i, LBA: %i\n", + rdisk_log(dev->log, "Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; case GPCMD_VERIFY_12: @@ -1471,71 +1487,71 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) } if (dev->sector_pos >= dev->drv->medium_size) - zip_lba_out_of_range(dev); + rdisk_lba_out_of_range(dev); if (dev->sector_len) { max_len = dev->sector_len; dev->requested_blocks = max_len; dev->packet_len = max_len * alloc_length; - zip_buf_alloc(dev, dev->packet_len); + rdisk_buf_alloc(dev, dev->packet_len); dev->requested_blocks = max_len; dev->packet_len = max_len << 9; - zip_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + rdisk_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - zip_data_command_finish(dev, dev->packet_len, 512, + rdisk_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1); - ui_sb_update_icon_write(SB_ZIP | dev->id, + ui_sb_update_icon_write(SB_RDISK | dev->id, dev->packet_status != PHASE_COMPLETE); } else { - zip_set_phase(dev, SCSI_PHASE_STATUS); - /* zip_log(dev->log, "All done - callback set\n"); */ + rdisk_set_phase(dev, SCSI_PHASE_STATUS); + /* rdisk_log(dev->log, "All done - callback set\n"); */ dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * ZIP_TIME; - zip_set_callback(dev); + dev->callback = 20.0 * RDISK_TIME; + rdisk_set_callback(dev); } break; case GPCMD_WRITE_SAME_10: - zip_set_phase(dev, SCSI_PHASE_DATA_OUT); + rdisk_set_phase(dev, SCSI_PHASE_DATA_OUT); alloc_length = 512; if ((cdb[1] & 6) == 6) - zip_invalid_field(dev, cdb[1]); + rdisk_invalid_field(dev, cdb[1]); else { if (dev->drv->read_only) - zip_write_protected(dev); + rdisk_write_protected(dev); else { 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) - zip_lba_out_of_range(dev); + rdisk_lba_out_of_range(dev); else if (dev->sector_len) { - zip_buf_alloc(dev, alloc_length); - zip_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + rdisk_buf_alloc(dev, alloc_length); + rdisk_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); max_len = 1; dev->requested_blocks = 1; dev->packet_len = alloc_length; - zip_set_phase(dev, SCSI_PHASE_DATA_OUT); + rdisk_set_phase(dev, SCSI_PHASE_DATA_OUT); - zip_data_command_finish(dev, 512, 512, + rdisk_data_command_finish(dev, 512, 512, alloc_length, 1); - ui_sb_update_icon_write(SB_ZIP | dev->id, + ui_sb_update_icon_write(SB_RDISK | dev->id, dev->packet_status != PHASE_COMPLETE); } else { - zip_set_phase(dev, SCSI_PHASE_STATUS); - /* zip_log(dev->log, "All done - callback set\n"); */ + rdisk_set_phase(dev, SCSI_PHASE_STATUS); + /* rdisk_log(dev->log, "All done - callback set\n"); */ dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * ZIP_TIME; - zip_set_callback(dev); + dev->callback = 20.0 * RDISK_TIME; + rdisk_set_callback(dev); } } } @@ -1543,19 +1559,19 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); + rdisk_set_phase(dev, SCSI_PHASE_DATA_IN); - if (dev->drv->bus_type == ZIP_BUS_SCSI) + if (dev->drv->bus_type == RDISK_BUS_SCSI) block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; else block_desc = 0; if (cdb[0] == GPCMD_MODE_SENSE_6) { len = cdb[4]; - zip_buf_alloc(dev, 256); + rdisk_buf_alloc(dev, 256); } else { len = (cdb[8] | (cdb[7] << 8)); - zip_buf_alloc(dev, 65536); + rdisk_buf_alloc(dev, 65536); } if (zip_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f))) { @@ -1563,16 +1579,16 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) alloc_length = len; if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = zip_mode_sense(dev, dev->buffer, 4, cdb[2], - block_desc); + len = rdisk_mode_sense(dev, dev->buffer, 4, cdb[2], + block_desc); len = MIN(len, alloc_length); dev->buffer[0] = len - 1; dev->buffer[1] = 0; if (block_desc) dev->buffer[3] = 8; } else { - len = zip_mode_sense(dev, dev->buffer, 8, cdb[2], - block_desc); + len = rdisk_mode_sense(dev, dev->buffer, 8, cdb[2], + block_desc); len = MIN(len, alloc_length); dev->buffer[0] = (len - 2) >> 8; dev->buffer[1] = (len - 2) & 255; @@ -1583,70 +1599,70 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) } } - zip_set_buf_len(dev, BufLen, &len); + rdisk_set_buf_len(dev, BufLen, &len); - zip_log(dev->log, "Reading mode page: %02X...\n", cdb[2]); + rdisk_log(dev->log, "Reading mode page: %02X...\n", cdb[2]); - zip_data_command_finish(dev, len, len, alloc_length, 0); + rdisk_data_command_finish(dev, len, len, alloc_length, 0); } else { - zip_invalid_field(dev, cdb[2]); - zip_buf_free(dev); + rdisk_invalid_field(dev, cdb[2]); + rdisk_buf_free(dev); } break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - zip_set_phase(dev, SCSI_PHASE_DATA_OUT); + rdisk_set_phase(dev, SCSI_PHASE_DATA_OUT); if (cdb[0] == GPCMD_MODE_SELECT_6) { len = cdb[4]; - zip_buf_alloc(dev, 256); + rdisk_buf_alloc(dev, 256); } else { len = (cdb[7] << 8) | cdb[8]; - zip_buf_alloc(dev, 65536); + rdisk_buf_alloc(dev, 65536); } - zip_set_buf_len(dev, BufLen, &len); + rdisk_set_buf_len(dev, BufLen, &len); dev->total_length = len; dev->do_page_save = cdb[1] & 1; - zip_data_command_finish(dev, len, len, len, 1); + rdisk_data_command_finish(dev, len, len, len, 1); return; case GPCMD_START_STOP_UNIT: - zip_set_phase(dev, SCSI_PHASE_STATUS); + rdisk_set_phase(dev, SCSI_PHASE_STATUS); switch (cdb[4] & 3) { case 0: /* Stop the disc. */ - zip_eject(dev->id); /* The Iomega Windows 9x drivers require this. */ + rdisk_eject(dev->id); /* The Iomega Windows 9x drivers require this. */ break; case 1: /* Start the disc and read the TOC. */ break; case 2: /* Eject the disc if possible. */ #if 0 - zip_eject(dev->id); + rdisk_eject(dev->id); #endif break; case 3: /* Load the disc (close tray). */ - zip_reload(dev->id); + rdisk_reload(dev->id); break; default: break; } - zip_command_complete(dev); + rdisk_command_complete(dev); break; case GPCMD_INQUIRY: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); + rdisk_set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[3]; max_len <<= 8; max_len |= cdb[4]; - zip_buf_alloc(dev, 65536); + rdisk_buf_alloc(dev, 65536); if (cdb[1] & 1) { preamble_len = 4; @@ -1665,8 +1681,8 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) break; case 0x83: if (idx + 24 > max_len) { - zip_data_phase_error(dev, cdb[2]); - zip_buf_free(dev); + rdisk_data_phase_error(dev, cdb[2]); + rdisk_buf_free(dev); return; } @@ -1684,21 +1700,26 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) dev->buffer[idx++] = 0x00; dev->buffer[idx++] = 68; /* Vendor */ - ide_padstr8(dev->buffer + idx, 8, "IOMEGA "); + if (dev->drv->type >= RDISK_TYPE_ZIP_100) + ide_padstr8(dev->buffer + idx, 8, "IOMEGA "); + else + ide_padstr8(dev->buffer + 8, 8, EMU_NAME); /* Vendor */ idx += 8; /* Product */ - if (dev->drv->is_250) + if (dev->drv->type == RDISK_TYPE_ZIP_250) ide_padstr8(dev->buffer + idx, 40, "ZIP 250 "); - else + else if (dev->drv->type == RDISK_TYPE_ZIP_100) ide_padstr8(dev->buffer + idx, 40, "ZIP 100 "); + else + ide_padstr8(dev->buffer + 16, 40, device_identify); /* Product */ idx += 40; ide_padstr8(dev->buffer + idx, 20, "53R141"); idx += 20; break; default: - zip_log(dev->log, "INQUIRY: Invalid page: %02X\n", cdb[2]); - zip_invalid_field(dev, cdb[2]); - zip_buf_free(dev); + rdisk_log(dev->log, "INQUIRY: Invalid page: %02X\n", cdb[2]); + rdisk_invalid_field(dev, cdb[2]); + rdisk_buf_free(dev); return; } } else { @@ -1712,20 +1733,20 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) dev->buffer[0] = 0x00; /* Hard disk */ dev->buffer[1] = 0x80; /* Removable */ /* SCSI-2 compliant */ - dev->buffer[2] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; - dev->buffer[3] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x21; + dev->buffer[2] = (dev->drv->bus_type == RDISK_BUS_SCSI) ? 0x02 : 0x00; + dev->buffer[3] = (dev->drv->bus_type == RDISK_BUS_SCSI) ? 0x02 : 0x21; #if 0 dev->buffer[4] = 31; #endif dev->buffer[4] = 0; - if (dev->drv->bus_type == ZIP_BUS_SCSI) { + if (dev->drv->bus_type == RDISK_BUS_SCSI) { dev->buffer[6] = 1; /* 16-bit transfers supported */ dev->buffer[7] = 0x20; /* Wide bus supported */ } dev->buffer[7] |= 0x02; ide_padstr8(dev->buffer + 8, 8, "IOMEGA "); /* Vendor */ - if (dev->drv->is_250) { + if (dev->drv->type == RDISK_TYPE_ZIP_250) { /* Product */ ide_padstr8(dev->buffer + 16, 16, "ZIP 250 "); /* Revision */ @@ -1735,11 +1756,18 @@ zip_command(scsi_common_t *sc, const uint8_t *cdb) ide_padstr8(dev->buffer + 36, 8, "08/08/01"); if (max_len >= 122) ide_padstr8(dev->buffer + 96, 26, "(c) Copyright IOMEGA 2000 "); /* Copyright string */ - } else { + } else if (dev->drv->type == RDISK_TYPE_ZIP_100) { /* Product */ ide_padstr8(dev->buffer + 16, 16, "ZIP 100 "); /* Revision */ ide_padstr8(dev->buffer + 32, 4, "E.08"); + } else { + 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 */ } idx = 36; @@ -1757,19 +1785,19 @@ atapi_out: len = idx; len = MIN(len, max_len); - zip_set_buf_len(dev, BufLen, &len); + rdisk_set_buf_len(dev, BufLen, &len); - zip_data_command_finish(dev, len, len, max_len, 0); + rdisk_data_command_finish(dev, len, len, max_len, 0); break; case GPCMD_PREVENT_REMOVAL: - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_command_complete(dev); + rdisk_set_phase(dev, SCSI_PHASE_STATUS); + rdisk_command_complete(dev); break; case GPCMD_SEEK_6: case GPCMD_SEEK_10: - zip_set_phase(dev, SCSI_PHASE_STATUS); + rdisk_set_phase(dev, SCSI_PHASE_STATUS); switch (cdb[0]) { case GPCMD_SEEK_6: @@ -1782,14 +1810,14 @@ atapi_out: default: break; } - zip_seek(dev, pos); - zip_command_complete(dev); + rdisk_seek(dev, pos); + rdisk_command_complete(dev); break; case GPCMD_READ_CDROM_CAPACITY: - zip_set_phase(dev, SCSI_PHASE_DATA_IN); + rdisk_set_phase(dev, SCSI_PHASE_DATA_IN); - zip_buf_alloc(dev, 8); + rdisk_buf_alloc(dev, 8); /* IMPORTANT: What's returned is the last LBA block. */ max_len = dev->drv->medium_size - 1; @@ -1801,21 +1829,21 @@ atapi_out: dev->buffer[6] = 2; /* 512 = 0x0200 */ len = 8; - zip_set_buf_len(dev, BufLen, &len); + rdisk_set_buf_len(dev, BufLen, &len); - zip_data_command_finish(dev, len, len, len, 0); + rdisk_data_command_finish(dev, len, len, len, 0); break; case GPCMD_IOMEGA_EJECT: - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_eject(dev->id); - zip_command_complete(dev); + rdisk_set_phase(dev, SCSI_PHASE_STATUS); + rdisk_eject(dev->id); + rdisk_command_complete(dev); break; case GPCMD_READ_FORMAT_CAPACITIES: len = (cdb[7] << 8) | cdb[8]; - zip_buf_alloc(dev, len); + rdisk_buf_alloc(dev, len); memset(dev->buffer, 0, len); pos = 0; @@ -1830,7 +1858,18 @@ atapi_out: dev->buffer[pos++] = 8; /* Current/Maximum capacity header */ - if (dev->drv->is_250) { + if (dev->drv->type == RDISK_TYPE_ZIP_100) { + /* ZIP 100 only supports ZIP 100 media as well, so we always return + the ZIP 100 size. */ + dev->buffer[pos++] = (ZIP_SECTORS >> 24) & 0xff; + dev->buffer[pos++] = (ZIP_SECTORS >> 16) & 0xff; + dev->buffer[pos++] = (ZIP_SECTORS >> 8) & 0xff; + dev->buffer[pos++] = ZIP_SECTORS & 0xff; + if (dev->drv->fp != NULL) + dev->buffer[pos++] = 2; + else + dev->buffer[pos++] = 3; + } else { /* 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->fp != NULL) { @@ -1846,17 +1885,6 @@ atapi_out: dev->buffer[pos++] = ZIP_250_SECTORS & 0xff; dev->buffer[pos++] = 3; /* Maximum medium capacity */ } - } else { - /* ZIP 100 only supports ZIP 100 media as well, so we always return - the ZIP 100 size. */ - dev->buffer[pos++] = (ZIP_SECTORS >> 24) & 0xff; - dev->buffer[pos++] = (ZIP_SECTORS >> 16) & 0xff; - dev->buffer[pos++] = (ZIP_SECTORS >> 8) & 0xff; - dev->buffer[pos++] = ZIP_SECTORS & 0xff; - if (dev->drv->fp != NULL) - dev->buffer[pos++] = 2; - else - dev->buffer[pos++] = 3; } dev->buffer[pos++] = 512 >> 16; @@ -1875,39 +1903,39 @@ atapi_out: dev->buffer[pos++] = 512 & 0xff; } - zip_set_buf_len(dev, BufLen, &len); + rdisk_set_buf_len(dev, BufLen, &len); - zip_data_command_finish(dev, len, len, len, 0); + rdisk_data_command_finish(dev, len, len, len, 0); break; default: - zip_illegal_opcode(dev, cdb[0]); + rdisk_illegal_opcode(dev, cdb[0]); break; } #if 0 - zip_log(dev->log, "Phase: %02X, request length: %i\n", + rdisk_log(dev->log, "Phase: %02X, request length: %i\n", dev->tf->phase, dev->tf->request_length); #endif if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR)) - zip_buf_free(dev); + rdisk_buf_free(dev); } static void -zip_command_stop(scsi_common_t *sc) +rdisk_command_stop(scsi_common_t *sc) { - zip_t *dev = (zip_t *) sc; + rdisk_t *dev = (rdisk_t *) sc; - zip_command_complete(dev); - zip_buf_free(dev); + rdisk_command_complete(dev); + rdisk_buf_free(dev); } /* The command second phase function, needed for Mode Select. */ static uint8_t -zip_phase_data_out(scsi_common_t *sc) +rdisk_phase_data_out(scsi_common_t *sc) { - zip_t *dev = (zip_t *) sc; + rdisk_t *dev = (rdisk_t *) sc; int len = 0; uint8_t error = 0; uint32_t last_to_write; @@ -1929,7 +1957,7 @@ zip_phase_data_out(scsi_common_t *sc) case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: if (dev->requested_blocks > 0) - zip_blocks(dev, &len, 1); + rdisk_blocks(dev, &len, 1); break; case GPCMD_WRITE_SAME_10: if (!dev->current_cdb[7] && !dev->current_cdb[8]) { @@ -1944,7 +1972,7 @@ zip_phase_data_out(scsi_common_t *sc) dev->buffer[2] = (i >> 8) & 0xff; dev->buffer[3] = i & 0xff; } else if (dev->current_cdb[1] & 4) { - /* CHS are 96, 1, 2048 (ZIP 100) and 239, 1, 2048 (ZIP 250) */ + /* CHS are 96, 1, 2048 (RDISK 100) and 239, 1, 2048 (RDISK 250) */ const uint32_t s = (i % 2048); const uint32_t h = ((i - s) / 2048) % 1; const uint32_t c = ((i - s) / 2048) / 1; @@ -1959,9 +1987,9 @@ zip_phase_data_out(scsi_common_t *sc) } if (fseek(dev->drv->fp, dev->drv->base + (i << 9), SEEK_SET) == -1) - log_fatal(dev->log, "zip_phase_data_out(): Error seeking\n"); + log_fatal(dev->log, "rdisk_phase_data_out(): Error seeking\n"); if (fwrite(dev->buffer, 1, 512, dev->drv->fp) != 512) - log_fatal(dev->log, "zip_phase_data_out(): Error writing data\n"); + log_fatal(dev->log, "rdisk_phase_data_out(): Error writing data\n"); } fflush(dev->drv->fp); @@ -1978,7 +2006,7 @@ zip_phase_data_out(scsi_common_t *sc) param_list_len = dev->current_cdb[4]; } - if (dev->drv->bus_type == ZIP_BUS_SCSI) { + if (dev->drv->bus_type == RDISK_BUS_SCSI) { if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { block_desc_len = dev->buffer[2]; block_desc_len <<= 8; @@ -1995,7 +2023,7 @@ zip_phase_data_out(scsi_common_t *sc) while (1) { if (pos >= param_list_len) { - zip_log(dev->log, "Buffer has only block descriptor\n"); + rdisk_log(dev->log, "Buffer has only block descriptor\n"); break; } @@ -2015,26 +2043,26 @@ zip_phase_data_out(scsi_common_t *sc) dev->ms_pages_saved.pages[page][i + 2] = val; else { error |= 1; - zip_invalid_field_pl(dev, val); + rdisk_invalid_field_pl(dev, val); } } } pos += page_len; - if (dev->drv->bus_type == ZIP_BUS_SCSI) + if (dev->drv->bus_type == RDISK_BUS_SCSI) val = zip_mode_sense_pages_default_scsi.pages[page][0] & 0x80; else val = zip_mode_sense_pages_default.pages[page][0] & 0x80; if (dev->do_page_save && val) - zip_mode_sense_save(dev); + rdisk_mode_sense_save(dev); if (pos >= dev->total_length) break; } if (error) { - zip_buf_free(dev); + rdisk_buf_free(dev); return 0; } break; @@ -2043,20 +2071,20 @@ zip_phase_data_out(scsi_common_t *sc) break; } - zip_command_stop((scsi_common_t *) dev); + rdisk_command_stop((scsi_common_t *) dev); return 1; } /* Peform a master init on the entire module. */ void -zip_global_init(void) +rdisk_global_init(void) { /* Clear the global data. */ - memset(zip_drives, 0x00, sizeof(zip_drives)); + memset(rdisk_drives, 0x00, sizeof(rdisk_drives)); } static int -zip_get_max(UNUSED(const ide_t *ide), const int ide_has_dma, const int type) +rdisk_get_max(UNUSED(const ide_t *ide), const int ide_has_dma, const int type) { int ret; @@ -2080,7 +2108,7 @@ zip_get_max(UNUSED(const ide_t *ide), const int ide_has_dma, const int type) } static int -zip_get_timings(UNUSED(const ide_t *ide), const int ide_has_dma, const int type) +rdisk_get_timings(UNUSED(const ide_t *ide), const int ide_has_dma, const int type) { int ret; @@ -2103,14 +2131,14 @@ zip_get_timings(UNUSED(const ide_t *ide), const int ide_has_dma, const int type) } static void -zip_100_identify(const ide_t *ide) +rdisk_zip_100_identify(const ide_t *ide) { ide_padstr((char *) (ide->buffer + 23), "E.08", 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */ } static void -zip_250_identify(const ide_t *ide, const int ide_has_dma) +rdisk_zip_250_identify(const ide_t *ide, const int ide_has_dma) { /* Firmware */ ide_padstr((char *) (ide->buffer + 23), "42.S", 8); @@ -2125,14 +2153,31 @@ zip_250_identify(const ide_t *ide, const int ide_has_dma) } static void -zip_identify(const ide_t *ide, const int ide_has_dma) +rdisk_generic_identify(const ide_t *ide, const int ide_has_dma, const rdisk_t *rdisk) { - const zip_t *zip = (zip_t *) ide->sc; + char model[40]; + + memset(model, 0, 40); + snprintf(model, 40, "%s %s%02i", EMU_NAME, "86B_RD", rdisk->id); + ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), model, 40); /* Model */ + + if (ide_has_dma) { + ide->buffer[80] = 0x70; /* Supported ATA versions : ATA/ATAPI-4 ATA/ATAPI-6 */ + /* Maximum ATA revision supported : ATA/ATAPI-6 T13 1410D revision 3a */ + ide->buffer[81] = 0x19; + } +} + +static void +rdisk_identify(const ide_t *ide, const int ide_has_dma) +{ + const rdisk_t *rdisk = (rdisk_t *) ide->sc; /* ATAPI device, direct-access device, removable media, interrupt DRQ: - Using (2 << 5) below makes the ASUS P/I-P54TP4XE misdentify the ZIP drive + Using (2 << 5) below makes the ASUS P/I-P54TP4XE misdentify the RDISK drive as a LS-120. */ ide->buffer[0] = 0x8000 | (0 << 8) | 0x80 | (1 << 5); @@ -2141,50 +2186,52 @@ zip_identify(const ide_t *ide, const int ide_has_dma) /* Interpret zero byte count limit as maximum length */ ide->buffer[126] = 0xfffe; - if (zip_drives[zip->id].is_250) - zip_250_identify(ide, ide_has_dma); + if (rdisk_drives[rdisk->id].type == RDISK_TYPE_ZIP_250) + rdisk_zip_250_identify(ide, ide_has_dma); + else if (rdisk_drives[rdisk->id].type == RDISK_TYPE_ZIP_100) + rdisk_zip_100_identify(ide); else - zip_100_identify(ide); + rdisk_generic_identify(ide, ide_has_dma, rdisk); } static void -zip_drive_reset(const int c) +rdisk_drive_reset(const int c) { - const uint8_t scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f; - const uint8_t scsi_id = zip_drives[c].scsi_device_id & 0x0f; + const uint8_t scsi_bus = (rdisk_drives[c].scsi_device_id >> 4) & 0x0f; + const uint8_t scsi_id = rdisk_drives[c].scsi_device_id & 0x0f; - if (zip_drives[c].priv == NULL) { - zip_drives[c].priv = (zip_t *) calloc(1, sizeof(zip_t)); - zip_t *dev = (zip_t *) zip_drives[c].priv; + if (rdisk_drives[c].priv == NULL) { + rdisk_drives[c].priv = (rdisk_t *) calloc(1, sizeof(rdisk_t)); + rdisk_t *dev = (rdisk_t *) rdisk_drives[c].priv; char n[1024] = { 0 }; - sprintf(n, "ZIP %i", c + 1); + sprintf(n, "Removable Disk %i", c + 1); dev->log = log_open(n); } - zip_t *dev = (zip_t *) zip_drives[c].priv; + rdisk_t *dev = (rdisk_t *) rdisk_drives[c].priv; dev->id = c; dev->cur_lun = SCSI_LUN_USE_CDB; - if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { + if (rdisk_drives[c].bus_type == RDISK_BUS_SCSI) { if (dev->tf == NULL) dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t)); - /* SCSI ZIP, attach to the SCSI bus. */ + /* SCSI RDISK, attach to the SCSI bus. */ scsi_device_t *sd = &scsi_devices[scsi_bus][scsi_id]; sd->sc = (scsi_common_t *) dev; - sd->command = zip_command; - sd->request_sense = zip_request_sense_for_scsi; - sd->reset = zip_reset; - sd->phase_data_out = zip_phase_data_out; - sd->command_stop = zip_command_stop; + sd->command = rdisk_command; + sd->request_sense = rdisk_request_sense_for_scsi; + sd->reset = rdisk_reset; + sd->phase_data_out = rdisk_phase_data_out; + sd->command_stop = rdisk_command_stop; sd->type = SCSI_REMOVABLE_DISK; - } else if (zip_drives[c].bus_type == ZIP_BUS_ATAPI) { + } else if (rdisk_drives[c].bus_type == RDISK_BUS_ATAPI) { /* ATAPI CD-ROM, attach to the IDE bus. */ - ide_t *id = ide_get_drive(zip_drives[c].ide_channel); + ide_t *id = ide_get_drive(rdisk_drives[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. */ @@ -2192,15 +2239,15 @@ zip_drive_reset(const int c) 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; + id->get_max = rdisk_get_max; + id->get_timings = rdisk_get_timings; + id->identify = rdisk_identify; id->stop = NULL; - id->packet_command = zip_command; - id->device_reset = zip_reset; - id->phase_data_out = zip_phase_data_out; - id->command_stop = zip_command_stop; - id->bus_master_error = zip_bus_master_error; + id->packet_command = rdisk_command; + id->device_reset = rdisk_reset; + id->phase_data_out = rdisk_phase_data_out; + id->command_stop = rdisk_command_stop; + id->bus_master_error = rdisk_bus_master_error; id->interrupt_drq = 1; ide_atapi_attach(id); @@ -2209,85 +2256,85 @@ zip_drive_reset(const int c) } void -zip_hard_reset(void) +rdisk_hard_reset(void) { - for (uint8_t c = 0; c < ZIP_NUM; c++) { - if ((zip_drives[c].bus_type == ZIP_BUS_ATAPI) || (zip_drives[c].bus_type == ZIP_BUS_SCSI)) { + for (uint8_t c = 0; c < RDISK_NUM; c++) { + if ((rdisk_drives[c].bus_type == RDISK_BUS_ATAPI) || (rdisk_drives[c].bus_type == RDISK_BUS_SCSI)) { - if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { - const uint8_t scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f; - const uint8_t scsi_id = zip_drives[c].scsi_device_id & 0x0f; + if (rdisk_drives[c].bus_type == RDISK_BUS_SCSI) { + const uint8_t scsi_bus = (rdisk_drives[c].scsi_device_id >> 4) & 0x0f; + const uint8_t scsi_id = rdisk_drives[c].scsi_device_id & 0x0f; - /* Make sure to ignore any SCSI ZIP drive that has an out of range SCSI bus. */ + /* Make sure to ignore any SCSI RDISK drive that has an out of range SCSI bus. */ if (scsi_bus >= SCSI_BUS_MAX) continue; - /* Make sure to ignore any SCSI ZIP drive that has an out of range ID. */ + /* Make sure to ignore any SCSI RDISK drive that has an out of range ID. */ if (scsi_id >= SCSI_ID_MAX) continue; } - /* Make sure to ignore any ATAPI ZIP drive that has an out of range IDE channel. */ - if ((zip_drives[c].bus_type == ZIP_BUS_ATAPI) && (zip_drives[c].ide_channel > 7)) + /* Make sure to ignore any ATAPI RDISK drive that has an out of range IDE channel. */ + if ((rdisk_drives[c].bus_type == RDISK_BUS_ATAPI) && (rdisk_drives[c].ide_channel > 7)) continue; - zip_drive_reset(c); + rdisk_drive_reset(c); - zip_t *dev = (zip_t *) zip_drives[c].priv; + rdisk_t *dev = (rdisk_t *) rdisk_drives[c].priv; - zip_log(dev->log, "ZIP hard_reset drive=%d\n", c); + rdisk_log(dev->log, "Removable Disk hard_reset drive=%d\n", c); if (dev->tf == NULL) continue; dev->id = c; - dev->drv = &zip_drives[c]; + dev->drv = &rdisk_drives[c]; - zip_init(dev); + rdisk_init(dev); - if (strlen(zip_drives[c].image_path)) - zip_load(dev, zip_drives[c].image_path, 0); + if (strlen(rdisk_drives[c].image_path)) + rdisk_load(dev, rdisk_drives[c].image_path, 0); - zip_mode_sense_load(dev); + rdisk_mode_sense_load(dev); - if (zip_drives[c].bus_type == ZIP_BUS_SCSI) - zip_log(dev->log, "SCSI ZIP drive %i attached to SCSI ID %i\n", - c, zip_drives[c].scsi_device_id); - else if (zip_drives[c].bus_type == ZIP_BUS_ATAPI) - zip_log(dev->log, "ATAPI ZIP drive %i attached to IDE channel %i\n", - c, zip_drives[c].ide_channel); + if (rdisk_drives[c].bus_type == RDISK_BUS_SCSI) + rdisk_log(dev->log, "SCSI RDISK drive %i attached to SCSI ID %i\n", + c, rdisk_drives[c].scsi_device_id); + else if (rdisk_drives[c].bus_type == RDISK_BUS_ATAPI) + rdisk_log(dev->log, "ATAPI RDISK drive %i attached to IDE channel %i\n", + c, rdisk_drives[c].ide_channel); } } } void -zip_close(void) +rdisk_close(void) { - for (uint8_t c = 0; c < ZIP_NUM; c++) { - if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { - const uint8_t scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f; - const uint8_t scsi_id = zip_drives[c].scsi_device_id & 0x0f; + for (uint8_t c = 0; c < RDISK_NUM; c++) { + if (rdisk_drives[c].bus_type == RDISK_BUS_SCSI) { + const uint8_t scsi_bus = (rdisk_drives[c].scsi_device_id >> 4) & 0x0f; + const uint8_t scsi_id = rdisk_drives[c].scsi_device_id & 0x0f; memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t)); } - zip_t *dev = (zip_t *) zip_drives[c].priv; + rdisk_t *dev = (rdisk_t *) rdisk_drives[c].priv; if (dev) { - zip_disk_unload(dev); + rdisk_disk_unload(dev); if (dev->tf) free(dev->tf); if (dev->log != NULL) { - zip_log(dev->log, "Log closed\n"); + rdisk_log(dev->log, "Log closed\n"); log_close(dev->log); dev->log = NULL; } free(dev); - zip_drives[c].priv = NULL; + rdisk_drives[c].priv = NULL; } } } diff --git a/src/dma.c b/src/dma.c index 4edeb39f8..2265947b9 100644 --- a/src/dma.c +++ b/src/dma.c @@ -856,7 +856,7 @@ dma16_read(uint16_t addr, UNUSED(void *priv)) break; } - dma_log("dma16_read(%08X) = %02X\n", port, ret); + dma_log("dma16_read(%08X) = %02X\n", addr, ret); return ret; } diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index c32b1f442..28e3b150f 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -187,10 +187,18 @@ fdc_ctrl_reset(void *priv) fdc->stat = 0x80; fdc->pnum = fdc->ptot = 0; fdc->st0 = 0; - fdc->lock = 0; fdc->head = 0; fdc->step = 0; fdc->power_down = 0; + + if (!fdc->lock && !fdc->fifointest) { + fdc->fifo = 0; + fdc->tfifo = 1; + + fifo_reset(fdc->fifo_p); + fifo_set_len(fdc->fifo_p, fdc->tfifo + 1); + fifo_set_trigger_len(fdc->fifo_p, fdc->tfifo + 1); + } } sector_id_t @@ -278,6 +286,15 @@ fdc_is_mfm(fdc_t *fdc) return fdc->mfm ? 1 : 0; } +int +fdc_is_dma(fdc_t *fdc) +{ + if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) + return 0; + else + return 1; +} + void fdc_request_next_sector_id(fdc_t *fdc) { @@ -318,14 +335,17 @@ fdc_int(fdc_t *fdc, int set_fintr) { int ienable = 0; - if (!(fdc->flags & FDC_FLAG_PCJR)) + if (fdc->flags & FDC_FLAG_PS2_MCA) + ienable = 1; + else if (!(fdc->flags & FDC_FLAG_PCJR)) ienable = !!(fdc->dor & 8); - if (ienable) + if (ienable) { picint(1 << fdc->irq); - if (set_fintr) - fdc->fintr = 1; + if (set_fintr) + fdc->fintr = 1; + } fdc_log("fdc_int(%i): fdc->fintr = %i\n", set_fintr, fdc->fintr); } @@ -368,6 +388,15 @@ fdc_set_power_down(fdc_t *fdc, uint8_t power_down) fdc->power_down = power_down; } +void +fdc_toggle_flag(fdc_t *fdc, int flag, int on) +{ + if (on) + fdc->flags |= flag; + else + fdc->flags &= ~flag; +} + void fdc_update_max_track(fdc_t *fdc, int max_track) { @@ -395,6 +424,58 @@ fdc_update_rwc(fdc_t *fdc, int drive, int rwc) fdc_rate(fdc, drive); } +uint8_t +fdc_get_media_id(fdc_t *fdc, int id) +{ + uint8_t ret = fdc->media_id & (1 << id); + + return ret; +} + +void +fdc_set_media_id(fdc_t *fdc, int id, int set) +{ + fdc->media_id = (fdc->media_id & ~(1 << id)) | (set << id); +} + +void +fdc_set_flags(fdc_t *fdc, int flags) +{ + fdc->flags |= flags; +} + +void +fdc_clear_flags(fdc_t *fdc, int flags) +{ + fdc->flags &= ~flags; +} + +void +fdc_set_fdd_changed(int drive, int changed) +{ + if (changed) + fdd_changed[drive] = 1; +} + +uint8_t +fdc_get_fdd_changed(int drive) +{ + uint8_t ret = !!fdd_changed[drive]; + + return ret; +} + +uint8_t +fdc_get_shadow(fdc_t *fdc) +{ + uint8_t ret = (fdc->rate & 0x03) | + ((fdc->pretrk & 0x07) << 2) | + (fdc->power_down ? 0x40 : 0x00) | + ((fdc_read(0x03f2, fdc) & 0x04) ? 0x80 : 0x00); + + return ret; +} + int fdc_get_boot_drive(fdc_t *fdc) { @@ -446,9 +527,11 @@ fdc_update_drv2en(fdc_t *fdc, int drv2en) void fdc_update_rate(fdc_t *fdc, int drive) { - if (((fdc->rwc[drive] == 1) || (fdc->rwc[drive] == 2)) && fdc->enh_mode) + if (((fdc->rwc[drive] == 1) || (fdc->rwc[drive] == 2)) && + fdc->enh_mode && !(fdc->flags & FDC_FLAG_SMC661)) fdc->bit_rate = 500; - else if ((fdc->rwc[drive] == 3) && fdc->enh_mode) + else if ((fdc->rwc[drive] == 3) && fdc->enh_mode && + !(fdc->flags & FDC_FLAG_SMC661)) fdc->bit_rate = 250; else switch (fdc->rate) { default: @@ -512,7 +595,7 @@ fdc_get_bitcell_period(fdc_t *fdc) static int fdc_get_densel(fdc_t *fdc, int drive) { - if (fdc->enh_mode) { + if (fdc->enh_mode && !(fdc->flags & FDC_FLAG_SMC661)) { switch (fdc->rwc[drive]) { case 1: case 3: @@ -720,9 +803,17 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->st0 &= ~0x07; fdc->st0 |= (fdd_get_head(0) ? 4 : 0); } else { - if (!(val & 8) && (fdc->dor & 8)) { - fdc->tc = 1; - fdc_int(fdc, 1); + /* + Writing this bit to logic "1" will enable the DRQ, + nDACK, TC and FINTR outputs. This bit being a + logic "0" will disable the nDACK and TC inputs, and + hold the DRQ and FINTR outputs in a high + impedance state. + */ + if (!(val & 8) && (fdc->dor & 8) && !(fdc->flags & FDC_FLAG_PS2_MCA)) { + fdc->tc = 1; + fdc->fintr = 0; + picintc(1 << fdc->irq); } if (!(val & 4)) { fdd_stop(real_drive(fdc, val & 3)); @@ -747,8 +838,13 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) return; case 3: /* TDR */ if (fdc->enh_mode) { - drive = real_drive(fdc, fdc->dor & 3); - fdc_update_rwc(fdc, drive, (val & 0x30) >> 4); + if (fdc->flags & FDC_FLAG_SMC661) { + fdc_set_swap(fdc, !!(val & 0x20)); + fdc_update_densel_force(fdc, (val & 0x18) >> 3); + } else { + drive = real_drive(fdc, fdc->dor & 3); + fdc_update_rwc(fdc, drive, (val & 0x30) >> 4); + } } /* Bit 2: FIFO test mode (PS/55 5550-S,T only. Undocumented) The Power-on Self Test of PS/55 writes and verifies 8 bytes of FIFO buffer through I/O 3F5h. @@ -761,6 +857,9 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->tfifo = 1; fdc->fifointest = 0; } + fifo_reset(fdc->fifo_p); + fifo_set_len(fdc->fifo_p, fdc->tfifo + 1); + fifo_set_trigger_len(fdc->fifo_p, fdc->tfifo + 1); } return; case 4: /* DSR */ @@ -1368,8 +1467,10 @@ fdc_read(uint16_t addr, void *priv) /* PS/55 POST throws an error and halt if ret = 1 or 2, somehow. */ } else if (!fdc->enh_mode) ret = 0x20; + else if (fdc->flags & FDC_FLAG_SMC661) + ret = (fdc->densel_force << 3) | ((!!fdc->swap) << 5) | (fdc->media_id << 6); else - ret = fdc->rwc[drive] << 4; + ret = (fdc->rwc[drive] << 4) | (fdc->media_id << 6); break; case 4: /*Status*/ ret = fdc->stat; @@ -1452,7 +1553,7 @@ fdc_read(uint16_t addr, void *priv) fdc->step = 0; break; default: - ret = 0xFF; + ret = 0xff; } fdc_log("[%04X:%08X] Read FDC %04X %02X [%i:%02X]\n", CS, cpu_state.pc, addr, ret, drive, fdc->dor & (0x10 << drive)); return ret; @@ -1612,8 +1713,8 @@ fdc_callback(void *priv) case 0x06: /* Read data */ case 0x0c: /* Read deleted data */ case 0x11: /* Scan equal */ + case 0x16: /* Verify */ case 0x19: /* Scan low or equal */ - case 0x1c: /* Verify */ case 0x1d: /* Scan high or equal */ if ((fdc->interrupt == 0x11) || (fdc->interrupt == 0x19) || (fdc->interrupt == 0x1D)) compare = 1; @@ -2203,9 +2304,13 @@ fdc_set_base(fdc_t *fdc, int base) { int super_io = (fdc->flags & FDC_FLAG_SUPERIO); + if (base == 0x0000) { + fdc->base_address = base; + return; + } + if (fdc->flags & FDC_FLAG_NSC) { - io_sethandler(base + 2, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); - io_sethandler(base + 4, 0x0002, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); + io_sethandler(base + 2, 0x0004, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); io_sethandler(base + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); } else { if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) { @@ -2234,10 +2339,12 @@ fdc_remove(fdc_t *fdc) { int super_io = (fdc->flags & FDC_FLAG_SUPERIO); + if (fdc->base_address == 0x0000) + return; + fdc_log("FDC Removed (%04X)\n", fdc->base_address); if (fdc->flags & FDC_FLAG_NSC) { - io_removehandler(fdc->base_address + 2, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); - io_removehandler(fdc->base_address + 4, 0x0002, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); + io_removehandler(fdc->base_address + 2, 0x0004, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); io_removehandler(fdc->base_address + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, fdc); } else { if ((fdc->flags & FDC_FLAG_AT) || (fdc->flags & FDC_FLAG_AMSTRAD)) { @@ -2327,6 +2434,8 @@ fdc_reset(void *priv) fdc->swwp = 0; fdc->disable_write = 0; + fdc->lock = 0; + fdc_ctrl_reset(fdc); if (!(fdc->flags & FDC_FLAG_AT)) @@ -2352,6 +2461,8 @@ fdc_reset(void *priv) } fdc->power_down = 0; + + fdc->media_id = 0; } static void @@ -2619,6 +2730,20 @@ const device_t fdc_at_actlow_device = { .config = NULL }; +const device_t fdc_at_smc_661_device = { + .name = "PC/AT Floppy Drive Controller (SM(s)C FDC37C661/2)", + .internal_name = "fdc_at_smc", + .flags = 0, + .local = FDC_FLAG_AT | FDC_FLAG_SUPERIO | FDC_FLAG_SMC661, + .init = fdc_init, + .close = fdc_close, + .reset = fdc_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t fdc_at_smc_device = { .name = "PC/AT Floppy Drive Controller (SM(s)C FDC37Cxxx)", .internal_name = "fdc_at_smc", diff --git a/src/floppy/fdc_compaticard.c b/src/floppy/fdc_compaticard.c index 741105927..cc438ddf6 100644 --- a/src/floppy/fdc_compaticard.c +++ b/src/floppy/fdc_compaticard.c @@ -214,7 +214,7 @@ static const device_config_t compaticard_ii_config[] = { }, { .name = "dma", - .description = "DMA channel", + .description = "DMA", .type = CONFIG_SELECTION, .default_string = NULL, .default_int = 2, @@ -272,7 +272,7 @@ static const device_config_t compaticard_iv_config[] = { }, { .name = "dma", - .description = "DMA channel", + .description = "DMA", .type = CONFIG_SELECTION, .default_string = NULL, .default_int = 2, diff --git a/src/floppy/fdc_magitronic.c b/src/floppy/fdc_magitronic.c index 17e556e0f..a1ee922da 100644 --- a/src/floppy/fdc_magitronic.c +++ b/src/floppy/fdc_magitronic.c @@ -110,7 +110,7 @@ static const device_config_t b215_config[] = { // clang-format off { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xca000, diff --git a/src/floppy/fdc_monster.c b/src/floppy/fdc_monster.c index b91d4db66..38ad9e2ed 100644 --- a/src/floppy/fdc_monster.c +++ b/src/floppy/fdc_monster.c @@ -162,7 +162,7 @@ static const device_config_t monster_fdc_config[] = { #endif { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xc8000, @@ -183,7 +183,7 @@ static const device_config_t monster_fdc_config[] = { #if 0 { .name = "bios_size", - .description = "BIOS Size:", + .description = "BIOS size", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 32, diff --git a/src/floppy/fdc_pii15xb.c b/src/floppy/fdc_pii15xb.c index 4e6a8367c..4c8c589e4 100644 --- a/src/floppy/fdc_pii15xb.c +++ b/src/floppy/fdc_pii15xb.c @@ -123,7 +123,7 @@ static const device_config_t pii_config[] = { // clang-format off { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xce000, diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index d3d513b9f..8bc946388 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -212,18 +212,9 @@ int fdd_get_from_internal_name(char *s) { int c = 0; - char *n; - - /* TODO: Remove this once the migration period is over. */ - if (!strcmp(s, "525_2hd_ps2")) - n = "525_2hd"; - else if (!strcmp(s, "35_2hd_ps2")) - n = "35_2hd"; - else - n = s; while (strlen(drive_types[c].internal_name)) { - if (!strcmp((char *) drive_types[c].internal_name, n)) + if (!strcmp((char *) drive_types[c].internal_name, s)) return c; c++; } @@ -467,12 +458,18 @@ fdd_load(int drive, char *fn) int c = 0; int size; const char *p; - FILE * fp; + FILE *fp; + int offs = 0; fdd_log("FDD: loading drive %d with '%s'\n", drive, fn); if (!fn) return; + if (strstr(fn, "wp://") == fn) { + offs = 5; + ui_writeprot[drive] = 1; + } + fn += offs; p = path_get_extension(fn); if (!p) return; @@ -485,13 +482,14 @@ fdd_load(int drive, char *fn) while (loaders[c].ext) { if (!strcasecmp(p, (char *) loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) { driveloaders[drive] = c; - if (floppyfns[drive] != fn) - strcpy(floppyfns[drive], fn); + if (floppyfns[drive] != (fn - offs)) + strcpy(floppyfns[drive], fn - offs); d86f_setup(drive); - loaders[c].load(drive, floppyfns[drive]); + loaders[c].load(drive, floppyfns[drive] + offs); drive_empty[drive] = 0; fdd_forced_seek(drive, 0); fdd_changed[drive] = 1; + ui_sb_update_icon_wp(SB_FLOPPY | drive, ui_writeprot[drive]); return; } c++; @@ -541,7 +539,7 @@ fdd_hole(int drive) static __inline uint64_t fdd_byteperiod(int drive) { - if (!fdd_get_turbo(drive) && drives[drive].byteperiod) + if (drives[drive].byteperiod) return drives[drive].byteperiod(drive); else return 32ULL * TIMER_USEC; diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 0a7120b16..f210bf4fd 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -758,36 +758,43 @@ d86f_get_encoding(int drive) uint64_t d86f_byteperiod(int drive) { - double dusec = (double) TIMER_USEC; - double p = 2.0; + d86f_t *dev = d86f[drive]; + uint64_t ret = 32ULL * TIMER_USEC; - switch (d86f_track_flags(drive) & 0x0f) { - case 0x02: /* 125 kbps, FM */ - p = 4.0; - break; - case 0x01: /* 150 kbps, FM */ - p = 20.0 / 6.0; - break; - case 0x0a: /* 250 kbps, MFM */ - case 0x00: /* 250 kbps, FM */ - default: - p = 2.0; - break; - case 0x09: /* 300 kbps, MFM */ - p = 10.0 / 6.0; - break; - case 0x08: /* 500 kbps, MFM */ - p = 1.0; - break; - case 0x0b: /* 1000 kbps, MFM */ - p = 0.5; - break; - case 0x0d: /* 2000 kbps, MFM */ - p = 0.25; - break; + if (!fdd_get_turbo(drive) || (dev->version != 0x0063) || (dev->state == STATE_SECTOR_NOT_FOUND)) { + double dusec = (double) TIMER_USEC; + double p = 2.0; + + switch (d86f_track_flags(drive) & 0x0f) { + case 0x02: /* 125 kbps, FM */ + p = 4.0; + break; + case 0x01: /* 150 kbps, FM */ + p = 20.0 / 6.0; + break; + case 0x0a: /* 250 kbps, MFM */ + case 0x00: /* 250 kbps, FM */ + default: + p = 2.0; + break; + case 0x09: /* 300 kbps, MFM */ + p = 10.0 / 6.0; + break; + case 0x08: /* 500 kbps, MFM */ + p = 1.0; + break; + case 0x0b: /* 1000 kbps, MFM */ + p = 0.5; + break; + case 0x0d: /* 2000 kbps, MFM */ + p = 0.25; + break; + } + + ret = (uint64_t) (p * dusec); } - return (uint64_t) (p * dusec); + return ret; } int @@ -2414,16 +2421,28 @@ d86f_turbo_poll(int drive, int side) case STATE_0C_READ_DATA: case STATE_11_SCAN_DATA: case STATE_16_VERIFY_DATA: - d86f_turbo_read(drive, side); + if (fdc_is_dma(d86f_fdc)) + for (int i = 0; i < (128 << dev->last_sector.id.n); i++) + d86f_turbo_read(drive, side); + else + d86f_turbo_read(drive, side); break; case STATE_05_WRITE_DATA: case STATE_09_WRITE_DATA: - d86f_turbo_write(drive, side); + if (fdc_is_dma(d86f_fdc)) + for (int i = 0; i < (128 << dev->last_sector.id.n); i++) + d86f_turbo_write(drive, side); + else + d86f_turbo_write(drive, side); break; case STATE_0D_FORMAT_TRACK: - d86f_turbo_format(drive, side, (side && (d86f_get_sides(drive) != 2))); + if (fdc_is_dma(d86f_fdc)) + while (dev->state == STATE_0D_FORMAT_TRACK) + d86f_turbo_format(drive, side, (side && (d86f_get_sides(drive) != 2))); + else + d86f_turbo_format(drive, side, (side && (d86f_get_sides(drive) != 2))); return; case STATE_IDLE: @@ -2451,16 +2470,17 @@ d86f_poll(int drive) dev->state = STATE_SECTOR_NOT_FOUND; } - if (fdd_get_turbo(drive) && (dev->version == 0x0063)) { - d86f_turbo_poll(drive, side); - return; - } - if ((dev->state != STATE_IDLE) && (dev->state != STATE_SECTOR_NOT_FOUND) && ((dev->state & 0xF8) != 0xE8)) { if (!d86f_can_read_address(drive)) dev->state = STATE_SECTOR_NOT_FOUND; } + /* Do normal poll if DENSEL is wrong, because Windows 95 is very strict about timings there. */ + if (fdd_get_turbo(drive) && (dev->version == 0x0063) && (dev->state != STATE_SECTOR_NOT_FOUND)) { + d86f_turbo_poll(drive, side); + return; + } + if ((dev->state != STATE_02_SPIN_TO_INDEX) && (dev->state != STATE_0D_SPIN_TO_INDEX)) d86f_get_bit(drive, side ^ 1); @@ -2565,12 +2585,6 @@ d86f_poll(int drive) d86f_advance_bit(drive, side); - if (d86f_wrong_densel(drive) && (dev->state != STATE_IDLE)) { - dev->state = STATE_IDLE; - fdc_noidam(d86f_fdc); - return; - } - if ((dev->index_count == 2) && (dev->state != STATE_IDLE)) { switch (dev->state) { case STATE_0A_FIND_ID: @@ -3265,7 +3279,12 @@ d86f_readsector(int drive, int sector, int track, int side, int rate, int sector if (!ret) return; - if (sector == SECTOR_FIRST) + if (d86f_wrong_densel(drive)) { + dev->state = STATE_SECTOR_NOT_FOUND; + + if (fdd_get_turbo(drive)) + dev->track_pos = 0; + } else if (sector == SECTOR_FIRST) dev->state = STATE_02_SPIN_TO_INDEX; else if (sector == SECTOR_NEXT) dev->state = STATE_02_FIND_ID; @@ -3290,7 +3309,13 @@ d86f_writesector(int drive, int sector, int track, int side, int rate, int secto if (!ret) return; - dev->state = fdc_is_deleted(d86f_fdc) ? STATE_09_FIND_ID : STATE_05_FIND_ID; + if (d86f_wrong_densel(drive)) { + dev->state = STATE_SECTOR_NOT_FOUND; + + if (fdd_get_turbo(drive)) + dev->track_pos = 0; + } else + dev->state = fdc_is_deleted(d86f_fdc) ? STATE_09_FIND_ID : STATE_05_FIND_ID; } void @@ -3303,7 +3328,13 @@ d86f_comparesector(int drive, int sector, int track, int side, int rate, int sec if (!ret) return; - dev->state = STATE_11_FIND_ID; + if (d86f_wrong_densel(drive)) { + dev->state = STATE_SECTOR_NOT_FOUND; + + if (fdd_get_turbo(drive)) + dev->track_pos = 0; + } else + dev->state = STATE_11_FIND_ID; } void @@ -3324,7 +3355,13 @@ d86f_readaddress(int drive, UNUSED(int side), UNUSED(int rate)) dev->id_found = 0; dev->dma_over = 0; - dev->state = STATE_0A_FIND_ID; + if (d86f_wrong_densel(drive)) { + dev->state = STATE_SECTOR_NOT_FOUND; + + if (fdd_get_turbo(drive)) + dev->track_pos = 0; + } else + dev->state = STATE_0A_FIND_ID; } void @@ -3426,7 +3463,13 @@ d86f_common_format(int drive, int side, UNUSED(int rate), uint8_t fill, int prox dev->index_count = dev->error_condition = dev->satisfying_bytes = dev->sector_count = 0; dev->dma_over = 0; - dev->state = STATE_0D_SPIN_TO_INDEX; + if (d86f_wrong_densel(drive) && !proxy) { + dev->state = STATE_SECTOR_NOT_FOUND; + + if (fdd_get_turbo(drive)) + dev->track_pos = 0; + } else + dev->state = STATE_0D_SPIN_TO_INDEX; } void diff --git a/src/game/gameport.c b/src/game/gameport.c index 8ae1c7d25..45f34f1e1 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -15,7 +15,7 @@ * * Copyright 2016-2022 Miran Grca. * Copyright 2008-2018 Sarah Walker. - * Copyright 2021 RichardG. + * Copyright 2021 RichardG. * Copyright 2021-2025 Jasmine Iwanek. */ #include @@ -61,13 +61,13 @@ typedef struct _joystick_instance_ { uint8_t state; g_axis_t axis[4]; - const joystick_if_t *intf; - void *dat; + const joystick_t *intf; + void *dat; } joystick_instance_t; int joystick_type = JS_TYPE_NONE; -static const joystick_if_t joystick_none = { +static const joystick_t joystick_none = { .name = "None", .internal_name = "none", .init = NULL, @@ -86,15 +86,22 @@ static const joystick_if_t joystick_none = { }; static const struct { - const joystick_if_t *joystick; + const joystick_t *joystick; } joysticks[] = { { &joystick_none }, { &joystick_2axis_2button }, + { &joystick_2button_gamepad }, + { &joystick_2button_flight_yoke }, { &joystick_2axis_4button }, + { &joystick_4button_gamepad }, + { &joystick_4button_flight_yoke }, { &joystick_2axis_6button }, { &joystick_2axis_8button }, { &joystick_3axis_2button }, + { &joystick_2button_yoke_throttle }, { &joystick_3axis_4button }, + { &joystick_win95_steering_wheel }, + { &joystick_4button_yoke_throttle }, { &joystick_4axis_4button }, { &joystick_ch_flightstick_pro }, { &joystick_ch_flightstick_pro_ch_pedals }, @@ -107,24 +114,39 @@ static const struct { static joystick_instance_t *joystick_instance[GAMEPORT_MAX] = { NULL, NULL }; static uint8_t gameport_pnp_rom[] = { - 0x09, 0xf8, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* BOX0002, dummy checksum (filled in by isapnp_add_card) */ - 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ - 0x82, 0x09, 0x00, 'G', 'a', 'm', 'e', ' ', 'P', 'o', 'r', 't', /* ANSI identifier */ + /* BOX0002, serial 0, dummy checksum (filled in by isapnp_add_card) */ + 0x09, 0xf8, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + /* PnP version 1.0, vendor version 1.0 */ + 0x0a, 0x10, 0x10, + /* ANSI identifier */ + 0x82, 0x09, 0x00, 'G', 'a', 'm', 'e', ' ', 'P', 'o', 'r', 't', - 0x15, 0x09, 0xf8, 0x00, 0x02, 0x01, /* logical device BOX0002, can participate in boot */ - 0x1c, 0x41, 0xd0, 0xb0, 0x2f, /* compatible device PNPB02F */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x47, 0x01, 0x00, 0x02, 0x00, 0x02, 0x08, 0x08, /* I/O 0x200, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x30, /* start dependent functions, acceptable */ - 0x47, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x08, /* I/O 0x208, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x31, 0x02, /* start dependent functions, sub-optimal */ - 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x38, /* end dependent functions */ + /* Logical device BOX0002, can participate in boot */ + 0x15, 0x09, 0xf8, 0x00, 0x02, 0x01, + /* Compatible device PNPB02F */ + 0x1c, 0x41, 0xd0, 0xb0, 0x2f, + /* Start dependent functions, preferred */ + 0x31, 0x00, + /* I/O 0x200, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x00, 0x02, 0x00, 0x02, 0x08, 0x08, + /* Start dependent functions, acceptable */ + 0x30, + /* I/O 0x208, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x08, + /* Start dependent functions, sub-optimal */ + 0x31, 0x02, + /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, + /* 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 const isapnp_device_config_t gameport_pnp_defaults[] = { - {.activate = 1, + { + .activate = 1, .io = { { .base = 0x200 }, } @@ -237,15 +259,13 @@ gameport_write(UNUSED(uint16_t addr), UNUSED(uint8_t val), void *priv) /* Read all axes. */ joystick->state |= 0x0f; - gameport_time(joystick, 0, joystick->intf->read_axis(joystick->dat, 0)); - gameport_time(joystick, 1, joystick->intf->read_axis(joystick->dat, 1)); - gameport_time(joystick, 2, joystick->intf->read_axis(joystick->dat, 2)); - gameport_time(joystick, 3, joystick->intf->read_axis(joystick->dat, 3)); + for (uint8_t i = 0; i < 4; i++) + gameport_time(joystick, i, joystick->intf->read_axis(joystick->dat, i)); /* Notify the interface. */ joystick->intf->write(joystick->dat); - cycles -= ISA_CYCLES(8); + cycles -= ISA_CYCLES((8 << is_pcjr)); } static uint8_t @@ -261,7 +281,7 @@ gameport_read(UNUSED(uint16_t addr), void *priv) /* Merge axis state with button state. */ uint8_t ret = joystick->state | joystick->intf->read(joystick->dat); - cycles -= ISA_CYCLES(8); + cycles -= ISA_CYCLES((8 << is_pcjr)); return ret; } @@ -299,6 +319,9 @@ gameport_remap(void *priv, uint16_t address) gameport_t *dev = (gameport_t *) priv; gameport_t *other_dev; + if (dev == NULL) + return; + if (dev->addr) { /* Remove this port from the active ports list. */ if (active_gameports == dev) { @@ -374,20 +397,14 @@ gameport_init(const device_t *info) if (!joystick_instance[0] && joystick_type) { joystick_instance[0] = calloc(1, sizeof(joystick_instance_t)); - joystick_instance[0]->axis[0].joystick = joystick_instance[0]; - joystick_instance[0]->axis[1].joystick = joystick_instance[0]; - joystick_instance[0]->axis[2].joystick = joystick_instance[0]; - joystick_instance[0]->axis[3].joystick = joystick_instance[0]; + // For each analog joystick axis + for (uint8_t i = 0; i < 4; i++) { + joystick_instance[0]->axis[i].joystick = joystick_instance[0]; - joystick_instance[0]->axis[0].axis_nr = 0; - joystick_instance[0]->axis[1].axis_nr = 1; - joystick_instance[0]->axis[2].axis_nr = 2; - joystick_instance[0]->axis[3].axis_nr = 3; + joystick_instance[0]->axis[i].axis_nr = i; - timer_add(&joystick_instance[0]->axis[0].timer, timer_over, &joystick_instance[0]->axis[0], 0); - timer_add(&joystick_instance[0]->axis[1].timer, timer_over, &joystick_instance[0]->axis[1], 0); - timer_add(&joystick_instance[0]->axis[2].timer, timer_over, &joystick_instance[0]->axis[2], 0); - timer_add(&joystick_instance[0]->axis[3].timer, timer_over, &joystick_instance[0]->axis[3], 0); + timer_add(&joystick_instance[0]->axis[i].timer, timer_over, &joystick_instance[0]->axis[i], 0); + } joystick_instance[0]->intf = joysticks[joystick_type].joystick; joystick_instance[0]->dat = joystick_instance[0]->intf->init(); @@ -399,8 +416,8 @@ gameport_init(const device_t *info) dev->len = (info->local >> 16) & 0xff; gameport_remap(dev, info->local & 0xffff); - /* Register ISAPnP if this is a standard game port card. */ - if ((info->local & 0xffff) == 0x200) + /* Register ISAPnP if this is a PNP game port card. */ + if (info->local & GAMEPORT_PNPROM) isapnp_set_device_defaults(isapnp_add_card(gameport_pnp_rom, sizeof(gameport_pnp_rom), gameport_pnp_config_changed, NULL, NULL, NULL, dev), 0, gameport_pnp_defaults); return dev; @@ -473,9 +490,23 @@ gameport_close(void *priv) } const device_t gameport_device = { - .name = "Game port", + .name = "86Box PNP Game port", .internal_name = "gameport", .flags = 0, + .local = GAMEPORT_PNPROM | GAMEPORT_8ADDR | 0x0200, + .init = gameport_init, + .close = gameport_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t gameport_200_device = { + .name = "Game port (Port 200h-207h)", + .internal_name = "gameport_200", + .flags = 0, .local = GAMEPORT_8ADDR | 0x0200, .init = gameport_init, .close = gameport_close, @@ -726,7 +757,7 @@ const device_t gameport_sio_device = { const device_t gameport_sio_1io_device = { .name = "Game port (Super I/O, 1 I/O port)", - .internal_name = "gameport_sio", + .internal_name = "gameport_sio_1io", .flags = 0, .local = GAMEPORT_SIO | GAMEPORT_1ADDR, .init = gameport_init, @@ -741,6 +772,7 @@ const device_t gameport_sio_1io_device = { static const GAMEPORT gameports[] = { { &device_none }, { &device_internal }, + { &gameport_200_device }, { &gameport_device }, { &gameport_208_device }, { &gameport_pnp_device }, @@ -761,7 +793,7 @@ gameport_available(int port) /* UI */ const device_t * -gameports_getdevice(int port) +gameport_getdevice(int port) { return (gameports[port].device); } diff --git a/src/game/joystick_ch_flightstick_pro.c b/src/game/joystick_ch_flightstick_pro.c index 5b240f3f4..b3d4e0ef5 100644 --- a/src/game/joystick_ch_flightstick_pro.c +++ b/src/game/joystick_ch_flightstick_pro.c @@ -8,8 +8,6 @@ * * Implementation of the Flight Stick Pro. * - * - * * Authors: Miran Grca, * Sarah Walker, * @@ -138,7 +136,7 @@ ch_flightstick_pro_a0_over(UNUSED(void *priv)) // } -const joystick_if_t joystick_ch_flightstick_pro = { +const joystick_t joystick_ch_flightstick_pro = { .name = "CH Flightstick Pro", .internal_name = "ch_flightstick_pro", .init = ch_flightstick_pro_init, @@ -156,7 +154,7 @@ const joystick_if_t joystick_ch_flightstick_pro = { .pov_names = { "POV" } }; -const joystick_if_t joystick_ch_flightstick_pro_ch_pedals = { +const joystick_t joystick_ch_flightstick_pro_ch_pedals = { .name = "CH Flightstick Pro + CH Pedals", .internal_name = "ch_flightstick_pro_ch_pedals", .init = ch_flightstick_pro_init, diff --git a/src/game/joystick_standard.c b/src/game/joystick_standard.c index 5f200cb98..fa83826da 100644 --- a/src/game/joystick_standard.c +++ b/src/game/joystick_standard.c @@ -8,13 +8,14 @@ * * Implementation of a standard joystick. * - * - * * Authors: Miran Grca, * Sarah Walker, + * Miran Grca, + * Jasmine Iwanek, * * Copyright 2016-2018 Miran Grca. * Copyright 2008-2018 Sarah Walker. + * Copyright 2021-2025 Jasmine Iwanek. * * 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 @@ -147,6 +148,40 @@ joystick_standard_read_axis_4button(UNUSED(void *priv), int axis) } } +#if 0 +// For later use +static int +joystick_standard_read_axis_with_pov(UNUSED(void *priv), int axis) +{ + if (!JOYSTICK_PRESENT(0, 0)) + return AXIS_NOT_PRESENT; + + switch (axis) { + case 0: // X-axis + return joystick_state[0][0].axis[0]; + case 1: // Y-axis + return joystick_state[0][0].axis[1]; + case 2: // POV Hat (mapped to the 3rd logical axis, index 2) + if (joystick_state[0][0].pov[0] == -1) + return 32767; // Centered/No input (as per tm_fcs_rcs_read_axis example) + if (joystick_state[0][0].pov[0] > 315 || joystick_state[0][0].pov[0] < 45) + return -32768; // Up + if (joystick_state[0][0].pov[0] >= 45 && joystick_state[0][0].pov[0] < 135) + return -16384; // Up-Right (example value, matches tm_fcs_rcs_read_axis) + if (joystick_state[0][0].pov[0] >= 135 && joystick_state[0][0].pov[0] < 225) + return 0; // Right/Left (example, matches tm_fcs_rcs_read_axis) + if (joystick_state[0][0].pov[0] >= 225 && joystick_state[0][0].pov[0] < 315) + return 16384; // Down-Left (example value, matches tm_fcs_rcs_read_axis) + return 0; // Fallback + case 3: // This case might be used for a Z-axis if present, or can return 0 if not. + // For gamepads with only X/Y and POV, this will likely be unused or return 0. + return 0; + default: + return 0; + } +} +#endif + static int joystick_standard_read_axis_3axis(UNUSED(void *priv), int axis) { @@ -239,7 +274,7 @@ joystick_standard_a0_over(UNUSED(void *priv)) // } -const joystick_if_t joystick_2axis_2button = { +const joystick_t joystick_2axis_2button = { .name = "2-axis, 2-button joystick(s)", .internal_name = "2axis_2button", .init = joystick_standard_init, @@ -257,7 +292,43 @@ const joystick_if_t joystick_2axis_2button = { .pov_names = { NULL } }; -const joystick_if_t joystick_2axis_4button = { +const joystick_t joystick_2button_gamepad = { + .name = "2-button gamepad(s)", + .internal_name = "2button_gamepad", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 2, + .button_count = 2, + .pov_count = 0, + .max_joysticks = 2, + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_2button_flight_yoke = { + .name = "2-button flight yoke", + .internal_name = "2button_flight_yoke", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 2, + .button_count = 2, + .pov_count = 0, + .max_joysticks = 2, + .axis_names = { "Roll axis", "Pitch axis" }, + .button_names = { "Trigger", "Button 2" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_2axis_4button = { .name = "2-axis, 4-button joystick", .internal_name = "2axis_4button", .init = joystick_standard_init, @@ -275,7 +346,43 @@ const joystick_if_t joystick_2axis_4button = { .pov_names = { NULL } }; -const joystick_if_t joystick_3axis_2button = { +const joystick_t joystick_4button_gamepad = { + .name = "4-button gamepad", + .internal_name = "4button_gamepad", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_4button, + .a0_over = joystick_standard_a0_over, + .axis_count = 2, + .button_count = 4, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_4button_flight_yoke = { + .name = "4-button flight yoke", + .internal_name = "4button_flight_yoke", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_4button, + .a0_over = joystick_standard_a0_over, + .axis_count = 2, + .button_count = 4, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Roll axis", "Pitch axis" }, + .button_names = { "Trigger", "Button 2", "Button 3", "Button 4" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_3axis_2button = { .name = "3-axis, 2-button joystick", .internal_name = "3axis_2button", .init = joystick_standard_init, @@ -293,7 +400,25 @@ const joystick_if_t joystick_3axis_2button = { .pov_names = { NULL } }; -const joystick_if_t joystick_3axis_4button = { +const joystick_t joystick_2button_yoke_throttle = { + .name = "2-button flight yoke with throttle", + .internal_name = "2button_yoke_throttle", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_3axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 3, + .button_count = 2, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Roll axis", "Pitch axis", "Throttle axis" }, + .button_names = { "Trigger", "Button 2" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_3axis_4button = { .name = "3-axis, 4-button joystick", .internal_name = "3axis_4button", .init = joystick_standard_init, @@ -311,7 +436,43 @@ const joystick_if_t joystick_3axis_4button = { .pov_names = { NULL } }; -const joystick_if_t joystick_4axis_4button = { +const joystick_t joystick_4button_yoke_throttle = { + .name = "4-button flight yoke with throttle", + .internal_name = "4button_yoke_throttle", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_3axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 3, + .button_count = 4, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Roll axis", "Pitch axis", "Throttle axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_win95_steering_wheel = { + .name = "Win95 Steering Wheel (3-axis, 4-button)", + .internal_name = "win95_steering_wheel", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_3axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 3, + .button_count = 4, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Steering axis", "Accelerator axis", "Brake axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_4axis_4button = { .name = "4-axis, 4-button joystick", .internal_name = "4axis_4button", .init = joystick_standard_init, @@ -329,7 +490,7 @@ const joystick_if_t joystick_4axis_4button = { .pov_names = { NULL } }; -const joystick_if_t joystick_2axis_6button = { +const joystick_t joystick_2axis_6button = { .name = "2-axis, 6-button joystick", .internal_name = "2axis_6button", .init = joystick_standard_init, @@ -347,7 +508,7 @@ const joystick_if_t joystick_2axis_6button = { .pov_names = { NULL } }; -const joystick_if_t joystick_2axis_8button = { +const joystick_t joystick_2axis_8button = { .name = "2-axis, 8-button joystick", .internal_name = "2axis_8button", .init = joystick_standard_init, diff --git a/src/game/joystick_sw_pad.c b/src/game/joystick_sw_pad.c index bfdc0e025..7c1d4910b 100644 --- a/src/game/joystick_sw_pad.c +++ b/src/game/joystick_sw_pad.c @@ -29,8 +29,6 @@ * - Some DOS stuff will write to 0x201 while a packet is * being transferred. This seems to be ignored. * - * - * * Authors: Miran Grca, * Sarah Walker, * @@ -244,7 +242,7 @@ sw_a0_over(void *priv) timer_set_delay_u64(&sw->trigger_timer, TIMER_USEC * 10000); } -const joystick_if_t joystick_sw_pad = { +const joystick_t joystick_sw_pad = { .name = "Microsoft SideWinder Pad", .internal_name = "sidewinder_pad", .init = sw_init, diff --git a/src/game/joystick_tm_fcs.c b/src/game/joystick_tm_fcs.c index 52d77d8fb..6c1176a42 100644 --- a/src/game/joystick_tm_fcs.c +++ b/src/game/joystick_tm_fcs.c @@ -8,8 +8,6 @@ * * Implementation of Thrust Master Flight Control System. * - * - * * Authors: Miran Grca, * Sarah Walker, * @@ -148,7 +146,7 @@ tm_fcs_a0_over(UNUSED(void *priv)) // } -const joystick_if_t joystick_tm_fcs = { +const joystick_t joystick_tm_fcs = { .name = "Thrustmaster Flight Control System", .internal_name = "thrustmaster_fcs", .init = tm_fcs_init, @@ -166,7 +164,7 @@ const joystick_if_t joystick_tm_fcs = { .pov_names = { "POV" } }; -const joystick_if_t joystick_tm_fcs_rcs = { +const joystick_t joystick_tm_fcs_rcs = { .name = "Thrustmaster FCS + Rudder Control System", .internal_name = "thrustmaster_fcs_rcs", .init = tm_fcs_init, diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index c4ebb80e0..9c96d90c8 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -25,6 +25,11 @@ #include #endif +#if defined(__HAIKU__) +/* Doesn't compile on Haiku without this include */ +#include +#endif + /* Configuration values. */ #define GFXCARD_MAX 2 #define SERIAL_MAX 8 @@ -121,7 +126,6 @@ extern int dpi_scale; /* (C) DPI scaling of the emulated s 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 */ @@ -135,6 +139,7 @@ extern int postcard_enabled; /* (C) enable POST card */ extern int unittester_enabled; /* (C) enable unit tester device */ extern int gameport_type[]; /* (C) enable gameports */ extern int isamem_type[]; /* (C) enable ISA mem cards */ +extern int isarom_type[]; /* (C) enable ISA ROM 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 */ @@ -149,13 +154,14 @@ 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 lba_enhancer_enabled; /* (C) enable Vision Systems LBA Enhancer */ 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 force_10ms; /* (C) force 10ms CPU frame interval */ extern int other_ide_present; /* IDE controllers from non-IDE cards are present */ extern int other_scsi_present; /* SCSI controllers from non-SCSI cards are present */ +extern int is_pcjr; /* The current machine is PCjr. */ extern int hard_reset_pending; extern int fixed_size_x; @@ -178,6 +184,8 @@ extern char cfg_path[1024]; /* full path of config file */ extern char global_cfg_path[1024]; /* full path of global config file */ extern int open_dir_usr_path; /* default file open dialog directory of usr_path */ extern char uuid[MAX_UUID_LEN]; /* UUID or machine identifier */ +extern char vmm_path[1024]; /* VM Manager path to scan (temporary) */ +extern int vmm_enabled; #ifndef USE_NEW_DYNAREC extern FILE *stdlog; /* file to log output to */ #endif diff --git a/src/include/86box/cassette.h b/src/include/86box/cassette.h index 168d82099..dc85bfc26 100644 --- a/src/include/86box/cassette.h +++ b/src/include/86box/cassette.h @@ -75,7 +75,7 @@ void pc_cas_del(pc_cassette_t *cas); * @short Set the cassette file * @return True on error, false otherwise *****************************************************************************/ -int pc_cas_set_fname(pc_cassette_t *cas, const char *fname); +int pc_cas_set_fname(pc_cassette_t *cas, char *fname); /*!*************************************************************************** * @short Get the cassette mode diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index 5ff4170a2..f98b60983 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -29,8 +29,9 @@ #define CD_STATUS_STOPPED 6 #define CD_STATUS_PLAYING_COMPLETED 7 #define CD_STATUS_HOLD 8 +#define CD_STATUS_DVD_REJECTED 16 #define CD_STATUS_HAS_AUDIO 0xc -#define CD_STATUS_MASK 0xf +#define CD_STATUS_MASK 0x1f /* Medium changed flag. */ #define CD_STATUS_TRANSITION 0x40 @@ -69,6 +70,8 @@ #define CD_FPS 75 +#define _LUT_SIZE 0x100 + #define FRAMES_TO_MSF(f, M, S, F) \ { \ uint64_t value = f; \ @@ -91,13 +94,19 @@ extern "C" { #endif enum { - CDROM_BUS_DISABLED = 0, - CDROM_BUS_ATAPI = 5, - CDROM_BUS_SCSI = 6, - CDROM_BUS_MITSUMI = 7, - CDROM_BUS_USB = 8 + CDROM_BUS_DISABLED = 0, + CDROM_BUS_PHILIPS = 1, + CDROM_BUS_SONY = 2, + CDROM_BUS_HITACHI = 3, + CDROM_BUS_MKE = 4, + CDROM_BUS_MITSUMI = 5, + CDROM_BUS_LPT = 6, + CDROM_BUS_ATAPI = 8, + CDROM_BUS_SCSI = 9, + CDROM_BUS_USB = 10 }; +#define BUS_TYPE_MKE CDROM_BUS_MKE #define BUS_TYPE_IDE CDROM_BUS_ATAPI #define BUS_TYPE_SCSI CDROM_BUS_SCSI #define BUS_TYPE_BOTH -2 @@ -106,117 +115,122 @@ enum { #define CDV EMU_VERSION_EX static const struct cdrom_drive_types_s { - const char * vendor; - const char * model; - const char * revision; - const char * internal_name; + const char *vendor; + const char *model; + const char *revision; + const char *internal_name; const int bus_type; /* SCSI standard for SCSI (or both) devices, early for IDE. */ const int scsi_std; const int speed; const int inquiry_len; const int caddy; + const int is_dvd; const int transfer_max[4]; } cdrom_drive_types[] = { - { EMU_NAME, "86B_CD", CDV, "86cd", BUS_TYPE_BOTH, 2, -1, 36, 0, { 4, 2, 2, 5 } }, + { EMU_NAME, "86B_CD", CDV, "86cd", BUS_TYPE_BOTH, 2, -1, 36, 0, 0, { 4, 2, 2, 5 } }, /* SCSI-1 / early ATAPI generic - second on purpose so the later variant is the default. */ - { EMU_NAME, "86B_CD", "1.00", "86cd100", BUS_TYPE_BOTH, 1, -1, 36, 1, { 0, -1, -1, -1 } }, + { EMU_NAME, "86B_CD", "1.00", "86cd100", BUS_TYPE_BOTH, 1, -1, 36, 1, 0, { 0, -1, -1, -1 } }, /* No difference from 86BOX CD-ROM, other than name - but enough people have requested such a name to warrant it. */ - { EMU_NAME, "86B_DVD", "4.30", "86dvd", BUS_TYPE_BOTH, 2, -1, 36, 0, { 4, 2, 2, 5 } }, - { "ASUS", "CD-S500/A", "1.41", "asus_500", BUS_TYPE_IDE, 0, 50, 36, 0, { 4, 2, 2, 2 } }, - { "ASUS", "CD-S520/A4", "1.32", "asus_520", BUS_TYPE_IDE, 0, 52, 36, 0, { 4, 2, 2, 2 } }, - { "AZT", "CDA46802I", "1.15", "azt_cda", BUS_TYPE_IDE, 0, 4, 36, 0, { 3, 0, 0, 0 } }, - { "BTC", "CD-ROM BCD36XH", "U1.0", "btc_36xh", BUS_TYPE_IDE, 0, 36, 36, 0, { 4, 2, 2, -1 } }, - { "GOLDSTAR", "CRD-8160B", "3.14", "goldstar", BUS_TYPE_IDE, 0, 16, 36, 0, { 4, 2, 2, -1 } }, + { EMU_NAME, "86B_DVD", "5.00", "86dvd", BUS_TYPE_BOTH, 2, -1, 36, 0, 1, { 4, 2, 2, 5 } }, + { "ASUS", "CD-S500/A", "1.41", "asus_500", BUS_TYPE_IDE, 0, 50, 36, 0, 0, { 4, 2, 2, 2 } }, + { "ASUS", "CD-S520/A4", "1.32", "asus_520", BUS_TYPE_IDE, 0, 52, 36, 0, 0, { 4, 2, 2, 2 } }, + { "AZT", "CDA46802I", "1.15", "azt_cda", BUS_TYPE_IDE, 0, 4, 36, 0, 0, { 3, 0, 0, 0 } }, + { "BTC", "CD-ROM BCD36XH", "U1.0", "btc_36xh", BUS_TYPE_IDE, 0, 36, 36, 0, 0, { 4, 2, 2, -1 } }, + { "GOLDSTAR", "CRD-8160B", "3.14", "goldstar", BUS_TYPE_IDE, 0, 16, 36, 0, 0, { 4, 2, 2, -1 } }, /* TODO: Find an IDENTIFY and/or INQUIRY dump. */ - { "GOLDSTAR", "GCD-R560B", "1.00", "goldstar", BUS_TYPE_IDE, 0, 6, 36, 0, { 4, 2, 2, -1 } }, - { "HITACHI", "CDR-8130", "0020", "hitachi_r8130", BUS_TYPE_IDE, 0, 16, 36, 0, { 4, 2, 2, -1 } }, - { "HITACHI", "GD-7500", "A1 ", "hitachi_7500", BUS_TYPE_IDE, 0, 40, 36, 0, { 4, 2, 2, 2 } }, /* DVD. */ - { "HL-DT-ST", "CD-ROM GCR-8526B", "1.01", "hldtst_8526b", BUS_TYPE_IDE, 0, 52, 36, 0, { 4, 2, 2, 2 } }, - { "HL-DT-ST", "DVDRAM GSA-4160", "A302", "hldtst_4160", BUS_TYPE_IDE, 0, 40, 36, 0, { 4, 2, 2, 2 } }, - { "KENWOOD", "CD-ROM UCR-421", "208E", "kenwood_421", BUS_TYPE_IDE, 0, 72, 36, 0, { 4, 2, 2, 4 } }, + { "GOLDSTAR", "GCD-R560B", "1.00", "goldstar", BUS_TYPE_IDE, 0, 6, 36, 0, 0, { 4, 2, 2, -1 } }, + { "HITACHI", "CDR-8130", "0020", "hitachi_r8130", BUS_TYPE_IDE, 0, 16, 36, 0, 0, { 4, 2, 2, -1 } }, + { "HITACHI", "GD-7500", "A1 ", "hitachi_7500", BUS_TYPE_IDE, 0, 40, 36, 0, 0, { 4, 2, 2, 2 } }, /* DVD. */ + { "HL-DT-ST", "CD-ROM GCR-8526B", "1.01", "hldtst_8526b", BUS_TYPE_IDE, 0, 52, 36, 0, 0, { 4, 2, 2, 2 } }, + { "HL-DT-ST", "DVDRAM GSA-4160", "A302", "hldtst_4160", BUS_TYPE_IDE, 0, 40, 36, 0, 0, { 4, 2, 2, 2 } }, + { "KENWOOD", "CD-ROM UCR-421", "208E", "kenwood_421", BUS_TYPE_IDE, 0, 72, 36, 0, 0, { 4, 2, 2, 4 } }, /* This is a laptop/notebook drive, as is also evident from the name: CRN = Notebook, CRD = Desktop. */ - { "LG", "CD-ROM CRN-8245B", "1.30", "lg_8245b", BUS_TYPE_IDE, 0, 24, 36, 0, { 4, 2, 2, -1 } }, - { "LG", "CD-ROM CRD-8322B", "1.06", "lg_8322b", BUS_TYPE_IDE, 0, 32, 36, 0, { 4, 2, 2, -1 } }, + { "LG", "CD-ROM CRN-8245B", "1.30", "lg_8245b", BUS_TYPE_IDE, 0, 24, 36, 0, 0, { 4, 2, 2, -1 } }, + { "LG", "CD-ROM CRD-8322B", "1.06", "lg_8322b", BUS_TYPE_IDE, 0, 32, 36, 0, 0, { 4, 2, 2, -1 } }, /* Nothing on Google, deduced 48x from the name. */ - { "LITE-ON", "LTN48125S", "1S07", "liteon_48125s", BUS_TYPE_IDE, 0, 48, 36, 0, { 4, 2, 2, 2 } }, + { "LITE-ON", "LTN48125S", "1S07", "liteon_48125s", BUS_TYPE_IDE, 0, 48, 36, 0, 0, { 4, 2, 2, 2 } }, /* Confirmed to be 52x, was the basis for deducing the other one's speed. */ - { "LITE-ON", "LTN526D", "YSR5", "liteon_526d", BUS_TYPE_IDE, 0, 52, 36, 0, { 4, 2, 2, 2 } }, - { "MATSHITA", "CD-ROM CR-583", "1.07", "matshita_583", BUS_TYPE_IDE, 0, 8, 36, 0, { 4, 2, 2, -1 } }, - { "MATSHITA", "CD-ROM CR-585", "Z18P", "matshita_585", BUS_TYPE_IDE, 0, 24, 36, 0, { 4, 2, 2, -1 } }, - { "MATSHITA", "CD-ROM CR-587", "7S13", "matshita_587", BUS_TYPE_IDE, 0, 24, 36, 0, { 4, 2, 2, -1 } }, - { "MATSHITA", "CD-ROM CR-588", "LS15", "matshita_588", BUS_TYPE_IDE, 0, 32, 36, 0, { 4, 2, 2, -1 } }, - { "MATSHITA", "CR-571", "1.0e", "matshita_571", BUS_TYPE_IDE, 0, 2, 36, 0, { 0, -1, -1, -1 } }, - { "MATSHITA", "CR-572", "1.0j", "matshita_572", BUS_TYPE_IDE, 0, 4, 36, 0, { 0, -1, -1, -1 } }, - { "MITSUMI", "CRMC-FX4820T", "D02A", "mitsumi_4820t", BUS_TYPE_IDE, 0, 48, 36, 0, { 4, 2, 2, 2 } }, + { "LITE-ON", "LTN526D", "YSR5", "liteon_526d", BUS_TYPE_IDE, 0, 52, 36, 0, 0, { 4, 2, 2, 2 } }, + { "MATSHITA", "CD-ROM CR-583", "1.07", "matshita_583", BUS_TYPE_IDE, 0, 8, 36, 0, 0, { 4, 2, 2, -1 } }, + { "MATSHITA", "CD-ROM CR-585", "Z18P", "matshita_585", BUS_TYPE_IDE, 0, 24, 36, 0, 0, { 4, 2, 2, -1 } }, + { "MATSHITA", "CD-ROM CR-587", "7S13", "matshita_587", BUS_TYPE_IDE, 0, 24, 36, 0, 0, { 4, 2, 2, -1 } }, + { "MATSHITA", "CD-ROM CR-588", "LS15", "matshita_588", BUS_TYPE_IDE, 0, 32, 36, 0, 0, { 4, 2, 2, -1 } }, + { "MATSHITA", "CR-571", "1.0e", "matshita_571", BUS_TYPE_IDE, 0, 2, 36, 0, 0, { 0, -1, -1, -1 } }, + { "MATSHITA", "CR-572", "1.0j", "matshita_572", BUS_TYPE_IDE, 0, 4, 36, 0, 0, { 0, -1, -1, -1 } }, + { "MITSUMI", "CRMC-FX4820T", "D02A", "mitsumi_4820t", BUS_TYPE_IDE, 0, 48, 36, 0, 0, { 4, 2, 2, 2 } }, /* TODO: Find an IDENTIFY and/or INQUIRY dump. */ - { "MITSUMI", "CRMC-FX810T4", "????", "mitsumi_810t4", BUS_TYPE_IDE, 0, 8, 36, 0, { 4, 2, 2, -1 } }, - { "NEC", "CD-ROM DRIVE:260", "1.00", "nec_260_early", BUS_TYPE_IDE, 1, 2, 36, 1, { 0, -1, -1, -1 } }, - { "NEC", "CD-ROM DRIVE:260", "1.01", "nec_260", BUS_TYPE_IDE, 1, 4, 36, 1, { 0, -1, -1, -1 } }, - { "NEC", "CD-ROM DRIVE:273", "4.20", "nec_273", BUS_TYPE_IDE, 0, 4, 36, 0, { 0, -1, -1, -1 } }, - { "NEC", "CD-ROM DRIVE:280", "1.05", "nec_280_early", BUS_TYPE_IDE, 0, 6, 36, 1, { 4, 2, 2, -1 } }, - { "NEC", "CD-ROM DRIVE:280", "3.08", "nec_280", BUS_TYPE_IDE, 0, 8, 36, 1, { 4, 2, 2, -1 } }, - { "NEC", "CDR-1300A", "1.05", "nec_1300a", BUS_TYPE_IDE, 0, 6, 36, 0, { 4, 2, 2, -1 } }, - { "NEC", "CDR-1900A", "1.00", "nec_1900a", BUS_TYPE_IDE, 0, 32, 36, 0, { 4, 2, 2, -1 } }, - { "PHILIPS", "CD-ROM PCA403CD", "U31P", "philips_403", BUS_TYPE_IDE, 0, 40, 36, 0, { 4, 2, 2, -1 } }, - { "SONY", "CD-ROM CDU76", "1.0i", "sony_76", BUS_TYPE_IDE, 0, 4, 36, 0, { 2, -1, -1, -1 } }, - { "SONY", "CD-ROM CDU311", "3.0h", "sony_311", BUS_TYPE_IDE, 0, 8, 36, 0, { 3, 2, 1, -1 } }, - { "SONY", "CD-ROM CDU5225", "NYS4", "sony_5225", BUS_TYPE_IDE, 0, 52, 36, 0, { 4, 2, 2, 4 } }, - { "TEAC", "CD-516E", "1.0G", "teac_516e", BUS_TYPE_IDE, 0, 16, 36, 0, { 3, 2, 2, -1 } }, - { "TEAC", "CD-524EA", "3.0D", "teac_524ea", BUS_TYPE_IDE, 0, 24, 36, 0, { 3, 2, 2, -1 } }, - { "TEAC", "CD-532E", "2.0A", "teac_532e", BUS_TYPE_IDE, 0, 32, 36, 0, { 3, 2, 2, -1 } }, - { "TOSHIBA", "CD-ROM XM-5302TA", "0305", "toshiba_5302ta", BUS_TYPE_IDE, 0, 4, 96, 0, { 0, -1, -1, -1 } }, - { "TOSHIBA", "CD-ROM XM-5702B", "TA70", "toshiba_5702b", BUS_TYPE_IDE, 0, 12, 96, 0, { 3, 2, 1, -1 } }, - { "TOSHIBA", "CD-ROM XM-6202B", "1512", "toshiba_6202b", BUS_TYPE_IDE, 0, 32, 96, 0, { 4, 2, 2, -1 } }, - { "TOSHIBA", "CD-ROM XM-6402B", "1008", "toshiba_6402b", BUS_TYPE_IDE, 0, 32, 96, 0, { 4, 2, 2, 2 } }, - { "TOSHIBA", "CD-ROM XM-6702B", "1007", "toshiba_6720b", BUS_TYPE_IDE, 0, 48, 96, 0, { 4, 2, 2, 2 } }, - { "TOSHIBA", "DVD-ROM SD-M1802", "1051", "toshiba_m1802", BUS_TYPE_IDE, 0, 48, 96, 0, { 4, 2, 2, 2 } }, - { "CHINON", "CD-ROM CDS-431", "H42 ", "chinon_431", BUS_TYPE_SCSI, 1, 1, 36, 1, { -1, -1, -1, -1 } }, - { "CHINON", "CD-ROM CDX-435", "M62 ", "chinon_435", BUS_TYPE_SCSI, 1, 2, 36, 1, { -1, -1, -1, -1 } }, - { "DEC", "RRD45 (C) DEC", "0436", "dec_45", BUS_TYPE_SCSI, 1, 4, 36, 0, { -1, -1, -1, -1 } }, - { "MATSHITA", "CD-ROM CR-501", "1.0b", "matshita_501", BUS_TYPE_SCSI, 1, 1, 36, 1, { -1, -1, -1, -1 } }, - { "NEC", "CD-ROM DRIVE:25", "1.0a", "nec_25", BUS_TYPE_SCSI, 1, 2, 36, 0, { -1, -1, -1, -1 } }, - { "NEC", "CD-ROM DRIVE:38", "1.00", "nec_38", BUS_TYPE_SCSI, 2, 1, 36, 0, { -1, -1, -1, -1 } }, + { "MITSUMI", "CRMC-FX810T4", "????", "mitsumi_810t4", BUS_TYPE_IDE, 0, 8, 36, 0, 0, { 4, 2, 2, -1 } }, + { "NEC", "CD-ROM DRIVE:260", "1.00", "nec_260_early", BUS_TYPE_IDE, 1, 2, 36, 1, 0, { 0, -1, -1, -1 } }, + { "NEC", "CD-ROM DRIVE:260", "1.01", "nec_260", BUS_TYPE_IDE, 1, 4, 36, 1, 0, { 0, -1, -1, -1 } }, + { "NEC", "CD-ROM DRIVE:273", "4.20", "nec_273", BUS_TYPE_IDE, 0, 4, 36, 0, 0, { 0, -1, -1, -1 } }, + { "NEC", "CD-ROM DRIVE:280", "1.05", "nec_280_early", BUS_TYPE_IDE, 0, 6, 36, 1, 0, { 4, 2, 2, -1 } }, + { "NEC", "CD-ROM DRIVE:280", "3.08", "nec_280", BUS_TYPE_IDE, 0, 8, 36, 1, 0, { 4, 2, 2, -1 } }, + { "NEC", "CDR-1300A", "1.05", "nec_1300a", BUS_TYPE_IDE, 0, 6, 36, 0, 0, { 4, 2, 2, -1 } }, + { "NEC", "CDR-1900A", "1.00", "nec_1900a", BUS_TYPE_IDE, 0, 32, 36, 0, 0, { 4, 2, 2, -1 } }, + { "PHILIPS", "CD-ROM PCA403CD", "U31P", "philips_403", BUS_TYPE_IDE, 0, 40, 36, 0, 0, { 4, 2, 2, -1 } }, + { "SONY", "CD-ROM CDU76", "1.0i", "sony_76", BUS_TYPE_IDE, 0, 4, 36, 0, 0, { 2, -1, -1, -1 } }, + { "SONY", "CD-ROM CDU311", "3.0h", "sony_311", BUS_TYPE_IDE, 0, 8, 36, 0, 0, { 3, 2, 1, -1 } }, + { "SONY", "CD-ROM CDU5225", "NYS4", "sony_5225", BUS_TYPE_IDE, 0, 52, 36, 0, 0, { 4, 2, 2, 4 } }, + { "TEAC", "CD-516E", "1.0G", "teac_516e", BUS_TYPE_IDE, 0, 16, 36, 0, 0, { 3, 2, 2, -1 } }, + { "TEAC", "CD-524EA", "3.0D", "teac_524ea", BUS_TYPE_IDE, 0, 24, 36, 0, 0, { 3, 2, 2, -1 } }, + { "TEAC", "CD-532E", "2.0A", "teac_532e", BUS_TYPE_IDE, 0, 32, 36, 0, 0, { 3, 2, 2, -1 } }, + { "TOSHIBA", "CD-ROM XM-5302TA", "0305", "toshiba_5302ta", BUS_TYPE_IDE, 0, 4, 96, 0, 0, { 0, -1, -1, -1 } }, + { "TOSHIBA", "CD-ROM XM-5702B", "TA70", "toshiba_5702b", BUS_TYPE_IDE, 0, 12, 96, 0, 0, { 3, 2, 1, -1 } }, + { "TOSHIBA", "CD-ROM XM-6202B", "1512", "toshiba_6202b", BUS_TYPE_IDE, 0, 32, 96, 0, 0, { 4, 2, 2, -1 } }, + { "TOSHIBA", "CD-ROM XM-6402B", "1008", "toshiba_6402b", BUS_TYPE_IDE, 0, 32, 96, 0, 0, { 4, 2, 2, 2 } }, + { "TOSHIBA", "CD-ROM XM-6702B", "1007", "toshiba_6720b", BUS_TYPE_IDE, 0, 48, 96, 0, 0, { 4, 2, 2, 2 } }, + { "TOSHIBA", "DVD-ROM SD-M1802", "1051", "toshiba_m1802", BUS_TYPE_IDE, 0, 48, 96, 0, 1, { 4, 2, 2, 2 } }, + { "CHINON", "CD-ROM CDS-431", "H42 ", "chinon_431", BUS_TYPE_SCSI, 1, 1, 36, 1, 0, { -1, -1, -1, -1 } }, + { "CHINON", "CD-ROM CDX-435", "M62 ", "chinon_435", BUS_TYPE_SCSI, 1, 2, 36, 1, 0, { -1, -1, -1, -1 } }, + { "DEC", "RRD45 (C) DEC", "0436", "dec_45", BUS_TYPE_SCSI, 1, 4, 36, 0, 0, { -1, -1, -1, -1 } }, + { "MATSHITA", "CD-ROM CR-501", "1.0b", "matshita_501", BUS_TYPE_SCSI, 1, 1, 36, 1, 0, { -1, -1, -1, -1 } }, + { "NEC", "CD-ROM DRIVE:25", "1.0a", "nec_25", BUS_TYPE_SCSI, 1, 2, 36, 0, 0, { -1, -1, -1, -1 } }, + { "NEC", "CD-ROM DRIVE:38", "1.00", "nec_38", BUS_TYPE_SCSI, 2, 1, 36, 0, 0, { -1, -1, -1, -1 } }, /* The speed of the following two is guesswork based on the CDR-74. */ - { "NEC", "CD-ROM DRIVE:75", "1.03", "nec_75", BUS_TYPE_SCSI, 1, 1, 36, 1, { -1, -1, -1, -1 } }, - { "NEC", "CD-ROM DRIVE:77", "1.06", "nec_77", BUS_TYPE_SCSI, 1, 1, 36, 1, { -1, -1, -1, -1 } }, - { "NEC", "CD-ROM DRIVE:211", "1.00", "nec_211", BUS_TYPE_SCSI, 2, 3, 36, 0, { -1, -1, -1, -1 } }, + { "NEC", "CD-ROM DRIVE:75", "1.03", "nec_75", BUS_TYPE_SCSI, 1, 1, 36, 1, 0, { -1, -1, -1, -1 } }, + { "NEC", "CD-ROM DRIVE:77", "1.06", "nec_77", BUS_TYPE_SCSI, 1, 1, 36, 1, 0, { -1, -1, -1, -1 } }, + { "NEC", "CD-ROM DRIVE:211", "1.00", "nec_211", BUS_TYPE_SCSI, 2, 3, 36, 0, 0, { -1, -1, -1, -1 } }, /* The speed of the following two is guesswork based on the CDR-400. */ - { "NEC", "CD-ROM DRIVE:464", "1.05", "nec_464", BUS_TYPE_SCSI, 2, 3, 36, 0, { -1, -1, -1, -1 } }, + { "NEC", "CD-ROM DRIVE:464", "1.05", "nec_464", BUS_TYPE_SCSI, 2, 3, 36, 0, 0, { -1, -1, -1, -1 } }, /* The speed of the following two is guesswork based on the name. */ - { "ShinaKen", "CD-ROM DM-3x1S", "1.04", "shinaken_3x1s", BUS_TYPE_SCSI, 1, 3, 36, 0, { -1, -1, -1, -1 } }, - { "SONY", "CD-ROM CDU-541", "1.0i", "sony_541", BUS_TYPE_SCSI, 1, 1, 36, 1, { -1, -1, -1, -1 } }, - { "SONY", "CD-ROM CDU-561", "1.8k", "sony_561", BUS_TYPE_SCSI, 2, 2, 36, 1, { -1, -1, -1, -1 } }, - { "SONY", "CD-ROM CDU-76S", "1.00", "sony_76s", BUS_TYPE_SCSI, 2, 4, 36, 0, { -1, -1, -1, -1 } }, - { "PHILIPS", "CDD2600", "1.07", "philips_2600", BUS_TYPE_SCSI, 2, 6, 36, 0, { -1, -1, -1, -1 } }, + { "ShinaKen", "CD-ROM DM-3x1S", "1.04", "shinaken_3x1s", BUS_TYPE_SCSI, 1, 3, 36, 0, 0, { -1, -1, -1, -1 } }, + { "SONY", "CD-ROM CDU-541", "1.0i", "sony_541", BUS_TYPE_SCSI, 1, 1, 36, 1, 0, { -1, -1, -1, -1 } }, + { "SONY", "CD-ROM CDU-561", "1.8k", "sony_561", BUS_TYPE_SCSI, 2, 2, 36, 1, 0, { -1, -1, -1, -1 } }, + { "SONY", "CD-ROM CDU-76S", "1.00", "sony_76s", BUS_TYPE_SCSI, 2, 4, 36, 0, 0, { -1, -1, -1, -1 } }, + { "PHILIPS", "CDD2600", "1.07", "philips_2600", BUS_TYPE_SCSI, 2, 6, 36, 0, 0, { -1, -1, -1, -1 } }, /* NOTE: The real thing is a CD changer drive! */ - { "PIONEER", "CD-ROM DRM-604X", "2403", "pioneer_604x", BUS_TYPE_SCSI, 2, 4, 47, 0, { -1, -1, -1, -1 } }, - { "PLEXTOR", "CD-ROM PX-32TS", "1.03", "plextor_32ts", BUS_TYPE_SCSI, 2, 32, 36, 0, { -1, -1, -1, -1 } }, + { "PIONEER", "CD-ROM DRM-604X", "2403", "pioneer_604x", BUS_TYPE_SCSI, 2, 4, 47, 0, 0, { -1, -1, -1, -1 } }, + { "PLEXTOR", "CD-ROM PX-32TS", "1.03", "plextor_32ts", BUS_TYPE_SCSI, 2, 32, 36, 0, 0, { -1, -1, -1, -1 } }, /* The speed of the following two is guesswork based on the R55S. */ - { "TEAC", "CD 50", "1.00", "teac_50", BUS_TYPE_SCSI, 2, 4, 36, 1, { -1, -1, -1, -1 } }, - { "TEAC", "CD-ROM R55S", "1.0R", "teac_55s", BUS_TYPE_SCSI, 2, 4, 36, 0, { -1, -1, -1, -1 } }, + { "TEAC", "CD 50", "1.00", "teac_50", BUS_TYPE_SCSI, 2, 4, 36, 1, 0, { -1, -1, -1, -1 } }, + { "TEAC", "CD-ROM R55S", "1.0R", "teac_55s", BUS_TYPE_SCSI, 2, 4, 36, 0, 0, { -1, -1, -1, -1 } }, /* Texel is Plextor according to Plextor's own EU website. */ - { "TEXEL", "CD-ROM DM-3024", "1.00", "texel_3024", BUS_TYPE_SCSI, 2, 2, 36, 1, { -1, -1, -1, -1 } }, + { "TEXEL", "CD-ROM DM-3024", "1.00", "texel_3024", BUS_TYPE_SCSI, 2, 2, 36, 1, 0, { -1, -1, -1, -1 } }, /* Unusual 2.23x according to Google, I'm rounding it upwards to 3x. Assumed caddy based on the DM-3024. */ - { "TEXEL", "CD-ROM DM-3028", "1.06", "texel_3028", BUS_TYPE_SCSI, 2, 3, 36, 1, { -1, -1, -1, -1 } }, /* Caddy. */ + { "TEXEL", "CD-ROM DM-3028", "1.06", "texel_3028", BUS_TYPE_SCSI, 2, 3, 36, 1, 0, { -1, -1, -1, -1 } }, /* Caddy. */ /* The characteristics are a complete guesswork because I can't find this one on Google. Also, INQUIRY length is always 96 on these Toshiba drives. */ - { "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "toshiba_xm", BUS_TYPE_SCSI, 2, 2, 96, 0, { -1, -1, -1, -1 } }, /* Tray. */ - { "TOSHIBA", "CD-ROM XM-3201B", "3232", "toshiba_3201b", BUS_TYPE_SCSI, 1, 1, 96, 1, { -1, -1, -1, -1 } }, /* Caddy. */ - { "TOSHIBA", "CD-ROM XM-3301TA", "0272", "toshiba_3301ta", BUS_TYPE_SCSI, 2, 2, 96, 0, { -1, -1, -1, -1 } }, /* Tray. */ - { "TOSHIBA", "CD-ROM XM-5701TA", "3136", "toshiba_5701a", BUS_TYPE_SCSI, 2, 12, 96, 0, { -1, -1, -1, -1 } }, /* Tray. */ - { "TOSHIBA", "DVD-ROM SD-M1401", "1008", "toshiba_m1401", BUS_TYPE_SCSI, 2, 40, 96, 0, { -1, -1, -1, -1 } }, /* Tray. */ - { "", "", "", "", BUS_TYPE_NONE, 0, -1, 0, 0, { -1, -1, -1, -1 } } + { "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "toshiba_xm", BUS_TYPE_SCSI, 2, 2, 96, 0, 0, { -1, -1, -1, -1 } }, /* Tray. */ + { "TOSHIBA", "CD-ROM XM-3201B", "3232", "toshiba_3201b", BUS_TYPE_SCSI, 1, 1, 96, 1, 0, { -1, -1, -1, -1 } }, /* Caddy. */ + { "TOSHIBA", "CD-ROM XM-3301TA", "0272", "toshiba_3301ta", BUS_TYPE_SCSI, 2, 2, 96, 0, 0, { -1, -1, -1, -1 } }, /* Tray. */ + { "TOSHIBA", "CD-ROM XM-5701TA", "3136", "toshiba_5701a", BUS_TYPE_SCSI, 2, 12, 96, 0, 0, { -1, -1, -1, -1 } }, /* Tray. */ + { "TOSHIBA", "DVD-ROM SD-M1401", "1008", "toshiba_m1401", BUS_TYPE_SCSI, 2, 40, 96, 0, 1, { -1, -1, -1, -1 } }, /* Tray. */ + { "MATSHITA", "CR-562", "0.75", "cr562", BUS_TYPE_MKE , 0, 2, 0, 0, 0, { -1, -1, -1, -1 } }, + { "MATSHITA", "CR-562", "0.80", "cr562_080", BUS_TYPE_MKE , 0, 2, 0, 0, 0, { -1, -1, -1, -1 } }, + { "MATSHITA", "CR-563", "0.75", "cr563", BUS_TYPE_MKE , 0, 2, 0, 0, 0, { -1, -1, -1, -1 } }, + { "MATSHITA", "CR-563", "0.80", "cr563_080", BUS_TYPE_MKE , 0, 2, 0, 0, 0, { -1, -1, -1, -1 } }, + { "", "", "", "", BUS_TYPE_NONE, 0, -1, 0, 0, 0, { -1, -1, -1, -1 } } }; /* To shut up the GCC compilers. */ @@ -283,7 +297,7 @@ typedef struct cdrom { union { uint8_t res; uint8_t res0; /* Reserved for other ID's. */ - uint8_t res1; + uint8_t mke_channel; uint8_t ide_channel; uint8_t scsi_device_id; }; @@ -296,7 +310,7 @@ typedef struct cdrom { uint8_t speed; uint8_t cur_speed; - void * priv; + void *priv; char image_path[1024]; char prev_image_path[1280]; @@ -322,10 +336,10 @@ typedef struct cdrom { const cdrom_ops_t *ops; - char * image_history[CD_IMAGE_HISTORY]; + char *image_history[CD_IMAGE_HISTORY]; - void * local; - void * log; + void *local; + void *log; void (*insert)(void *priv); void (*close)(void *priv); @@ -351,6 +365,13 @@ typedef struct cdrom { /* Only used on Windows hosts for disc change notifications. */ uint8_t host_letter; + uint8_t mode2; + + uint8_t _F_LUT[_LUT_SIZE]; + uint8_t _B_LUT[_LUT_SIZE]; + + uint8_t p_parity[172]; + uint8_t q_parity[104]; } cdrom_t; extern cdrom_t cdrom[CDROM_NUM]; @@ -374,6 +395,7 @@ extern void cdrom_get_model(const int type, char *name, const int id) extern char *cdrom_get_revision(const int type); extern int cdrom_get_scsi_std(const int type); extern int cdrom_is_early(const int type); +extern int cdrom_is_dvd(const int type); extern int cdrom_is_generic(const int type); extern int cdrom_is_caddy(const int type); extern int cdrom_get_speed(const int type); @@ -381,6 +403,7 @@ extern int cdrom_get_inquiry_len(const int type); extern int cdrom_has_dma(const int type); extern int cdrom_get_transfer_max(const int type, const int mode); extern int cdrom_get_type_count(void); +extern void cdrom_generate_name_mke(const int type, char *name); extern void cdrom_get_identify_model(const int type, char *name, const int id); extern void cdrom_get_name(const int type, char *name); extern char *cdrom_get_internal_name(const int type); @@ -448,6 +471,12 @@ extern int cdrom_is_empty(const uint8_t id); extern void cdrom_eject(const uint8_t id); extern void cdrom_reload(const uint8_t id); +extern void cdrom_compute_ecc_block(cdrom_t *dev, uint8_t *parity, const uint8_t *data, + uint32_t major_count, uint32_t minor_count, + uint32_t major_mult, uint32_t minor_inc, int m2f1); +extern unsigned long cdrom_crc32(unsigned long crc, const unsigned char *buf, + size_t len); + extern int cdrom_assigned_letters; #ifdef __cplusplus diff --git a/src/include/86box/cdrom_image.h b/src/include/86box/cdrom_image.h index 84dd66f37..e0760ff7e 100644 --- a/src/include/86box/cdrom_image.h +++ b/src/include/86box/cdrom_image.h @@ -33,6 +33,6 @@ typedef struct track_file_t { int motorola; } track_file_t; -extern void * image_open(cdrom_t *dev, const char *path); +extern void *image_open(cdrom_t *dev, const char *path); #endif /*CDROM_IMAGE_H*/ diff --git a/src/include/86box/cdrom_mitsumi.h b/src/include/86box/cdrom_mitsumi.h index 0b8a3a250..01c549c0b 100644 --- a/src/include/86box/cdrom_mitsumi.h +++ b/src/include/86box/cdrom_mitsumi.h @@ -8,11 +8,11 @@ * * Mitsumi CD-ROM emulation for the ISA bus. * - * - * * Authors: Miran Grca, + * Jasmine Iwanek, * - * Copyright 2022 Miran Grca. + * Copyright 2022 Miran Grca. + * Copyright 2024-2025 Jasmine Iwanek. */ #ifndef CDROM_MITSUMI_H #define CDROM_MITSUMI_H diff --git a/src/include/86box/cdrom_mke.h b/src/include/86box/cdrom_mke.h new file mode 100644 index 000000000..659e084e3 --- /dev/null +++ b/src/include/86box/cdrom_mke.h @@ -0,0 +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. + * + * Panasonic/MKE CD-ROM emulation for the ISA bus. + * + * Authors: Miran Grca, + * Cacodemon345 + * + * Copyright 2022-2025 Miran Grca. + * Copyright 2025 Cacodemon345. + */ + +#ifndef CDROM_MKE_H +#define CDROM_MKE_H + +extern const device_t mke_cdrom_device; +extern const device_t mke_cdrom_noncreative_device; + +#endif /*CDROM_MKE_H*/ diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 3a65bbce9..7ee8182ea 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -18,6 +18,7 @@ #define EMU_CHIPSET_H /* ACC */ +extern const device_t acc2036_device; extern const device_t acc2168_device; /* ALi */ @@ -37,6 +38,9 @@ extern const device_t ali6117d_device; /* AMD */ extern const device_t amd640_device; +/* ASUS */ +extern const device_t isa486c_device; + /* Compaq */ extern const device_t compaq_386_device; extern const device_t compaq_genoa_device; @@ -52,6 +56,7 @@ extern const device_t neat_sx_device; extern const device_t scat_device; extern const device_t scat_4_device; extern const device_t scat_sx_device; +extern const device_t cs8220_device; extern const device_t cs8230_device; extern const device_t cs4031_device; @@ -109,6 +114,9 @@ extern const device_t slc90e66_device; extern const device_t ioapic_device; +/* Olivetti */ +extern const device_t olivetti_eva_device; + /* OPTi */ extern const device_t opti283_device; extern const device_t opti291_device; @@ -116,7 +124,9 @@ extern const device_t opti381_device; extern const device_t opti391_device; extern const device_t opti481_device; extern const device_t opti493_device; -extern const device_t opti495_device; +extern const device_t opti495slc_device; +extern const device_t opti495sx_device; +extern const device_t opti498_device; extern const device_t opti499_device; extern const device_t opti601_device; extern const device_t opti602_device; @@ -156,6 +166,9 @@ extern const device_t stpc_atlas_device; extern const device_t stpc_serial_device; extern const device_t stpc_lpt_device; +/* Symphony */ +extern const device_t sl82c461_device; + /* UMC */ extern const device_t umc_8886f_device; extern const device_t umc_8886af_device; @@ -191,12 +204,12 @@ extern const device_t vlsi_scamp_device; extern const device_t wd76c10_device; /* Miscellaneous Hardware */ +extern const device_t tulip_jumper_device; + +extern const device_t dell_jumper_device; + 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; - -#ifdef USE_OLIVETTI -extern const device_t olivetti_eva_device; -#endif /* USE_OLIVETTI */ #endif /*EMU_CHIPSET_H*/ diff --git a/src/include/86box/config.h b/src/include/86box/config.h index 693f38ab7..b2391527a 100644 --- a/src/include/86box/config.h +++ b/src/include/86box/config.h @@ -122,6 +122,7 @@ typedef struct config_t { int ide_qua_enabled; /* Quaternary IDE controller enabled */ int bugger_enabled; /* ISA bugger device enabled */ int isa_rtc_type; /* ISA RTC card */ + int isa_rom_type[ISAROM_MAX]; /* ISA ROM boards */ int isa_mem_type[ISAMEM_MAX]; /* ISA memory boards */ /* Hard disks category */ @@ -132,7 +133,7 @@ typedef struct config_t { /* Other removable devices category */ storage_cfg_t cdrom[CDROM_NUM]; /* CD-ROM drives */ - storage_cfg_t rdisk[ZIP_NUM]; /* Removable disk drives */ + storage_cfg_t rdisk[RDISK_NUM]; /* Removable disk drives */ } config_t; #endif diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 91ff2daa6..76f12a0c5 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -239,6 +239,8 @@ extern const char *device_get_internal_name(const device_t *dev); extern int machine_get_config_int(char *str); extern const char *machine_get_config_string(char *str); +extern int machine_device_available(const device_t *dev); + extern const device_t device_none; extern const device_t device_internal; diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 2d17380d0..cd1e58db7 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -38,26 +38,27 @@ #define FDC_QUATERNARY_IRQ 6 #define FDC_QUATERNARY_DMA 2 -#define FDC_FLAG_PCJR 0x01 /* PCjr */ -#define FDC_FLAG_DISKCHG_ACTLOW 0x02 /* Amstrad, PS/1, PS/2 ISA */ -#define FDC_FLAG_AT 0x04 /* AT+, PS/x */ -#define FDC_FLAG_PS2 0x08 /* PS/1, PS/2 ISA */ -#define FDC_FLAG_PS2_MCA 0x10 /* PS/2 MCA */ -#define FDC_FLAG_SUPERIO 0x20 /* Super I/O chips */ -#define FDC_FLAG_START_RWC_1 0x40 /* W83877F, W83977F */ -#define FDC_FLAG_MORE_TRACKS 0x80 /* W83877F, W83977F, PC87306, PC87309 */ -#define FDC_FLAG_NSC 0x100 /* PC87306, PC87309 */ -#define FDC_FLAG_TOSHIBA 0x200 /* T1000, T1200 */ -#define FDC_FLAG_AMSTRAD 0x400 /* Non-AT Amstrad machines */ -#define FDC_FLAG_UMC 0x800 /* UMC UM8398 */ -#define FDC_FLAG_ALI 0x1000 /* ALi M512x / M1543C */ -#define FDC_FLAG_NO_DSR_RESET 0x2000 /* Has no DSR reset */ -#define FDC_FLAG_DENSEL_INVERT 0x4000 /* Invert DENSEL polarity */ -#define FDC_FLAG_FINTR 0x8000 /* Raise FINTR on data command finish */ -#define FDC_FLAG_NEC 0x10000 /* Is NEC upd765-compatible */ -#define FDC_FLAG_SEC 0x20000 /* Is Secondary */ -#define FDC_FLAG_TER 0x40000 /* Is Tertiary */ -#define FDC_FLAG_QUA 0x80000 /* Is Quaternary */ +#define FDC_FLAG_PCJR 0x01 /* PCjr */ +#define FDC_FLAG_DISKCHG_ACTLOW 0x02 /* Amstrad, PS/1, PS/2 ISA */ +#define FDC_FLAG_AT 0x04 /* AT+, PS/x */ +#define FDC_FLAG_PS2 0x08 /* PS/1, PS/2 ISA */ +#define FDC_FLAG_PS2_MCA 0x10 /* PS/2 MCA */ +#define FDC_FLAG_SUPERIO 0x20 /* Super I/O chips */ +#define FDC_FLAG_START_RWC_1 0x40 /* W83877F, W83977F */ +#define FDC_FLAG_MORE_TRACKS 0x80 /* W83877F, W83977F, PC87306, PC87309 */ +#define FDC_FLAG_NSC 0x100 /* PC87306, PC87309 */ +#define FDC_FLAG_TOSHIBA 0x200 /* T1000, T1200 */ +#define FDC_FLAG_AMSTRAD 0x400 /* Non-AT Amstrad machines */ +#define FDC_FLAG_UMC 0x800 /* UMC UM8398 */ +#define FDC_FLAG_ALI 0x1000 /* ALi M512x / M1543C */ +#define FDC_FLAG_NO_DSR_RESET 0x2000 /* Has no DSR reset */ +#define FDC_FLAG_DENSEL_INVERT 0x4000 /* Invert DENSEL polarity */ +#define FDC_FLAG_FINTR 0x8000 /* Raise FINTR on data command finish */ +#define FDC_FLAG_NEC 0x10000 /* Is NEC upd765-compatible */ +#define FDC_FLAG_SEC 0x20000 /* Is Secondary */ +#define FDC_FLAG_TER 0x40000 /* Is Tertiary */ +#define FDC_FLAG_QUA 0x80000 /* Is Quaternary */ +#define FDC_FLAG_SMC661 0x100000 /* SM(s)C FDC37C661 - different TDR enhanced mode */ typedef struct fdc_t { uint8_t dor; @@ -119,6 +120,8 @@ typedef struct fdc_t { uint8_t lock; uint8_t dsr; + uint8_t media_id; + uint8_t params[15]; uint8_t specify[2]; uint8_t res[11]; @@ -166,6 +169,9 @@ extern void fdc_3f1_enable(fdc_t *fdc, int enable); extern int fdc_get_bit_rate(fdc_t *fdc); extern int fdc_get_bitcell_period(fdc_t *fdc); +extern uint8_t fdc_get_media_id(fdc_t *fdc, int id); +extern void fdc_set_media_id(fdc_t *fdc, int id, int set); + /* A few functions to communicate between Super I/O chips and the FDC. */ extern void fdc_update_enh_mode(fdc_t *fdc, int enh_mode); extern int fdc_get_rwc(fdc_t *fdc, int drive); @@ -177,6 +183,7 @@ extern uint8_t fdc_get_densel_polarity(fdc_t *fdc); extern void fdc_update_densel_force(fdc_t *fdc, int densel_force); extern void fdc_update_drvrate(fdc_t *fdc, int drive, int drvrate); extern void fdc_update_drv2en(fdc_t *fdc, int drv2en); +extern void fdc_toggle_flag(fdc_t *fdc, int flag, int on); extern void fdc_noidam(fdc_t *fdc); extern void fdc_nosector(fdc_t *fdc); @@ -201,6 +208,7 @@ 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); extern int fdc_is_mfm(fdc_t *fdc); +extern int fdc_is_dma(fdc_t *fdc); extern double fdc_get_hut(fdc_t *fdc); extern double fdc_get_hlt(fdc_t *fdc); extern void fdc_request_next_sector_id(fdc_t *fdc); @@ -215,6 +223,11 @@ extern uint8_t fdc_get_diswr(fdc_t *fdc); extern void fdc_set_diswr(fdc_t *fdc, uint8_t diswr); extern uint8_t fdc_get_swap(fdc_t *fdc); extern void fdc_set_swap(fdc_t *fdc, uint8_t swap); +extern void fdc_set_flags(fdc_t *fdc, int flags); +extern void fdc_clear_flags(fdc_t *fdc, int flags); +extern void fdc_set_fdd_changed(int drive, int changed); +extern uint8_t fdc_get_fdd_changed(int drive); +extern uint8_t fdc_get_shadow(fdc_t *fdc); extern void fdc_finishcompare(fdc_t *fdc, int satisfying); extern void fdc_finishread(fdc_t *fdc); @@ -254,6 +267,7 @@ extern const device_t fdc_at_sec_device; extern const device_t fdc_at_ter_device; extern const device_t fdc_at_qua_device; extern const device_t fdc_at_actlow_device; +extern const device_t fdc_at_smc_661_device; extern const device_t fdc_at_smc_device; extern const device_t fdc_at_ali_device; extern const device_t fdc_at_winbond_device; diff --git a/src/include/86box/flash.h b/src/include/86box/flash.h index 6f0e1ff15..bd9b7e505 100644 --- a/src/include/86box/flash.h +++ b/src/include/86box/flash.h @@ -20,6 +20,7 @@ #ifndef EMU_FLASH_H #define EMU_FLASH_H +extern const device_t amd_am28f010_flash_device; extern const device_t catalyst_flash_device; extern const device_t intel_flash_bxt_ami_device; diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index 7928cdd30..a990d018e 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -15,7 +15,7 @@ * * Copyright 2016-2022 Miran Grca. * Copyright 2008-2018 Sarah Walker. - * Copyright 2021 RichardG. + * Copyright 2021 RichardG. * Copyright 2021-2025 Jasmine Iwanek. */ #ifndef EMU_GAMEPORT_H @@ -51,8 +51,29 @@ #define GAMEPORT_6ADDR 0x060000 #define GAMEPORT_8ADDR 0x080000 #define GAMEPORT_SIO 0x1000000 +#define GAMEPORT_PNPROM 0x2000000 -typedef struct plat_joystick_t { +typedef struct joystick_t { + const char *name; + const char *internal_name; + + void *(*init)(void); + void (*close)(void *priv); + uint8_t (*read)(void *priv); + void (*write)(void *priv); + int (*read_axis)(void *priv, int axis); + void (*a0_over)(void *priv); + + int axis_count; + int button_count; + int pov_count; + int max_joysticks; + const char *axis_names[MAX_JOY_AXES]; + const char *button_names[MAX_JOY_BUTTONS]; + const char *pov_names[MAX_JOY_POVS]; +} joystick_t; + +typedef struct plat_joystick_state_t { char name[260]; int a[MAX_JOY_AXES]; @@ -77,9 +98,9 @@ typedef struct plat_joystick_t { int nr_axes; int nr_buttons; int nr_povs; -} plat_joystick_t; +} plat_joystick_state_t; -typedef struct joystick_t { +typedef struct joystick_state_t { int axis[MAX_JOY_AXES]; int button[MAX_JOY_BUTTONS]; int pov[MAX_JOY_POVS]; @@ -88,27 +109,7 @@ typedef struct joystick_t { int axis_mapping[MAX_JOY_AXES]; int button_mapping[MAX_JOY_BUTTONS]; int pov_mapping[MAX_JOY_POVS][2]; -} joystick_t; - -typedef struct joystick_if_t { - const char *name; - const char *internal_name; - - void *(*init)(void); - void (*close)(void *priv); - uint8_t (*read)(void *priv); - void (*write)(void *priv); - int (*read_axis)(void *priv, int axis); - void (*a0_over)(void *priv); - - int axis_count; - int button_count; - int pov_count; - int max_joysticks; - const char *axis_names[MAX_JOY_AXES]; - const char *button_names[MAX_JOY_BUTTONS]; - const char *pov_names[MAX_JOY_POVS]; -} joystick_if_t; +} joystick_state_t; extern device_t game_ports[GAMEPORT_MAX]; @@ -126,6 +127,7 @@ extern int gameport_get_from_internal_name(const char *str); #ifdef EMU_DEVICE_H extern const device_t gameport_device; +extern const device_t gameport_200_device; extern const device_t gameport_201_device; extern const device_t gameport_203_device; extern const device_t gameport_205_device; @@ -144,10 +146,10 @@ extern const device_t gameport_sio_1io_device; extern const device_t *standalone_gameport_type; #endif -extern int gameport_instance_id; -extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -extern joystick_t joystick_state[GAMEPORT_MAX][MAX_JOYSTICKS]; -extern int joysticks_present; +extern int gameport_instance_id; +extern plat_joystick_state_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +extern joystick_state_t joystick_state[GAMEPORT_MAX][MAX_JOYSTICKS]; +extern int joysticks_present; extern int joystick_type; @@ -170,29 +172,28 @@ extern void gameport_update_joystick_type(void); extern void gameport_remap(void *priv, uint16_t address); extern void *gameport_add(const device_t *gameport_type); -extern const joystick_if_t joystick_2axis_2button; -extern const joystick_if_t joystick_2axis_4button; -extern const joystick_if_t joystick_3axis_2button; -extern const joystick_if_t joystick_3axis_4button; -extern const joystick_if_t joystick_4axis_4button; -extern const joystick_if_t joystick_2axis_6button; -extern const joystick_if_t joystick_2axis_8button; +extern const joystick_t joystick_2axis_2button; +extern const joystick_t joystick_2button_gamepad; +extern const joystick_t joystick_2button_flight_yoke; +extern const joystick_t joystick_2axis_4button; +extern const joystick_t joystick_4button_gamepad; +extern const joystick_t joystick_4button_flight_yoke; +extern const joystick_t joystick_3axis_2button; +extern const joystick_t joystick_2button_yoke_throttle; +extern const joystick_t joystick_3axis_4button; +extern const joystick_t joystick_4button_yoke_throttle; +extern const joystick_t joystick_win95_steering_wheel; +extern const joystick_t joystick_4axis_4button; +extern const joystick_t joystick_2axis_6button; +extern const joystick_t joystick_2axis_8button; -extern const joystick_if_t joystick_ch_flightstick_pro; -extern const joystick_if_t joystick_ch_flightstick_pro_ch_pedals; +extern const joystick_t joystick_ch_flightstick_pro; +extern const joystick_t joystick_ch_flightstick_pro_ch_pedals; -extern const joystick_if_t joystick_sw_pad; +extern const joystick_t joystick_sw_pad; -extern const joystick_if_t joystick_tm_fcs; -extern const joystick_if_t joystick_tm_fcs_rcs; - -extern int gameport_available(int); -extern int gameport_has_config(int); -extern const char *gameport_get_internal_name(int); -extern int gampeport_get_from_internal_name(char *); -#ifdef EMU_DEVICE_H -extern const device_t *gameport_getdevice(int); -#endif +extern const joystick_t joystick_tm_fcs; +extern const joystick_t joystick_tm_fcs_rcs; #ifdef __cplusplus } diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 71f83e5e6..c308078a5 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -27,7 +27,7 @@ #define HDC_NONE 0 #define HDC_INTERNAL 1 -#define HDC_MAX 2 +#define HDC_MAX 4 extern int hdc_current[HDC_MAX]; @@ -60,6 +60,8 @@ extern const device_t ide_pci_device; /* pci_ide */ extern const device_t ide_pci_sec_device; /* pci_ide sec */ extern const device_t ide_pci_2ch_device; /* pci_ide_2ch */ +extern const device_t ide_pci_ter_qua_2ch_device; /* pci_ide_ter_qua_2ch */ + extern const device_t ide_ali1489_device; /* ALi M1489 */ extern const device_t ide_ali5213_device; /* ALi M5213 */ @@ -76,10 +78,17 @@ extern const device_t ide_cmd640_pci_single_channel_sec_device; /* CMD PCI-640B extern const device_t ide_cmd646_device; /* CMD PCI-646 */ extern const device_t ide_cmd646_legacy_only_device; /* CMD PCI-646 (Legacy Mode Only) */ extern const device_t ide_cmd646_single_channel_device; /* CMD PCI-646 (Only primary channel) */ +extern const device_t ide_cmd646_ter_qua_device; /* CMD PCI-646 (Tertiary and quaternary channels) */ +extern const device_t ide_cmd648_ter_qua_device; /* CMD PCI-648 (Tertiary and quaternary channels) */ +extern const device_t ide_cmd648_ter_qua_onboard_device; /* CMD PCI-648 (Tertiary and quaternary channels, on-board) */ +extern const device_t ide_cmd649_ter_qua_device; /* CMD PCI-649 (Tertiary and quaternary channels) */ extern const device_t ide_opti611_vlb_device; /* OPTi 82c611/611A VLB */ extern const device_t ide_opti611_vlb_sec_device; /* OPTi 82c611/611A VLB (Secondary channel) */ +extern const device_t ide_rz1000_pci_device; /* PC Technology RZ-1000 PCI */ +extern const device_t ide_rz1000_pci_single_channel_device; /* PC Technology RZ-1000 PCI (Only primary channel) */ + extern const device_t ide_um8673f_device; /* UMC UM8673F */ extern const device_t ide_um8886af_device; /* UMC UM8886AF */ @@ -96,8 +105,10 @@ extern const device_t ide_qua_pnp_device; extern const device_t mcide_device; -extern const device_t xta_wdxt150_device; /* xta_wdxt150 */ -extern const device_t xta_hd20_device; /* EuroPC internal */ +extern const device_t xta_wdxt150_device; /* xta_wdxt150 */ +extern const device_t xta_hd20_device; /* EuroPC internal */ +extern const device_t xta_st50x_device; /* ST-50X */ +extern const device_t xta_st50x_pc5086_device; /* ST-50X (PC-5086) */ extern const device_t xtide_device; /* xtide_xt */ extern const device_t xtide_at_device; /* xtide_at */ @@ -106,17 +117,16 @@ extern const device_t xtide_acculogic_device; /* xtide_ps2 */ extern const device_t xtide_at_ps2_device; /* xtide_at_ps2 */ extern const device_t xtide_at_ps2_2ch_device; /* xtide_at_ps2_2ch */ -/* Miscellaneous */ -extern const device_t lba_enhancer_device; - extern void hdc_init(void); extern void hdc_reset(void); extern const char *hdc_get_internal_name(int hdc); -extern int hdc_get_from_internal_name(char *s); +extern int hdc_get_from_internal_name(const char *s); extern int hdc_has_config(int hdc); extern const device_t *hdc_get_device(int hdc); extern int hdc_get_flags(int hdc); extern int hdc_available(int hdc); +extern void xta_handler(void *priv, int set); + #endif /*EMU_HDC_H*/ diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index 41fb7703e..3fd589f9c 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -178,9 +178,6 @@ enum { TIMINGS_PIO_FC = 2 }; -extern int ide_ter_enabled; -extern int ide_qua_enabled; - #ifdef SCSI_DEVICE_H extern ide_t *ide_get_drive(int ch); extern void ide_irq(ide_t *ide, int set, int log); @@ -230,6 +227,8 @@ extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src); extern uint8_t ide_read_ali_75(void); extern uint8_t ide_read_ali_76(void); +extern void ide_hard_reset(void); + /* Legacy #define's. */ #define ide_irq_raise(ide) ide_irq(ide, 1, 1) #define ide_irq_lower(ide) ide_irq(ide, 0, 1) diff --git a/src/include/86box/hdc_ide_sff8038i.h b/src/include/86box/hdc_ide_sff8038i.h index 79075b8b2..901cdb325 100644 --- a/src/include/86box/hdc_ide_sff8038i.h +++ b/src/include/86box/hdc_ide_sff8038i.h @@ -56,6 +56,11 @@ typedef struct sff8038i_t int irq_level; int irq_pin; int pci_irq_line; + + uint8_t (*ven_write)(uint16_t port, uint8_t val, void *priv); + uint8_t (*ven_read)(uint16_t port, uint8_t val, void *priv); + + void *priv; } sff8038i_t; extern const device_t sff8038i_device; @@ -78,4 +83,7 @@ extern void sff_set_irq_pin(sff8038i_t *dev, int irq_pin); extern void sff_set_irq_level(sff8038i_t *dev, int irq_level); extern void sff_set_mirq(sff8038i_t *dev, uint8_t mirq); +extern void sff_set_ven_handlers(sff8038i_t *dev, uint8_t (*ven_write)(uint16_t port, uint8_t val, void *priv), + uint8_t (*ven_read)(uint16_t port, uint8_t val, void *priv), void *priv); + #endif /*EMU_HDC_IDE_SFF8038I_H*/ diff --git a/src/include/86box/hdd.h b/src/include/86box/hdd.h index eda4396ef..597059e4f 100644 --- a/src/include/86box/hdd.h +++ b/src/include/86box/hdd.h @@ -67,14 +67,15 @@ enum { }; #else enum { - HDD_BUS_DISABLED = 0, - HDD_BUS_MFM = 1, - HDD_BUS_XTA = 2, - HDD_BUS_ESDI = 3, - HDD_BUS_IDE = 4, - HDD_BUS_ATAPI = 5, - HDD_BUS_SCSI = 6, - HDD_BUS_USB = 7 + HDD_BUS_DISABLED = 0, + HDD_BUS_MFM = 1, + HDD_BUS_XTA = 2, + HDD_BUS_ESDI = 3, + HDD_BUS_LPT = 6, + HDD_BUS_IDE = 7, + HDD_BUS_ATAPI = 8, + HDD_BUS_SCSI = 9, + HDD_BUS_USB = 10 }; #endif @@ -159,7 +160,7 @@ typedef struct hard_disk_t { uint8_t pad; uint8_t pad0; - void * priv; + void *priv; char fn[1024]; /* Name of current image file */ /* Differential VHD parent file */ @@ -185,7 +186,7 @@ typedef struct hard_disk_t { uint8_t max_multiple_block; uint8_t pad1[3]; - const char * model; + const char *model; hdd_zone_t zones[HDD_MAX_ZONES]; diff --git a/src/include/86box/isamem.h b/src/include/86box/isamem.h index 51fe50e33..93f417e3e 100644 --- a/src/include/86box/isamem.h +++ b/src/include/86box/isamem.h @@ -42,7 +42,6 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #ifndef EMU_ISAMEM_H #define EMU_ISAMEM_H @@ -52,17 +51,12 @@ extern "C" { #endif -/* Global variables. */ -extern const device_t isamem_device; -extern const device_t isamem_brat80_device; -extern const device_t isamem_ev159_device; - /* Functions. */ extern void isamem_reset(void); extern const char *isamem_get_name(int t); extern const char *isamem_get_internal_name(int t); -extern int isamem_get_from_internal_name(const char *s); +extern int isamem_get_from_internal_name(const char *str); extern const device_t *isamem_get_device(int t); extern int isamem_has_config(int board); diff --git a/src/include/86box/isarom.h b/src/include/86box/isarom.h new file mode 100644 index 000000000..91cfa15a9 --- /dev/null +++ b/src/include/86box/isarom.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. + * + * Implementation of ISA ROM card Expansions. + * + * Authors: Jasmine Iwanek, + * + * Copyright 2025 Jasmine Iwanek. + */ +#ifndef EMU_ISAROM_H +#define EMU_ISAROM_H + +#define ISAROM_MAX 4 /* max #cards in system */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Functions. */ +extern void isarom_reset(void); + +extern const char *isarom_get_name(int t); +extern const char *isarom_get_internal_name(int t); +extern int isarom_get_from_internal_name(const char *str); +extern const device_t *isarom_get_device(int t); +extern int isarom_has_config(int board); + +#ifdef __cplusplus +} +#endif + +#endif /*EMU_ISAROM_H*/ diff --git a/src/include/86box/isartc.h b/src/include/86box/isartc.h index 0224180b3..815daa5d6 100644 --- a/src/include/86box/isartc.h +++ b/src/include/86box/isartc.h @@ -42,7 +42,6 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #ifndef EMU_ISARTC_H #define EMU_ISARTC_H @@ -50,13 +49,11 @@ extern "C" { #endif -/* Global variables. */ - /* Functions. */ extern void isartc_reset(void); extern const char *isartc_get_internal_name(int t); -extern int isartc_get_from_internal_name(char *s); +extern int isartc_get_from_internal_name(const char *str); extern const device_t *isartc_get_device(int t); extern int isartc_has_config(int board); diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index e21fa60d9..86cea515e 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -22,6 +22,21 @@ #ifndef EMU_KEYBOARD_H #define EMU_KEYBOARD_H +#define FLAG_AT 0x00 /* dev is AT */ +#define FLAG_PS2_KBD 0x10 /* dev is AT or PS/2 */ +#define FLAG_AX 0x08 /* dev is AX */ +#define FLAG_TYPE_MASK 0x07 /* mask for type */ + +enum { + KBD_83_KEY = 0, + KBD_84_KEY, + KBD_101_KEY, + KBD_102_KEY, + KBD_JIS, + KBD_KSC, + KBD_ABNT2 +}; + enum { DEV_KBD = 0, DEV_AUX = 1 @@ -38,6 +53,15 @@ enum { DEV_STATE_MAIN_WANT_EXECUTE_BAT = 7 }; +enum { + KEYBOARD_TYPE_INTERNAL = 0, + KEYBOARD_TYPE_PC_XT, + KEYBOARD_TYPE_AT, + KEYBOARD_TYPE_AX, + KEYBOARD_TYPE_PS2, + KEYBOARD_TYPE_PS55 +}; + /* Used by the AT / PS/2 keyboard controller, common device, keyboard, and mouse. */ typedef struct kbc_at_port_t { uint8_t wantcmd; @@ -194,6 +218,8 @@ typedef struct scancode { extern "C" { #endif +extern int keyboard_type; + extern uint8_t keyboard_mode; extern int keyboard_scan; @@ -216,52 +242,56 @@ extern int mouse_scan; extern kbc_at_port_t *kbc_at_ports[2]; #ifdef EMU_DEVICE_H -extern const device_t keyboard_pc_device; -extern const device_t keyboard_pc82_device; -extern const device_t keyboard_pravetz_device; -extern const device_t keyboard_xt_device; -extern const device_t keyboard_xt86_device; -extern const device_t keyboard_xt_compaq_device; -extern const device_t keyboard_xt_t1x00_device; -extern const device_t keyboard_tandy_device; -# ifdef USE_LASERXT -extern const device_t keyboard_xt_lxt3_device; -# endif /* 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_ami_device; -extern const device_t keyboard_at_compaq_device; -extern const device_t keyboard_at_phoenix_device; -extern const device_t keyboard_at_ncr_device; -extern const device_t keyboard_at_olivetti_device; -extern const device_t keyboard_at_siemens_device; -extern const device_t keyboard_at_tg_ami_device; -extern const device_t keyboard_at_toshiba_device; -extern const device_t keyboard_ps2_device; -extern const device_t keyboard_ps2_ps1_device; -extern const device_t keyboard_ps2_ps1_pci_device; -extern const device_t keyboard_ps2_xi8088_device; -extern const device_t keyboard_ps2_ami_device; -extern const device_t keyboard_ps2_compaq_device; -extern const device_t keyboard_ps2_holtek_device; -extern const device_t keyboard_ps2_mca_1_device; -extern const device_t keyboard_ps2_mca_2_device; -extern const device_t keyboard_ps2_olivetti_device; -extern const device_t keyboard_ps2_phoenix_device; -extern const device_t keyboard_ps2_quadtel_device; -extern const device_t keyboard_ps2_tg_ami_device; -extern const device_t keyboard_ps2_tg_ami_green_device; -extern const device_t keyboard_ps2_pci_device; -extern const device_t keyboard_ps2_ami_pci_device; -extern const device_t keyboard_ps2_intel_ami_pci_device; -extern const device_t keyboard_ps2_acer_pci_device; -extern const device_t keyboard_ps2_ali_pci_device; -extern const device_t keyboard_ps2_phoenix_pci_device; -extern const device_t keyboard_ps2_tg_ami_pci_device; +extern const device_t kbc_pc_device; +extern const device_t kbc_pc82_device; +extern const device_t kbc_pravetz_device; +extern const device_t kbc_xt_device; +extern const device_t kbc_xt86_device; +extern const device_t kbc_xt_compaq_device; +extern const device_t kbc_xt_t1x00_device; +extern const device_t kbc_tandy_device; +extern const device_t kbc_xt_lxt3_device; +extern const device_t kbc_xt_olivetti_device; +extern const device_t kbc_xt_zenith_device; +extern const device_t kbc_xt_hyundai_device; +extern const device_t kbc_xt_fe2010_device; +extern const device_t kbc_xtclone_device; +extern const device_t kbc_at_device; +extern const device_t kbc_at_ami_device; +extern const device_t kbc_at_compaq_device; +extern const device_t kbc_at_phoenix_device; +extern const device_t kbc_at_ncr_device; +extern const device_t kbc_at_olivetti_device; +extern const device_t kbc_at_siemens_device; +extern const device_t kbc_at_tg_ami_device; +extern const device_t kbc_at_toshiba_device; +extern const device_t kbc_ps2_device; +extern const device_t kbc_ps2_ps1_device; +extern const device_t kbc_ps2_ps1_pci_device; +extern const device_t kbc_ps2_xi8088_device; +extern const device_t kbc_ps2_ami_device; +extern const device_t kbc_ps2_compaq_device; +extern const device_t kbc_ps2_holtek_device; +extern const device_t kbc_ps2_mca_1_device; +extern const device_t kbc_ps2_mca_2_device; +extern const device_t kbc_ps2_olivetti_device; +extern const device_t kbc_ps2_phoenix_device; +extern const device_t kbc_ps2_quadtel_device; +extern const device_t kbc_ps2_tg_ami_device; +extern const device_t kbc_ps2_tg_ami_green_device; +extern const device_t kbc_ps2_pci_device; +extern const device_t kbc_ps2_ami_pci_device; +extern const device_t kbc_ps2_intel_ami_pci_device; +extern const device_t kbc_ps2_acer_pci_device; +extern const device_t kbc_ps2_ali_pci_device; +extern const device_t kbc_ps2_phoenix_pci_device; +extern const device_t kbc_ps2_tg_ami_pci_device; +extern const device_t keyboard_pc_xt_device; +extern const device_t keyboard_at_device; +extern const device_t keyboard_ax_device; +extern const device_t keyboard_ps2_device; +extern const device_t keyboard_ps55_device; extern const device_t keyboard_at_generic_device; #endif /*EMU_DEVICE_H*/ @@ -273,9 +303,11 @@ extern void keyboard_process(void); extern uint16_t keyboard_convert(int ch); extern void keyboard_input(int down, uint16_t scan); extern void keyboard_all_up(void); -extern void keyboard_update_states(uint8_t cl, uint8_t nl, uint8_t sl); +extern void keyboard_update_states(uint8_t cl, uint8_t nl, uint8_t sl, uint8_t kl); extern uint8_t keyboard_get_shift(void); -extern void keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl); +extern void keyboard_set_in_reset(uint8_t in_reset); +extern uint8_t keyboard_get_in_reset(void); +extern void keyboard_get_states(uint8_t *cl, uint8_t *nl, uint8_t *sl, uint8_t *kl); extern void keyboard_set_states(uint8_t cl, uint8_t nl, uint8_t sl); extern int keyboard_recv(uint16_t key); extern int keyboard_recv_ui(uint16_t key); @@ -285,11 +317,15 @@ extern int keyboard_isfsexit(void); extern int keyboard_isfsexit_up(void); extern void keyboard_set_is_amstrad(int ams); extern void kbc_at_set_ps2(void *priv, uint8_t ps2); +extern uint8_t kbc_at_read_p(void *priv, uint8_t port, uint8_t mask); extern void kbc_at_write_p(void *priv, uint8_t port, uint8_t mask, uint8_t val); extern void kbc_at_set_fast_reset(uint8_t new_fast_reset); -extern void kbc_at_handler(int set, void *priv); +extern void kbc_at_port_handler(int num, int set, uint16_t port, void *priv); +extern void kbc_at_handler(int set, uint16_t port, void *priv); +extern void kbc_at_set_irq(int num, uint16_t irq, void *priv); +extern void kbc_at_dev_queue_reset(atkbc_dev_t *dev, uint8_t reset_main); extern uint8_t kbc_at_dev_queue_pos(atkbc_dev_t *dev, uint8_t main); extern void kbc_at_dev_queue_add(atkbc_dev_t *dev, uint8_t val, uint8_t main); extern void kbc_at_dev_reset(atkbc_dev_t *dev, int do_fa); @@ -298,6 +334,18 @@ extern atkbc_dev_t *kbc_at_dev_init(uint8_t inst); passed on incorrectly. */ extern uint16_t convert_scan_code(uint16_t scan_code); +extern const char * keyboard_get_name(int mouse); +extern const char * keyboard_get_internal_name(int mouse); +extern int keyboard_get_from_internal_name(char *s); +extern int keyboard_has_config(int mouse); +#ifdef EMU_DEVICE_H +extern const device_t *keyboard_get_device(int mouse); +#endif +extern int keyboard_get_ndev(void); +extern void keyboard_add_device(void); + +extern const scancode scancode_set1[512]; + #ifdef __cplusplus } #endif diff --git a/src/include/86box/lpt.h b/src/include/86box/lpt.h index 674d6340f..4e3adf406 100644 --- a/src/include/86box/lpt.h +++ b/src/include/86box/lpt.h @@ -17,87 +17,130 @@ #define LPT6_IRQ 5 #endif -typedef struct lpt_device_t { - const char *name; - const char *internal_name; +typedef struct lpt_device_s { + const char *name; + const char *internal_name; - void *(*init)(void *lpt); - void (*close)(void *priv); - void (*write_data)(uint8_t val, void *priv); - void (*write_ctrl)(uint8_t val, void *priv); - uint8_t (*read_data)(void *priv); - uint8_t (*read_status)(void *priv); - uint8_t (*read_ctrl)(void *priv); + void *(*init)(void *lpt); + void (*close)(void *priv); + void (*write_data)(uint8_t val, void *priv); + void (*write_ctrl)(uint8_t val, void *priv); + void (*autofeed)(uint8_t val,void *priv); + void (*strobe)(uint8_t old, uint8_t val,void *priv); + uint8_t (*read_status)(void *priv); + uint8_t (*read_ctrl)(void *priv); + void (*epp_write_data)(uint8_t is_addr, uint8_t val, void *priv); + void (*epp_request_read)(uint8_t is_addr, void *priv); + + void *priv; + struct lpt_t *lpt; +//#ifdef EMU_DEVICE_H +// struct device_t *cfgdevice; +//#else + void *cfgdevice; +//#endif } lpt_device_t; -extern void lpt_init(void); -extern void lpt_port_setup(int i, uint16_t port); -extern void lpt_port_irq(int i, uint8_t irq); -extern void lpt_port_remove(int i); -extern void lpt1_remove_ams(void); - -#define lpt1_setup(a) lpt_port_setup(0, a) -#define lpt1_irq(a) lpt_port_irq(0, a) -#define lpt1_remove() lpt_port_remove(0) - -#define lpt2_setup(a) lpt_port_setup(1, a) -#define lpt2_irq(a) lpt_port_irq(1, a) -#define lpt2_remove() lpt_port_remove(1) - -#define lpt3_setup(a) lpt_port_setup(2, a) -#define lpt3_irq(a) lpt_port_irq(2, a) -#define lpt3_remove() lpt_port_remove(2) - -#define lpt4_setup(a) lpt_port_setup(3, a) -#define lpt4_irq(a) lpt_port_irq(3, a) -#define lpt4_remove() lpt_port_remove(3) - -#if 0 -#define lpt5_setup(a) lpt_port_setup(4, a) -#define lpt5_irq(a) lpt_port_irq(4, a) -#define lpt5_remove() lpt_port_remove(4) - -#define lpt6_setup(a) lpt_port_setup(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 lpt_port_t { +#ifdef _TIMER_H_ +typedef struct lpt_t { uint8_t enabled; uint8_t irq; + uint8_t irq_state; + uint8_t dma; uint8_t dat; uint8_t ctrl; + uint8_t ext; + uint8_t epp; + uint8_t ecp; + uint8_t ecr; + uint8_t in_dat; + uint8_t fifo_stat; + uint8_t dma_stat; + uint8_t state; + uint8_t autofeed; + uint8_t strobe; + uint8_t lv2; + uint8_t cnfga_readout; + uint8_t inst; + uint8_t pad[5]; uint16_t addr; - uint16_t pad0; - int device; + uint16_t id; + uint16_t pad0[2]; int enable_irq; lpt_device_t *dt; - void *priv; +#ifdef FIFO_H + fifo16_t * fifo; +#else + void * fifo; +#endif + + pc_timer_t fifo_out_timer; +} lpt_t; +#endif /* _TIMER_H_ */ + +typedef struct lpt_port_s { + uint8_t enabled; + + int device; } lpt_port_t; 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); +typedef enum { + LPT_STATE_IDLE = 0, + LPT_STATE_READ_DMA, + LPT_STATE_WRITE_FIFO +} lpt_state_t; -extern uint8_t lpt_read_port(int port, uint16_t reg); +extern void lpt_write(uint16_t port, uint8_t val, void *priv); -extern uint8_t lpt_read_status(int port); -extern void lpt_irq(void *priv, int raise); +extern void lpt_write_to_fifo(void *priv, uint8_t val); -extern const char *lpt_device_get_name(int id); -extern const char *lpt_device_get_internal_name(int id); +extern uint8_t lpt_read(uint16_t port, void *priv); -extern int lpt_device_get_from_internal_name(char *s); +extern uint8_t lpt_read_port(lpt_t *dev, uint16_t reg); -extern const lpt_device_t lpt_dac_device; -extern const lpt_device_t lpt_dac_stereo_device; +extern uint8_t lpt_read_status(lpt_t *dev); +extern void lpt_irq(void *priv, int raise); -extern const lpt_device_t dss_device; +extern int lpt_device_get_from_internal_name(const char *str); -extern const lpt_device_t lpt_hasp_savquest_device; +extern const char *lpt_device_get_name(int id); +extern const char *lpt_device_get_internal_name(int id); + +#ifdef EMU_DEVICE_H +extern const device_t *lpt_device_getdevice(const int id); +#endif + +extern int lpt_device_has_config(const int id); + +extern const lpt_device_t lpt_dac_device; +extern const lpt_device_t lpt_dac_stereo_device; + +extern const lpt_device_t dss_device; + +extern const lpt_device_t lpt_hasp_savquest_device; + +extern void lpt_set_ext(lpt_t *dev, uint8_t ext); +extern void lpt_set_ecp(lpt_t *dev, uint8_t ecp); +extern void lpt_set_epp(lpt_t *dev, uint8_t epp); +extern void lpt_set_lv2(lpt_t *dev, uint8_t lv2); +extern void lpt_set_fifo_threshold(lpt_t *dev, int threshold); +extern void lpt_set_cnfga_readout(lpt_t *dev, const uint8_t cnfga_readout); +extern void lpt_port_setup(lpt_t *dev, uint16_t port); +extern void lpt_port_irq(lpt_t *dev, uint8_t irq); +extern void lpt_port_dma(lpt_t *dev, uint8_t dma); +extern void lpt_port_remove(lpt_t *dev); +extern void lpt1_remove_ams(lpt_t *dev); + +extern void lpt_devices_init(void); +extern void lpt_devices_close(void); + +extern void lpt_set_next_inst(int ni); +extern void lpt_set_3bc_used(int is_3bc_used); + +extern void lpt_standalone_init(void); + +extern const device_t lpt_port_device; #endif /*EMU_LPT_H*/ diff --git a/src/include/86box/m_pcjr.h b/src/include/86box/m_pcjr.h new file mode 100644 index 000000000..c6cb33588 --- /dev/null +++ b/src/include/86box/m_pcjr.h @@ -0,0 +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. + * + * Header files for the PCjr keyboard and video subsystems. + * + * + * + * Authors: Connor Hyde, + * + * Copyright 2025 starfrost + */ + +#pragma once + +#define PCJR_RGB 0 +#define PCJR_COMPOSITE 1 +#define PCJR_RGB_NO_BROWN 4 +#define PCJR_RGB_IBM_5153 5 + +typedef struct pcjr_s +{ + /* Video Controller stuff. */ + mem_mapping_t mapping; + uint8_t crtc[32]; + int crtcreg; + int array_index; + uint8_t array[32]; + int array_ff; + int memctrl; + uint8_t status; + int addr_mode; + uint8_t *vram; + uint8_t *b8000; + int linepos; + int displine; + int scanline; + int vc; + int dispon; + int cursorvisible; // Is the cursor visible on the current scanline? + int cursoron; + int blink; + int vsynctime; + int fullchange; + int vadj; + uint16_t memaddr; + uint16_t memaddr_backup; + uint64_t dispontime; + uint64_t dispofftime; + pc_timer_t timer; + int firstline; + int lastline; + int composite; + int apply_hd; + + /* Keyboard Controller stuff. */ + int latched; + int data; + int serial_data[44]; + int serial_pos; + uint8_t pa; + uint8_t pb; + pc_timer_t send_delay_timer; + +} pcjr_t; + +void pcjr_recalc_timings(pcjr_t *pcjr); + +// Note: This is a temporary solution until the pcjr video is made its own gfx card +void pcjr_vid_init(pcjr_t *pcjr); \ No newline at end of file diff --git a/src/include/86box/m_tandy.h b/src/include/86box/m_tandy.h new file mode 100644 index 000000000..2d0100c1a --- /dev/null +++ b/src/include/86box/m_tandy.h @@ -0,0 +1,95 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header files for the Tandy keyboard and video subsystems. + * + * + * + * Authors: Connor Hyde, + * + * Copyright 2025 starfrost + */ + +typedef struct t1kvid_t { + mem_mapping_t mapping; + mem_mapping_t vram_mapping; + + uint8_t crtc[32]; + int crtcreg; + + int array_index; + uint8_t array[256]; + int memctrl; + uint8_t mode; + uint8_t col; + uint8_t status; + + uint8_t *vram; + uint8_t *b8000; + uint32_t b8000_mask; + uint32_t b8000_limit; + uint8_t planar_ctrl; + uint8_t lp_strobe; + + int linepos; + int displine; + int scanline; + int vc; + int dispon; + int cursorvisible; + int cursoron; + int blink; + int fullchange; + int vsynctime; + int vadj; + uint16_t memaddr; + uint16_t memaddr_backup; + + uint64_t dispontime; + uint64_t dispofftime; + pc_timer_t timer; + int firstline; + int lastline; + + int composite; +} t1kvid_t; + +typedef struct t1keep_t { + char *path; + + int state; + int count; + int addr; + int clk; + uint16_t data; + uint16_t store[64]; +} t1keep_t; + +typedef struct tandy_t { + mem_mapping_t ram_mapping; + mem_mapping_t rom_mapping; /* SL2 */ + + uint8_t *rom; /* SL2 */ + uint8_t ram_bank; + uint8_t rom_bank; /* SL2 */ + int rom_offset; /* SL2 */ + + uint32_t base; + uint32_t mask; + int is_hx; + int is_sl2; + + t1kvid_t *vid; +} tandy_t; + +void tandy_vid_init(tandy_t* dev); +uint8_t tandy_vid_in(uint16_t addr, void* priv); +void tandy_vid_out(uint16_t addr, uint8_t val, void *priv); + +void tandy_vid_close(void* priv); +void tandy_recalc_address_sl(tandy_t* dev); //this function is needed by both m_ and vid_tandy.c diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 4469b55c2..9e14f0656 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -85,27 +85,28 @@ #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_PS2_KBC 0x00000400 /* sys has a PS/2 keyboard controller */ +#define MACHINE_VIDEO_ONLY 0x00000008 /* sys has fixed video */ +#define MACHINE_KEYBOARD 0x00000010 /* sys has int keyboard */ +#define MACHINE_AX 0x00000020 /* sys adheres to Japanese AX standard */ +#define MACHINE_KEYBOARD_JIS 0x00000020 /* sys has int keyboard which is Japanese (AX or PS/55) */ +#define MACHINE_MOUSE 0x00000040 /* sys has int mouse */ +#define MACHINE_FDC 0x00000080 /* sys has int FDC */ +#define MACHINE_LPT_PRI 0x00000100 /* sys has int pri LPT */ +#define MACHINE_LPT_SEC 0x00000200 /* sys has int sec LPT */ +#define MACHINE_LPT_TER 0x00000400 /* sys has int ter LPT */ +#define MACHINE_PS2_KBC 0x00000800 /* sys has a PS/2 keyboard controller */ /* this is separate from having PS/2 ports */ -#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 */ +#define MACHINE_UART_PRI 0x00010800 /* sys has int pri UART */ +#define MACHINE_UART_SEC 0x00002000 /* sys has int sec UART */ +#define MACHINE_UART_TER 0x00004000 /* sys has int ter UART */ +#define MACHINE_UART_QUA 0x00008000 /* sys has int qua UART */ +#define MACHINE_GAMEPORT 0x00010000 /* sys has int game port */ +#define MACHINE_SOUND 0x00020000 /* sys has int sound */ +#define MACHINE_NIC 0x00040000 /* sys has int NIC */ /* Feature flags for advanced devices. */ #define MACHINE_APM 0x00080000 /* sys has APM */ #define MACHINE_ACPI 0x00100000 /* sys has ACPI */ -#define MACHINE_HWM 0x00200000 /* sys has hw monitor */ +#define MACHINE_PCI_INTERNAL 0x00200000 /* sys has only internal PCI */ #define MACHINE_CARTRIDGE 0x00400000 /* sys has cartridge bays */ /* Feature flags for internal storage controllers. */ #define MACHINE_MFM 0x00800000 /* sys has int MFM/RLL */ @@ -197,6 +198,7 @@ enum { MACHINE_CHIPSET_GC100A, MACHINE_CHIPSET_GC103, MACHINE_CHIPSET_HT18, + MACHINE_CHIPSET_ACC_2036, MACHINE_CHIPSET_ACC_2168, MACHINE_CHIPSET_ALI_M1217, MACHINE_CHIPSET_ALI_M6117, @@ -211,6 +213,7 @@ enum { MACHINE_CHIPSET_SCAT_SX, MACHINE_CHIPSET_NEAT, MACHINE_CHIPSET_NEAT_SX, + MACHINE_CHIPSET_CT_AT, MACHINE_CHIPSET_CT_386, MACHINE_CHIPSET_CT_CS4031, MACHINE_CHIPSET_CONTAQ_82C596, @@ -239,7 +242,9 @@ enum { MACHINE_CHIPSET_OPTI_391, MACHINE_CHIPSET_OPTI_481, MACHINE_CHIPSET_OPTI_493, - MACHINE_CHIPSET_OPTI_495, + MACHINE_CHIPSET_OPTI_495SLC, + MACHINE_CHIPSET_OPTI_495SX, + MACHINE_CHIPSET_OPTI_498, MACHINE_CHIPSET_OPTI_499, MACHINE_CHIPSET_OPTI_895_802G, MACHINE_CHIPSET_OPTI_547_597, @@ -334,6 +339,7 @@ typedef struct _machine_ { uint32_t gpio_acpi; #ifdef EMU_DEVICE_H const device_t *device; + const device_t *kbd_device; const device_t *fdc_device; const device_t *sio_device; const device_t *vid_device; @@ -341,6 +347,7 @@ typedef struct _machine_ { const device_t *net_device; #else void *device; + void *kbd_device; void *fdc_device; void *sio_device; void *vid_device; @@ -385,6 +392,7 @@ 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 int machine_get_chipset(int m); extern void machine_close(void); extern int machine_has_mouse(void); extern int machine_is_sony(void); @@ -446,9 +454,6 @@ extern int machine_at_pb286_init(const machine_t *); extern int machine_at_siemens_init(const machine_t *); // Siemens PCD-2L. N82330 discrete machine. It segfaults in some places extern int machine_at_wellamerastar_init(const machine_t *); // Wells American A*Star with custom award BIOS -#ifdef USE_OPEN_AT -extern int machine_at_openat_init(const machine_t *); -#endif /* USE_OPEN_AT */ /* m_at_286_386sx.c */ extern int machine_at_tg286m_init(const machine_t *); @@ -457,6 +462,7 @@ extern int machine_at_px286_init(const machine_t *); extern int machine_at_quadt286_init(const machine_t *); extern int machine_at_mr286_init(const machine_t *); +extern int machine_at_pbl300sx_init(const machine_t *); extern int machine_at_neat_init(const machine_t *); extern int machine_at_neat_ami_init(const machine_t *); extern int machine_at_ataripc4_init(const machine_t *); @@ -466,6 +472,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_drsm35286_init(const machine_t *); extern int machine_at_senor_scat286_init(const machine_t *); extern int machine_at_super286c_init(const machine_t *); extern int machine_at_super286tr_init(const machine_t *); @@ -475,18 +482,21 @@ extern int machine_at_spc4620p_init(const machine_t *); extern int machine_at_kmxc02_init(const machine_t *); extern int machine_at_deskmaster286_init(const machine_t *); +extern int machine_at_dells200_init(const machine_t *); +extern int machine_at_at122_init(const machine_t *); +extern int machine_at_tuliptc7_init(const machine_t *); + extern int machine_at_pc8_init(const machine_t *); extern int machine_at_3302_init(const machine_t *); -#ifdef USE_OLIVETTI extern int machine_at_m290_init(const machine_t *); -#endif /* USE_OLIVETTI */ extern int machine_at_shuttle386sx_init(const machine_t *); extern int machine_at_adi386sx_init(const machine_t *); extern int machine_at_cmdsl386sx16_init(const machine_t *); extern int machine_at_cmdsl386sx25_init(const machine_t *); extern int machine_at_dataexpert386sx_init(const machine_t *); +extern int machine_at_dells333sl_init(const machine_t *); extern int machine_at_if386sx_init(const machine_t *); extern int machine_at_spc6033p_init(const machine_t *); extern int machine_at_wd76c10_init(const machine_t *); @@ -508,15 +518,19 @@ extern int machine_at_pc916sx_init(const machine_t *); sure this appear here (and in the .c file) in the order and position in which they appear in the machine table. */ extern int machine_at_dataexpert386wb_init(const machine_t *); +extern int machine_at_isa486c_init(const machine_t *); extern int machine_at_genoa486_init(const machine_t *); extern int machine_at_ga486l_init(const machine_t *); +extern int machine_at_cobalt_init(const machine_t *); extern int machine_at_cougar_init(const machine_t *); extern int machine_at_acc386_init(const machine_t *); +extern int machine_at_asus3863364k_init(const machine_t *); extern int machine_at_asus386_init(const machine_t *); extern int machine_at_ecs386_init(const machine_t *); extern int machine_at_spc6000a_init(const machine_t *); extern int machine_at_micronics386_init(const machine_t *); +extern int machine_at_micronics386px_init(const machine_t *); extern int machine_at_ecs386v_init(const machine_t *); extern int machine_at_tandy4000_init(const machine_t *); @@ -529,6 +543,8 @@ extern int machine_at_cs4031_init(const machine_t *); extern int machine_at_pb410a_init(const machine_t *); extern int machine_at_decpclpv_init(const machine_t *); +extern int machine_at_dell466np_init(const machine_t *); + extern int machine_at_acerv10_init(const machine_t *); extern int machine_at_acera1g_init(const machine_t *); @@ -538,10 +554,13 @@ extern int machine_at_winbios1429_init(const machine_t *); extern int machine_at_opti495_init(const machine_t *); extern int machine_at_opti495_ami_init(const machine_t *); extern int machine_at_opti495_mr_init(const machine_t *); +extern int machine_at_c747_init(const machine_t *); extern int machine_at_exp4349_init(const machine_t *); extern int machine_at_vect486vl_init(const machine_t *); extern int machine_at_d824_init(const machine_t *); +extern int machine_at_tuliptc38_init(const machine_t *); +extern int machine_at_martin_init(const machine_t *); extern int machine_at_403tg_init(const machine_t *); extern int machine_at_403tg_d_init(const machine_t *); @@ -552,9 +571,11 @@ extern int machine_at_aptiva510_init(const machine_t *); extern int machine_at_pc330_6573_init(const machine_t *); extern int machine_at_mvi486_init(const machine_t *); +extern int machine_at_dtk461_init(const machine_t *); extern int machine_at_sis401_init(const machine_t *); extern int machine_at_isa486_init(const machine_t *); extern int machine_at_av4_init(const machine_t *); +extern int machine_at_advantage40xxd_init(const machine_t *); extern int machine_at_valuepoint433_init(const machine_t *); extern int machine_at_vli486sv2g_init(const machine_t *); @@ -583,6 +604,7 @@ extern int machine_at_sb486p_init(const machine_t *); extern int machine_at_486sp3_init(const machine_t *); extern int machine_at_486sp3c_init(const machine_t *); extern int machine_at_486sp3g_init(const machine_t *); +extern int machine_at_sb486pv_init(const machine_t *); extern int machine_at_486ap4_init(const machine_t *); extern int machine_at_g486vpa_init(const machine_t *); extern int machine_at_486vipio2_init(const machine_t *); @@ -603,6 +625,7 @@ extern int machine_at_iach488_init(const machine_t *); extern int machine_at_pcm9340_init(const machine_t *); extern int machine_at_pcm5330_init(const machine_t *); +extern int machine_at_84xxuuda_init(const machine_t *); extern int machine_at_ecs486_init(const machine_t *); extern int machine_at_hot433a_init(const machine_t *); extern int machine_at_pl4600c_init(const machine_t *); @@ -635,6 +658,7 @@ extern void machine_at_award_common_init(const machine_t *); extern void machine_at_sp4_common_init(const machine_t *model); +extern int machine_at_v12p_init(const machine_t *); extern int machine_at_excaliburpci_init(const machine_t *); extern int machine_at_p5mp3_init(const machine_t *); extern int machine_at_dellxp60_init(const machine_t *); @@ -657,6 +681,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_d842_init(const machine_t *); extern int machine_at_ambradp90_init(const machine_t *); extern int machine_at_p54np4_init(const machine_t *); extern int machine_at_586ip_init(const machine_t *); @@ -664,6 +689,7 @@ extern int machine_at_tek932_init(const machine_t *); extern int machine_at_acerv30_init(const machine_t *); extern int machine_at_apollo_init(const machine_t *); +extern int machine_at_optiplexgxl_init(const machine_t *); extern int machine_at_zappa_init(const machine_t *); extern int machine_at_powermatev_init(const machine_t *); extern int machine_at_hawk_init(const machine_t *); @@ -700,6 +726,7 @@ extern int machine_at_fmb_init(const machine_t *); extern int machine_at_acerm3a_init(const machine_t *); extern int machine_at_ap53_init(const machine_t *); extern int machine_at_8500tuc_init(const machine_t *); +extern int machine_at_d943_init(const machine_t *); extern int machine_at_p55t2s_init(const machine_t *); extern int machine_at_p5vxb_init(const machine_t *); @@ -714,6 +741,8 @@ extern int machine_at_vectra54_init(const machine_t *); extern int machine_at_5sbm2_init(const machine_t *); /* m_at_socket7.c */ +extern void machine_at_optiplex_21152_init(void); + extern int machine_at_acerv35n_init(const machine_t *); extern int machine_at_p55t2p4_init(const machine_t *); extern int machine_at_m7shi_init(const machine_t *); @@ -743,11 +772,10 @@ extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_ma23c_init(const machine_t *); extern int machine_at_nupro592_init(const machine_t *); extern int machine_at_tx97_init(const machine_t *); -#ifdef USE_AN430TX -extern int machine_at_an430tx_init(const machine_t *); -#endif /* USE_AN430TX */ +extern int machine_at_optiplexgn_init(const machine_t *); extern int machine_at_ym430tx_init(const machine_t *); extern int machine_at_thunderbolt_init(const machine_t *); +extern int machine_at_an430tx_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 *); @@ -764,6 +792,7 @@ extern int machine_at_ms5146_init(const machine_t *); extern int machine_at_cb52xsi_init(const machine_t *); extern int machine_at_m560_init(const machine_t *); +extern int machine_at_m5ata_init(const machine_t *); extern int machine_at_ms5164_init(const machine_t *); extern int machine_at_sp97xv_init(const machine_t *); @@ -782,6 +811,7 @@ extern int machine_at_ax59pro_init(const machine_t *); extern int machine_at_mvp3_init(const machine_t *); extern int machine_at_ficva503a_init(const machine_t *); extern int machine_at_5emapro_init(const machine_t *); +extern int machine_at_delhi3_init(const machine_t *); extern int machine_at_5sg100_init(const machine_t *); @@ -793,6 +823,7 @@ extern int machine_at_686nx_init(const machine_t *); extern int machine_at_acerv60n_init(const machine_t *); extern int machine_at_lgibmx61_init(const machine_t *); extern int machine_at_vs440fx_init(const machine_t *); +extern int machine_at_dellvenus_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 *); @@ -806,12 +837,13 @@ extern int machine_at_p65up5_cp6nd_init(const machine_t *); /* m_at_slot1.c */ extern int machine_at_m729_init(const machine_t *); +extern int machine_at_acerv62x_init(const machine_t *); extern int machine_at_p65up5_cpknd_init(const machine_t *); extern int machine_at_kn97_init(const machine_t *); extern int machine_at_lx6_init(const machine_t *); +extern int machine_at_optiplexgxa_init(const machine_t *); extern int machine_at_spitfire_init(const machine_t *); - extern int machine_at_ma30d_init(const machine_t *); extern int machine_at_p6i440e2_init(const machine_t *); @@ -889,6 +921,9 @@ extern int machine_xt_m19_init(const machine_t *); /* m_pcjr.c */ extern int machine_pcjr_init(const machine_t *); +/* m_pc5086.c */ +extern int machine_pc5086_init(const machine_t *); + /* m_ps1.c */ extern int machine_ps1_m2011_init(const machine_t *); extern int machine_ps1_m2121_init(const machine_t *); @@ -955,6 +990,7 @@ extern int machine_xt_kaypropc_init(const machine_t *); extern int machine_xt_sansx16_init(const machine_t *); extern int machine_xt_bw230_init(const machine_t *); extern int machine_xt_pb8810_init(const machine_t *); +extern int machine_xt_tuliptc8_init(const machine_t *); extern int machine_xt_v20xt_init(const machine_t *); @@ -969,10 +1005,14 @@ extern int machine_xt_compaq_deskpro_init(const machine_t *); extern int machine_xt_compaq_portable_init(const machine_t *); /* m_xt_laserxt.c */ -#ifdef USE_LASERXT extern int machine_xt_laserxt_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t laserxt_device; +#endif extern int machine_xt_lxt3_init(const machine_t *); -#endif /* USE_LASERXT */ +#ifdef EMU_DEVICE_H +extern const device_t lxt3_device; +#endif /* m_xt_philips.c */ extern int machine_xt_p3105_init(const machine_t *); diff --git a/src/include/86box/machine_status.h b/src/include/86box/machine_status.h index e6e9e6acd..c5640ac08 100644 --- a/src/include/86box/machine_status.h +++ b/src/include/86box/machine_status.h @@ -5,6 +5,7 @@ typedef struct dev_status_empty_active_t { atomic_bool_t empty; atomic_bool_t active; atomic_bool_t write_active; + atomic_bool_t write_prot; } dev_status_empty_active_t; typedef struct dev_status_active_t { @@ -19,7 +20,7 @@ typedef struct dev_status_empty_t { typedef struct machine_status_t { dev_status_empty_active_t fdd[FDD_NUM]; dev_status_empty_active_t cdrom[CDROM_NUM]; - dev_status_empty_active_t zip[ZIP_NUM]; + dev_status_empty_active_t rdisk[RDISK_NUM]; dev_status_empty_active_t mo[MO_NUM]; dev_status_empty_active_t cassette; dev_status_active_t hdd[HDD_BUS_USB]; diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index f8d0f659a..8710fca51 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -265,12 +265,16 @@ extern uint32_t biosmask; extern uint32_t biosaddr; extern int readlookup[256]; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) extern uintptr_t *readlookup2; +#endif extern uintptr_t old_rl2; extern uint8_t uncached; extern int readlnext; extern int writelookup[256]; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) extern uintptr_t *writelookup2; +#endif extern int writelnext; extern uint32_t ram_mapped_addr[64]; extern uint8_t page_ff[4096]; @@ -288,7 +292,16 @@ extern mem_mapping_t bios_high_mapping; extern uint32_t mem_logical_addr; extern page_t *pages; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) extern page_t **page_lookup; +#endif + +#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +/* The lookup tables. */ +extern page_t *page_lookup[1048576]; +extern uintptr_t readlookup2[1048576]; +extern uintptr_t writelookup2[1048576]; +#endif extern uint32_t get_phys_virt; extern uint32_t get_phys_phys; @@ -300,7 +313,6 @@ extern int writelnum; extern int memspeed[11]; -extern int mmu_perm; extern uint8_t high_page; /* if a high (> 4 gb) page was detected */ extern uint8_t *_mem_exec[MEM_MAPPINGS_NO]; @@ -458,6 +470,9 @@ extern void mem_a20_init(void); extern void mem_a20_recalc(void); extern void mem_init(void); +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) +extern void mem_free(void); +#endif extern void mem_close(void); extern void mem_zero(void); extern void mem_reset(void); @@ -468,6 +483,8 @@ extern void mem_remap_top_nomid(int kb); extern void umc_smram_recalc(uint32_t start, int set); +extern void pcjr_waitstates(void *); + extern mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; extern mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; diff --git a/src/include/86box/mo.h b/src/include/86box/mo.h index f4e7e9809..6d308adb8 100644 --- a/src/include/86box/mo.h +++ b/src/include/86box/mo.h @@ -84,10 +84,11 @@ static const mo_drive_type_t mo_drive_types[KNOWN_MO_DRIVE_TYPES] = { }; enum { - MO_BUS_DISABLED = 0, - MO_BUS_ATAPI = 5, - MO_BUS_SCSI = 6, - MO_BUS_USB = 7 + MO_BUS_DISABLED = 0, + MO_BUS_LPT = 6, + MO_BUS_ATAPI = 8, + MO_BUS_SCSI = 9, + MO_BUS_USB = 10 }; typedef struct mo_drive_t { @@ -110,13 +111,13 @@ typedef struct mo_drive_t { uint8_t pad; uint8_t pad0; - FILE * fp; - void * priv; + FILE *fp; + void *priv; char image_path[1024]; char prev_image_path[1024]; - char * image_history[MO_IMAGE_HISTORY]; + char *image_history[MO_IMAGE_HISTORY]; uint32_t type; uint32_t medium_size; @@ -129,16 +130,16 @@ typedef struct mo_drive_t { typedef struct mo_t { mode_sense_pages_t ms_pages_saved; - mo_drive_t * drv; + mo_drive_t *drv; #ifdef EMU_IDE_H - ide_tf_t * tf; + ide_tf_t *tf; #else - void * tf; + void *tf; #endif void * log; - uint8_t * buffer; + uint8_t *buffer; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; diff --git a/src/include/86box/mouse.h b/src/include/86box/mouse.h index 8dd3bad2d..d3e33ad32 100644 --- a/src/include/86box/mouse.h +++ b/src/include/86box/mouse.h @@ -26,7 +26,7 @@ #endif #define MOUSE_TYPE_NONE 0 /* no mouse configured */ -#define MOUSE_TYPE_INTERNAL 1 /* achine has internal mouse */ +#define MOUSE_TYPE_INTERNAL 1 /* machine has internal mouse */ #define MOUSE_TYPE_LOGIBUS 2 /* Logitech/ATI Bus Mouse */ #define MOUSE_TYPE_INPORT 3 /* Microsoft InPort Mouse */ #if 0 @@ -42,7 +42,10 @@ #define MOUSE_TYPE_WACOM 12 /* WACOM tablet */ #define MOUSE_TYPE_WACOMARTP 13 /* WACOM tablet (ArtPad) */ #define MOUSE_TYPE_MSYSTEMSB 14 /* Mouse Systems bus mouse */ +#define MOUSE_TYPE_MSBPOINT 15 /* Microsoft Serial BallPoint mouse */ +#define MOUSE_TYPE_PS2_QPORT 27 /* PS/2 QuickPort series Bus Mouse */ +#define MOUSE_TYPE_QPORT 0x40 /* Mouse is an on-board version of one of the above. */ #define MOUSE_TYPE_ONBOARD 0x80 /* Mouse is an on-board version of one of the above. */ @@ -71,8 +74,11 @@ extern const device_t mouse_genibus_device; extern const device_t mouse_mssystems_device; extern const device_t mouse_mssystems_bus_device; extern const device_t mouse_msserial_device; +extern const device_t mouse_msserial_ballpoint_device; extern const device_t mouse_ltserial_device; extern const device_t mouse_ps2_device; +extern const device_t mouse_upc_device; +extern const device_t mouse_upc_standalone_device; # ifdef USE_WACOM extern const device_t mouse_wacom_device; extern const device_t mouse_wacom_artpad_device; @@ -129,6 +135,11 @@ extern void mouse_init(void); extern void mouse_bus_set_irq(void *priv, int irq); +extern void mouse_upc_port_handler(int num, int set, uint16_t port, void *priv); +extern void mouse_upc_handler(int set, uint16_t port, void *priv); + +extern void mouse_upc_set_irq(int num, uint16_t irq, void *priv); + #ifdef __cplusplus } #endif diff --git a/src/include/86box/net_dp8390.h b/src/include/86box/net_dp8390.h index 553366808..0b1cc45f5 100644 --- a/src/include/86box/net_dp8390.h +++ b/src/include/86box/net_dp8390.h @@ -41,89 +41,89 @@ typedef struct dp8390_t { /* Command Register - 00h read/write */ struct CR_t { - int stop; /* STP - Software Reset command */ - int start; /* START - start the NIC */ - int tx_packet; /* TXP - initiate packet transmission */ + bool stop; /* STP - Software Reset command */ + bool start; /* START - start the NIC */ + bool tx_packet; /* TXP - initiate packet transmission */ uint8_t rdma_cmd; /* RD0,RD1,RD2 - Remote DMA command */ uint8_t pgsel; /* PS0,PS1 - Page select */ } CR; /* Interrupt Status Register - 07h read/write */ struct ISR_t { - int pkt_rx; /* PRX - packet received with no errors */ - int pkt_tx; /* PTX - packet txed with no errors */ - int rx_err; /* RXE - packet rxed with 1 or more errors */ - int tx_err; /* TXE - packet txed " " " " " */ - int overwrite; /* OVW - rx buffer resources exhausted */ - int cnt_oflow; /* CNT - network tally counter MSB's set */ - int rdma_done; /* RDC - remote DMA complete */ - int reset; /* RST - reset status */ + bool pkt_rx; /* PRX - packet received with no errors */ + bool pkt_tx; /* PTX - packet txed with no errors */ + bool rx_err; /* RXE - packet rxed with 1 or more errors */ + bool tx_err; /* TXE - packet txed " " " " " */ + bool overwrite; /* OVW - rx buffer resources exhausted */ + bool cnt_oflow; /* CNT - network tally counter MSB's set */ + bool rdma_done; /* RDC - remote DMA complete */ + bool reset; /* RST - reset status */ } ISR; /* Interrupt Mask Register - 0fh write */ struct IMR_t { - int rx_inte; /* PRXE - packet rx interrupt enable */ - int tx_inte; /* PTXE - packet tx interrput enable */ - int rxerr_inte; /* RXEE - rx error interrupt enable */ - int txerr_inte; /* TXEE - tx error interrupt enable */ - int overw_inte; /* OVWE - overwrite warn int enable */ - int cofl_inte; /* CNTE - counter o'flow int enable */ - int rdma_inte; /* RDCE - remote DMA complete int enable */ - int reserved; /* D7 - reserved */ + bool rx_inte; /* PRXE - packet rx interrupt enable */ + bool tx_inte; /* PTXE - packet tx interrput enable */ + bool rxerr_inte; /* RXEE - rx error interrupt enable */ + bool txerr_inte; /* TXEE - tx error interrupt enable */ + bool overw_inte; /* OVWE - overwrite warn int enable */ + bool cofl_inte; /* CNTE - counter o'flow int enable */ + bool rdma_inte; /* RDCE - remote DMA complete int enable */ + bool reserved; /* D7 - reserved */ } IMR; /* Data Configuration Register - 0eh write */ struct DCR_t { - int wdsize; /* WTS - 8/16-bit select */ - int endian; /* BOS - byte-order select */ - int longaddr; /* LAS - long-address select */ - int loop; /* LS - loopback select */ - int auto_rx; /* AR - auto-remove rx pkts with remote DMA */ + bool wdsize; /* WTS - 8/16-bit select */ + bool endian; /* BOS - byte-order select */ + bool longaddr; /* LAS - long-address select */ + bool loop; /* LS - loopback select */ + bool auto_rx; /* AR - auto-remove rx pkts with remote DMA */ uint8_t fifo_size; /* FT0,FT1 - fifo threshold */ } DCR; /* Transmit Configuration Register - 0dh write */ struct TCR_t { - int crc_disable; /* CRC - inhibit tx CRC */ + bool crc_disable; /* CRC - inhibit tx CRC */ uint8_t loop_cntl; /* LB0,LB1 - loopback control */ - int ext_stoptx; /* ATD - allow tx disable by external mcast */ - int coll_prio; /* OFST - backoff algorithm select */ + bool ext_stoptx; /* ATD - allow tx disable by external mcast */ + bool coll_prio; /* OFST - backoff algorithm select */ uint8_t reserved; /* D5,D6,D7 - reserved */ } TCR; /* Transmit Status Register - 04h read */ struct TSR_t { - int tx_ok; /* PTX - tx complete without error */ - int reserved; /* D1 - reserved */ - int collided; /* COL - tx collided >= 1 times */ - int aborted; /* ABT - aborted due to excessive collisions */ - int no_carrier; /* CRS - carrier-sense lost */ - int fifo_ur; /* FU - FIFO underrun */ - int cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */ - int ow_coll; /* OWC - out-of-window collision */ + bool tx_ok; /* PTX - tx complete without error */ + bool reserved; /* D1 - reserved */ + bool collided; /* COL - tx collided >= 1 times */ + bool aborted; /* ABT - aborted due to excessive collisions */ + bool no_carrier; /* CRS - carrier-sense lost */ + bool fifo_ur; /* FU - FIFO underrun */ + bool cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */ + bool ow_coll; /* OWC - out-of-window collision */ } TSR; /* Receive Configuration Register - 0ch write */ struct RCR_t { - int errors_ok; /* SEP - accept pkts with rx errors */ - int runts_ok; /* AR - accept < 64-byte runts */ - int broadcast; /* AB - accept eth broadcast address */ - int multicast; /* AM - check mcast hash array */ - int promisc; /* PRO - accept all packets */ - int monitor; /* MON - check pkts, but don't rx */ + bool errors_ok; /* SEP - accept pkts with rx errors */ + bool runts_ok; /* AR - accept < 64-byte runts */ + bool broadcast; /* AB - accept eth broadcast address */ + bool multicast; /* AM - check mcast hash array */ + bool promisc; /* PRO - accept all packets */ + bool monitor; /* MON - check pkts, but don't rx */ uint8_t reserved; /* D6,D7 - reserved */ } RCR; /* Receive Status Register - 0ch read */ struct RSR_t { - int rx_ok; /* PRX - rx complete without error */ - int bad_crc; /* CRC - Bad CRC detected */ - int bad_falign; /* FAE - frame alignment error */ - int fifo_or; /* FO - FIFO overrun */ - int rx_missed; /* MPA - missed packet error */ - int rx_mbit; /* PHY - unicast or mcast/bcast address match */ - int rx_disabled; /* DIS - set when in monitor mode */ - int deferred; /* DFR - collision active */ + bool rx_ok; /* PRX - rx complete without error */ + bool bad_crc; /* CRC - Bad CRC detected */ + bool bad_falign; /* FAE - frame alignment error */ + bool fifo_or; /* FO - FIFO overrun */ + bool rx_missed; /* MPA - missed packet error */ + bool rx_mbit; /* PHY - unicast or mcast/bcast address match */ + bool rx_disabled; /* DIS - set when in monitor mode */ + bool deferred; /* DFR - collision active */ } RSR; uint16_t local_dma; /* 01,02h read ; current local DMA addr */ diff --git a/src/include/86box/network.h b/src/include/86box/network.h index ef9f291ad..01454c6f9 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -48,10 +48,13 @@ #include /* Network provider types. */ -#define NET_TYPE_NONE 0 /* use the null network driver */ -#define NET_TYPE_SLIRP 1 /* use the SLiRP port forwarder */ -#define NET_TYPE_PCAP 2 /* use the (Win)Pcap API */ -#define NET_TYPE_VDE 3 /* use the VDE plug API */ +#define NET_TYPE_NONE 0 /* use the null network driver */ +#define NET_TYPE_SLIRP 1 /* use the SLiRP port forwarder */ +#define NET_TYPE_PCAP 2 /* use the (Win)Pcap API */ +#define NET_TYPE_VDE 3 /* use the VDE plug API */ +#define NET_TYPE_TAP 4 /* use a linux TAP device */ +#define NET_TYPE_NMSWITCH 5 /* use the network multicast switch provider */ +#define NET_TYPE_NRSWITCH 6 /* use the network remote switch provider */ #define NET_MAX_FRAME 1518 /* Queue size must be a power of 2 */ @@ -95,6 +98,9 @@ typedef struct netcard_conf_t { int net_type; char host_dev_name[128]; uint32_t link_state; + uint8_t switch_group; + uint8_t promisc_mode; + char nrs_hostname[128]; } netcard_conf_t; extern netcard_conf_t net_cards_conf[NET_CARD_MAX]; @@ -126,7 +132,9 @@ typedef struct netdrv_t { extern const netdrv_t net_pcap_drv; extern const netdrv_t net_slirp_drv; extern const netdrv_t net_vde_drv; +extern const netdrv_t net_tap_drv; extern const netdrv_t net_null_drv; +extern const netdrv_t net_netswitch_drv; struct _netcard_t { const device_t *device; @@ -155,10 +163,11 @@ typedef struct { int has_slirp; int has_pcap; int has_vde; + int has_tap; } network_devmap_t; -#define HAS_NOSLIRP_NET(x) (x.has_pcap || x.has_vde) +#define HAS_NOSLIRP_NET(x) (x.has_pcap || x.has_vde || x.has_tap) #ifdef __cplusplus extern "C" { @@ -191,6 +200,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 int network_type_has_config(int); extern const char *network_card_get_internal_name(int); extern int network_card_get_from_internal_name(char *); #ifdef EMU_DEVICE_H diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index 0f7d22172..273fc0a37 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -99,6 +99,7 @@ extern const device_t ami_1994_nvr_device; extern const device_t ami_1995_nvr_device; extern const device_t via_nvr_device; extern const device_t p6rp4_nvr_device; +extern const device_t martin_nvr_device; extern const device_t elt_nvr_device; #endif diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 097fcf502..8887f89f4 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -283,9 +283,11 @@ extern void pci_init(int flags); /* PCI bridge stuff. */ extern void pci_bridge_set_ctl(void *priv, uint8_t ctl); +extern uint8_t pci_bridge_get_bus_index(void *priv); #ifdef EMU_DEVICE_H extern const device_t dec21150_device; +extern const device_t dec21152_device; extern const device_t ali5243_agp_device; extern const device_t ali5247_agp_device; diff --git a/src/include/86box/pic.h b/src/include/86box/pic.h index 798cc3357..f6dc9af64 100644 --- a/src/include/86box/pic.h +++ b/src/include/86box/pic.h @@ -102,4 +102,6 @@ extern int picinterrupt(void); extern uint8_t pic_irq_ack(void); +extern void pic_toggle_latch(int is_ps2); + #endif /*EMU_PIC_H*/ diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index de0a9f30c..ef06b3429 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -32,8 +32,8 @@ /* String ID numbers. */ enum { STRING_MOUSE_CAPTURE, /* "Click to capture mouse" */ - STRING_MOUSE_RELEASE, /* "Press F8+F12 to release mouse" */ - STRING_MOUSE_RELEASE_MMB, /* "Press F8+F12 or middle button to release mouse" */ + STRING_MOUSE_RELEASE, /* "Press %1 to release mouse" */ + STRING_MOUSE_RELEASE_MMB, /* "Press %1 or middle button to release mouse" */ STRING_INVALID_CONFIG, /* "Invalid configuration" */ STRING_NO_ST506_ESDI_CDROM, /* "MFM/RLL or ESDI CD-ROM drives never existed" */ STRING_NET_ERROR, /* "Failed to initialize network driver" */ @@ -185,9 +185,9 @@ extern void floppy_mount(uint8_t id, char *fn, uint8_t wp); extern void floppy_eject(uint8_t id); extern void cdrom_mount(uint8_t id, char *fn); extern void plat_cdrom_ui_update(uint8_t id, uint8_t reload); -extern void zip_eject(uint8_t id); -extern void zip_mount(uint8_t id, char *fn, uint8_t wp); -extern void zip_reload(uint8_t id); +extern void rdisk_eject(uint8_t id); +extern void rdisk_mount(uint8_t id, char *fn, uint8_t wp); +extern void rdisk_reload(uint8_t id); extern void mo_eject(uint8_t id); extern void mo_mount(uint8_t id, char *fn, uint8_t wp); extern void mo_reload(uint8_t id); diff --git a/src/include/86box/prt_devs.h b/src/include/86box/prt_devs.h index 1379c8fa8..d136d9d93 100644 --- a/src/include/86box/prt_devs.h +++ b/src/include/86box/prt_devs.h @@ -2,10 +2,14 @@ #define EMU_PRT_DEVS_H extern const lpt_device_t lpt_prt_text_device; +extern const device_t prt_text_device; extern const lpt_device_t lpt_prt_escp_device; +extern const device_t prt_escp_device; extern const lpt_device_t lpt_prt_ps_device; +extern const device_t prt_ps_device; #ifdef USE_PCL extern const lpt_device_t lpt_prt_pcl_device; +extern const device_t prt_pcl_device; #endif #endif /*EMU_PRT_DEVS_H*/ diff --git a/src/include/86box/prt_papersizes.h b/src/include/86box/prt_papersizes.h new file mode 100644 index 000000000..c45c74568 --- /dev/null +++ b/src/include/86box/prt_papersizes.h @@ -0,0 +1,50 @@ +/* + * 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 paper sizes for printers. + * + * Authors: Jasmine Iwanek, + * + * Copyright 2025 Jasmine Iwanek + */ +#ifndef EMU_PRT_PAPERSIZES_H +#define EMU_PRT_PAPERSIZES_H + +/* Standard U.S. Letter */ +#define LETTER_PAGE_WIDTH 8.5 +#define LETTER_PAGE_HEIGHT 11.0 + +/* Standard U.S. Legal */ +#define LEGAL_PAGE_WIDTH 8.5 +#define LEGAL_PAGE_HEIGHT 14.0 + +/* Standard U.S. Ledger */ +#define LEDGER_PAGE_WIDTH 11.0 +#define LEDGER_PAGE_HEIGHT 17.0 + +/* Standard A0 */ +#define A0_PAGE_WIDTH 33.125 +#define A0_PAGE_HEIGHT 46.75 + +/* Standard A1 */ +#define A1_PAGE_WIDTH 23.375 +#define A1_PAGE_HEIGHT 33.125 + +/* Standard A2 */ +#define A2_PAGE_WIDTH 16.5 +#define A2_PAGE_HEIGHT 23.375 + +/* Standard A3 */ +#define A3_PAGE_WIDTH 11.75 +#define A3_PAGE_HEIGHT 16.5 + +/* Standard A4 */ +#define A4_PAGE_WIDTH 8.25 +#define A4_PAGE_HEIGHT 11.75 + +#endif /*EMU_PLAT_FALLTHROUGH_H*/ diff --git a/src/include/86box/rdisk.h b/src/include/86box/rdisk.h new file mode 100644 index 000000000..df48ba703 --- /dev/null +++ b/src/include/86box/rdisk.h @@ -0,0 +1,182 @@ +/* + * 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 Iomega ZIP drive with SCSI(-like) + * commands, for both ATAPI and SCSI usage. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2018-2025 Miran Grca. + */ + +#ifndef EMU_RDISK_H +#define EMU_RDISK_H + +#define RDISK_NUM 4 + +#define BUF_SIZE 32768 + +#define RDISK_TIME 10.0 + +#define ZIP_SECTORS (96 * 2048) + +#define ZIP_250_SECTORS (489532) + +#define RDISK_IMAGE_HISTORY 10 + +enum { + RDISK_TYPE_GENERIC = 0, + RDISK_TYPE_ZIP_100, + RDISK_TYPE_ZIP_250 +}; + +typedef struct rdisk_type_t { + uint32_t sectors; + uint16_t bytes_per_sector; +} rdisk_type_t; + +#define KNOWN_RDISK_TYPES 2 +static const rdisk_type_t rdisk_types[KNOWN_RDISK_TYPES] = { + { ZIP_SECTORS, 512 }, + { ZIP_250_SECTORS, 512 }, +}; + +typedef struct rdisk_drive_type_t { + const char *vendor; + const char *model; + const char *revision; + int8_t supported_media[KNOWN_RDISK_TYPES]; +} rdisk_drive_type_t; + +#define KNOWN_RDISK_DRIVE_TYPES 3 +static const rdisk_drive_type_t rdisk_drive_types[KNOWN_RDISK_DRIVE_TYPES] = { + { "86BOX", "REMOVABLE DISK", "5.00", { 1, 1 }}, + { "IOMEGA", "ZIP 100", "E.08", { 1, 0 }}, + { "IOMEGA", "ZIP 250", "42.S", { 1, 1 }} +}; + +enum { + RDISK_BUS_DISABLED = 0, + RDISK_BUS_LPT = 6, + RDISK_BUS_IDE = 7, + RDISK_BUS_ATAPI = 8, + RDISK_BUS_SCSI = 9, + RDISK_BUS_USB = 10 +}; + +typedef struct rdisk_drive_t { + uint8_t id; + + union { + uint8_t res; + /* Reserved for other ID's. */ + uint8_t res0; + uint8_t res1; + uint8_t ide_channel; + uint8_t scsi_device_id; + }; + + uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */ + uint8_t bus_mode; /* Bit 0 = PIO suported; + Bit 1 = DMA supportd. */ + uint8_t read_only; /* Struct variable reserved for + media status. */ + uint8_t pad; + uint8_t pad0; + + FILE *fp; + void *priv; + + char image_path[1024]; + char prev_image_path[1024]; + + char *image_history[RDISK_IMAGE_HISTORY]; + + uint32_t type; + uint32_t medium_size; + uint32_t base; +} rdisk_drive_t; + +typedef struct rdisk_t { + mode_sense_pages_t ms_pages_saved; + + rdisk_drive_t *drv; +#ifdef EMU_IDE_H + ide_tf_t *tf; +#else + void *tf; +#endif + + void *log; + + uint8_t *buffer; + uint8_t atapi_cdb[16]; + uint8_t current_cdb[16]; + uint8_t sense[256]; + + uint8_t id; + uint8_t cur_lun; + uint8_t pad0; + uint8_t pad1; + + uint16_t max_transfer_len; + uint16_t pad2; + + int requested_blocks; + int packet_status; + int total_length; + int do_page_save; + int unit_attention; + int request_pos; + int old_len; + int transition; + + uint32_t sector_pos; + uint32_t sector_len; + uint32_t packet_len; + uint32_t block_len; + + double callback; + + uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen); +} rdisk_t; + +extern rdisk_t *rdisk[RDISK_NUM]; +extern rdisk_drive_t rdisk_drives[RDISK_NUM]; +extern uint8_t atapi_rdisk_drives[8]; +extern uint8_t scsi_rdisk_drives[16]; + +#define rdisk_sense_error dev->sense[0] +#define rdisk_sense_key dev->sense[2] +#define rdisk_info *(uint32_t *) &(dev->sense[3]) +#define rdisk_asc dev->sense[12] +#define rdisk_ascq dev->sense[13] + +#ifdef __cplusplus +extern "C" { +#endif + +extern void rdisk_disk_close(const rdisk_t *dev); +extern void rdisk_disk_reload(const rdisk_t *dev); +extern void rdisk_insert(rdisk_t *dev); + +extern void rdisk_global_init(void); +extern void rdisk_hard_reset(void); + +extern void rdisk_reset(scsi_common_t *sc); +extern int rdisk_is_empty(const uint8_t id); +extern void rdisk_load(const rdisk_t *dev, const char *fn, const int skip_insert); +extern void rdisk_close(void); + +#ifdef __cplusplus +} +#endif + +#endif /*EMU_RDISK_H*/ diff --git a/src/include/86box/renderdefs.h b/src/include/86box/renderdefs.h new file mode 100644 index 000000000..36c3d9f74 --- /dev/null +++ b/src/include/86box/renderdefs.h @@ -0,0 +1,40 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * definitions for renderers + * + * Authors: Jasmine Iwanek, + * + * Copyright 2025 Jasmine Iwanek. + */ +#ifndef EMU_RENDERDEFS_H +#define EMU_RENDERDEFS_H + +#define RENDERER_NAME_DEFAULT "default" +#define RENDERER_NAME_SYSTEM "system" +#define RENDERER_NAME_QT_SOFTWARE "qt_software" +#define RENDERER_NAME_QT_OPENGL "qt_opengl" +#define RENDERER_NAME_QT_OPENGLES "qt_opengles" +#define RENDERER_NAME_QT_OPENGL3 "qt_opengl3" +#define RENDERER_NAME_QT_VULKAN "qt_vulkan" +#define RENDERER_NAME_VNC "vnc" + +#define RENDERER_SOFTWARE 0 +#define RENDERER_OPENGL3 1 +#define RENDERER_VULKAN 2 +#define RENDERER_VNC 3 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /*EMU_RENDERDEFS_H*/ diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index 31c77ce5a..f35c7e36e 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -151,6 +151,7 @@ extern void serial_set_dsr(serial_t *dev, uint8_t enabled); extern void serial_set_dcd(serial_t *dev, uint8_t enabled); extern void serial_set_ri(serial_t *dev, uint8_t enabled); extern int serial_get_ri(serial_t *dev); +extern uint8_t serial_get_shadow(serial_t *dev); extern const device_t ns8250_device; extern const device_t ns8250_pcjr_device; diff --git a/src/include/86box/serial_passthrough.h b/src/include/86box/serial_passthrough.h index c5454194a..a5fa0013a 100644 --- a/src/include/86box/serial_passthrough.h +++ b/src/include/86box/serial_passthrough.h @@ -13,7 +13,7 @@ * Jasmine Iwanek * * Copyright 2021 Andreas J. Reichel. - * Copyright 2021-2022 Jasmine Iwanek. + * Copyright 2021-2025 Jasmine Iwanek. */ #ifndef SERIAL_PASSTHROUGH_H @@ -28,10 +28,15 @@ #include <86box/serial.h> enum serial_passthrough_mode { - SERPT_MODE_VCON, /*Named Pipe (Server) / Pseudo Terminal/Virtual Console */ - SERPT_MODE_TCPSRV, /* TCP Server (TODO) */ - SERPT_MODE_TCPCLNT, /* TCP Client (TODO) */ - SERPT_MODE_HOSTSER, /* Host Serial Passthrough */ +#ifdef _WIN32 + SERPT_MODE_NPIPE_SRV, /* Named Pipe (Server) */ + SERPT_MODE_NPIPE_CLNT, /* Named Pipe (Client) */ +#else + SERPT_MODE_VCON, /* Pseudo Terminal/Virtual Console */ +#endif + SERPT_MODE_TCP_SRV, /* TCP Server (TODO) */ + SERPT_MODE_TCP_CLNT, /* TCP Client (TODO) */ + SERPT_MODE_HOSTSER, /* Host Serial Passthrough */ SERPT_MODES_MAX, }; diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 7fcb376b9..941604ddb 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -20,14 +20,13 @@ extern const device_t acc3221_device; /* Acer / ALi */ -extern const device_t ali5105_device; - extern const device_t ali5123_device; /* Chips & Technologies */ extern const device_t f82c606_device; extern const device_t f82c710_device; +extern const device_t f82c710_pc5086_device; /* SM(S)C */ extern const device_t fdc37c651_device; @@ -46,33 +45,61 @@ extern const device_t fdc37c666_device; extern const device_t fdc37c669_device; extern const device_t fdc37c669_370_device; -extern const device_t fdc37c67x_device; +#define FDC37C93X_NORMAL 0x0002 +#define FDC37C93X_FR 0x0003 +#define FDC37C93X_APM 0x0030 +#define FDC37C93X_CHIP_ID 0x00ff -extern const device_t fdc37c931apm_device; -extern const device_t fdc37c931apm_compaq_device; -extern const device_t fdc37c932fr_device; -extern const device_t fdc37c932qf_device; -extern const device_t fdc37c932_device; -extern const device_t fdc37c935_device; -extern const device_t fdc37c935_370_device; -extern const device_t fdc37c935_no_nvr_device; +#define FDC37XXX1 0x0100 /* Compaq KBC firmware and configuration registers on GPIO ports. */ +#define FDC37XXX2 0x0200 /* AMI '5' Megakey KBC firmware. */ +#define FDC37XXX3 0x0300 /* IBM KBC firmware. */ +#define FDC37XXX5 0x0500 /* Phoenix Multikey/42 1.38 KBC firmware. */ +#define FDC37XXX7 0x0700 /* Phoenix Multikey/42i 4.16 KBC firmware. */ +#define FDC37XXXX_KBC 0x0f00 + +#define FDC37C93X_NO_NVR 0x1000 +#define FDC37XXXX_370 0x2000 + +extern const device_t fdc37c93x_device; extern const device_t fdc37m60x_device; -extern const device_t fdc37m60x_370_device; + +extern const device_t fdc37c67x_device; /* ITE */ extern const device_t it8661f_device; extern const device_t it8671f_device; + +/* Intel */ extern const device_t i82091aa_device; +extern const device_t i82091aa_26e_device; extern const device_t i82091aa_398_device; extern const device_t i82091aa_ide_pri_device; extern const device_t i82091aa_ide_device; -/* National Semiconductors */ +/* National Semiconductors PC87310 / ALi M5105 */ +#define PC87310_IDE 0x0001 +#define PC87310_ALI 0x0002 + extern const device_t pc87310_device; -extern const device_t pc87310_ide_device; + +/* National Semiconductors */ +#define PCX7307_PC87307 0x00c0 +#define PCX7307_PC97307 0x00cf + +#define PC87309_PC87309 0x00e0 + +#define PCX730X_CHIP_ID 0x00ff + +#define PCX730X_AMI 0x0200 /* AMI '5' Megakey KBC firmware. */ +#define PCX730X_PHOENIX_42 0x0500 /* Phoenix Multikey/42 1.37 KBC firmware. */ +#define PCX730X_PHOENIX_42I 0x0700 /* Phoenix Multikey/42i 4.16 KBC firmware. */ +#define PCX730X_KBC 0x0f00 + +#define PCX730X_15C 0x2000 extern const device_t pc87306_device; + extern const device_t pc87311_device; extern const device_t pc87311_ide_device; extern const device_t pc87332_device; @@ -81,13 +108,10 @@ extern const device_t pc87332_398_ide_device; extern const device_t pc87332_398_ide_sec_device; extern const device_t pc87332_398_ide_fdcon_device; +/* National Semiconductors PC87307 / PC87309 */ extern const device_t pc87307_device; -extern const device_t pc87307_15c_device; -extern const device_t pc87307_both_device; -extern const device_t pc97307_device; extern const device_t pc87309_device; -extern const device_t pc87309_15c_device; /* LG Prime */ extern const device_t prime3b_device; @@ -104,6 +128,10 @@ extern const device_t sio_detect_device; #endif /* USE_SIO_DETECT */ /* UMC */ +extern const device_t um82c862f_device; +extern const device_t um82c862f_ide_device; +extern const device_t um82c863f_device; +extern const device_t um82c863f_ide_device; extern const device_t um8663af_device; extern const device_t um8663af_ide_device; extern const device_t um8663af_sec_device; diff --git a/src/include/86box/snd_ac97.h b/src/include/86box/snd_ac97.h index 45a921863..a365f5afa 100644 --- a/src/include/86box/snd_ac97.h +++ b/src/include/86box/snd_ac97.h @@ -100,6 +100,7 @@ #define AC97_CODEC_STAC9708 AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x08) #define AC97_CODEC_STAC9721 AC97_VENDOR_ID(0x83, 0x84, 0x76, 0x09) #define AC97_CODEC_TR28023 AC97_VENDOR_ID('T', 'R', 'A', 0x03) +#define AC97_CODEC_W83971D AC97_VENDOR_ID('W', 'E', 'C', 0x01) #define AC97_CODEC_WM9701A AC97_VENDOR_ID('W', 'M', 'L', 0x00) typedef struct ac97_vendor_reg_t { @@ -150,6 +151,7 @@ extern const device_t cs4297a_device; extern const device_t stac9708_device; extern const device_t stac9721_device; extern const device_t tr28023_device; +extern const device_t w83971d_device; extern const device_t wm9701a_device; extern const device_t ac97_via_device; diff --git a/src/include/86box/snd_cms.h b/src/include/86box/snd_cms.h index 8201fe32c..8eec22935 100644 --- a/src/include/86box/snd_cms.h +++ b/src/include/86box/snd_cms.h @@ -7,20 +7,23 @@ #define MASTER_CLOCK 7159090 typedef struct cms_t { -#ifdef SAASOUND_H_INCLUDED - SAASND saasound; - SAASND saasound2; -#else - void* saasound; - void* saasound2; -#endif + int addrs[2]; + uint8_t regs[2][32]; + uint16_t latch[2][6]; + int freq[2][6]; + float count[2][6]; + int vol[2][6][2]; + int stat[2][6]; + uint16_t noise[2][2]; + uint16_t noisefreq[2][2]; + int noisecount[2][2]; + int noisetype[2][2]; uint8_t latched_data; - int16_t buffer[WTBUFLEN * 2]; - int16_t buffer2[WTBUFLEN * 2]; + int16_t buffer[SOUNDBUFLEN * 2]; - int pos, pos2; + int pos; } cms_t; extern void cms_update(cms_t *cms); diff --git a/src/include/86box/snd_mmb.h b/src/include/86box/snd_mmb.h new file mode 100644 index 000000000..6e5f7d3a8 --- /dev/null +++ b/src/include/86box/snd_mmb.h @@ -0,0 +1,42 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Mindscape Music Board emulation. + * + * Authors: Roy Baer, + * Jasmine Iwanek, + * + * Copyright 2025 Roy Baer. + * Copyright 2025 Jasmine Iwanek. + */ +#ifndef _SOUND_SND_MMB_H_ +#define _SOUND_SND_MMB_H_ + +#define MMB_FREQ FREQ_48000 + +/* NOTE: + * The constant clock rate is a deviation from the real hardware which has + * the design flaw that the clock rate is always half the ISA bus clock. + */ +#define MMB_CLOCK 2386364 + +typedef struct ay_3_891x_s { + uint8_t index; + uint8_t regs[16]; + struct ayumi chip; +} ay_3_891x_t; + +typedef struct mmb_s { + ay_3_891x_t first; + ay_3_891x_t second; + + int16_t buffer[SOUNDBUFLEN * 2]; + int pos; +} mmb_t; + +#endif /* _SOUND_SND_MMB_H_ */ diff --git a/src/include/86box/snd_resid.h b/src/include/86box/snd_resid.h index c7e97ac0f..c6a616a3e 100644 --- a/src/include/86box/snd_resid.h +++ b/src/include/86box/snd_resid.h @@ -4,7 +4,7 @@ #ifdef __cplusplus extern "C" { #endif -void *sid_init(uint8_t type); +void *sid_init(uint8_t type, double range); void sid_close(void *priv); void sid_reset(void *priv); uint8_t sid_read(uint16_t addr, void *priv); diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index a30095c66..5f91ec9d0 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -12,9 +12,11 @@ * * Authors: Sarah Walker, * Miran Grca, + * Jasmine Iwanek, * * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2025 Miran Grca. + * Copyright 2024-2025 Jasmine Iwanek. */ #ifndef EMU_SOUND_H @@ -132,6 +134,12 @@ extern const device_t cmi8738_device; extern const device_t cmi8738_onboard_device; extern const device_t cmi8738_6ch_onboard_device; +/* Covox ISA */ +extern const device_t voicemasterkey_device; +extern const device_t soundmasterplus_device; +extern const device_t isadacr0_device; +extern const device_t isadacr1_device; + /* Creative Labs Game Blaster */ extern const device_t cms_device; @@ -197,6 +205,7 @@ extern const device_t ct5880_onboard_device; /* Gravis UltraSound and UltraSound Max */ extern const device_t gus_device; +extern const device_t gus_max_device; /* IBM PS/1 Audio Card */ extern const device_t ps1snd_device; @@ -205,11 +214,17 @@ extern const device_t ps1snd_device; extern const device_t ssi2001_device; extern const device_t entertainer_device; +/* Mindscape Music Board */ +extern const device_t mmb_device; + /* Pro Audio Spectrum Plus, 16, and 16D */ extern const device_t pasplus_device; extern const device_t pas16_device; extern const device_t pas16d_device; +/* Rainbow Arts PC-Soundman */ +extern const device_t soundman_device; + /* Tandy PSSJ */ extern const device_t pssj_device; extern const device_t pssj_isa_device; diff --git a/src/include/86box/ui.h b/src/include/86box/ui.h index 783400ebc..63243a666 100644 --- a/src/include/86box/ui.h +++ b/src/include/86box/ui.h @@ -49,7 +49,7 @@ extern int ui_msgbox_header(int flags, void *header, void *message); #define SB_CARTRIDGE 0x10 #define SB_FLOPPY 0x20 #define SB_CDROM 0x30 -#define SB_ZIP 0x40 +#define SB_RDISK 0x40 #define SB_MO 0x50 #define SB_HDD 0x60 #define SB_NETWORK 0x70 @@ -67,6 +67,7 @@ extern void ui_sb_update_tip(int meaning); extern void ui_sb_update_icon(int tag, int active); extern void ui_sb_update_icon_write(int tag, int write); extern void ui_sb_update_icon_state(int tag, int state); +extern void ui_sb_update_icon_wp(int tag, int state); extern void ui_sb_set_text_w(wchar_t *wstr); extern void ui_sb_set_text(char *str); extern void ui_sb_bugui(char *str); diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index 696b640bc..5aa8927e0 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -24,6 +24,26 @@ #define INT_FIFO_EMP (1 << 3) #define INT_MASK 0xf +typedef enum { + IBM_8514A_TYPE = 0, + ATI_38800_TYPE, + ATI_68800_TYPE, + TYPE_MAX +} ibm8514_card_type; + +typedef enum { + IBM = 0, + ATI, + EXTENSIONS_MAX +} ibm8514_extensions_t; + +typedef enum { + VGA_MODE = 0, + IBM_MODE, + ATI_MODE, + MODE_MAX +} ibm8514_mode_t; + typedef struct hwcursor8514_t { int ena; int x; @@ -58,7 +78,7 @@ typedef struct ibm8514_t { int force_old_addr; int type; - int local; + ibm8514_card_type local; int bpp; int on; int accel_bpp; @@ -67,7 +87,7 @@ typedef struct ibm8514_t { uint32_t vram_mask; uint32_t pallook[512]; uint32_t bios_addr; - uint32_t ma_latch; + uint32_t memaddr_latch; PALETTE vgapal; uint8_t hwcursor_oddeven; @@ -189,6 +209,7 @@ typedef struct ibm8514_t { int split; int h_disp; int h_total; + int h_sync_start; int h_sync_width; int h_disp_time; int rowoffset; @@ -207,8 +228,8 @@ typedef struct ibm8514_t { int lastline_draw; int displine; int fullchange; - uint32_t ma; - uint32_t maback; + uint32_t memaddr; + uint32_t memaddr_backup; uint8_t *vram; uint8_t *changedvram; @@ -223,7 +244,7 @@ typedef struct ibm8514_t { int hdisp; int hdisp2; int hdisped; - int sc; + int scanline; int vsyncstart; int vsyncwidth; int vtotal; @@ -246,7 +267,9 @@ typedef struct ibm8514_t { int pitch; int ext_pitch; int ext_crt_pitch; - int extensions; + ibm8514_extensions_t extensions; + ibm8514_mode_t mode; + int onboard; int linear; uint32_t vram_amount; int vram_512k_8514; @@ -263,9 +286,9 @@ typedef struct ibm8514_t { } ibm8514_t; -#define IBM_8514A (((dev->local & 0xff) == 0x00) && (dev->extensions == 0x00)) -#define ATI_8514A_ULTRA (((dev->local & 0xff) == 0x00) && (dev->extensions == 0x01)) -#define ATI_GRAPHICS_ULTRA ((dev->local & 0xff) == 0x01) -#define ATI_MACH32 ((dev->local & 0xff) == 0x02) +#define IBM_8514A (((dev->local & 0xff) == IBM_8514A_TYPE) && (dev->extensions == IBM)) +#define ATI_8514A_ULTRA (((dev->local & 0xff) == IBM_8514A_TYPE) && (dev->extensions == ATI)) +#define ATI_GRAPHICS_ULTRA ((dev->local & 0xff) == ATI_38800_TYPE) +#define ATI_MACH32 ((dev->local & 0xff) == ATI_68800_TYPE) #endif /*VIDEO_8514A_H*/ diff --git a/src/include/86box/vid_ati_mach8.h b/src/include/86box/vid_ati_mach8.h index d5e80d0c8..ad5281ac3 100644 --- a/src/include/86box/vid_ati_mach8.h +++ b/src/include/86box/vid_ati_mach8.h @@ -18,6 +18,12 @@ #ifndef VIDEO_ATI_MACH8_H #define VIDEO_ATI_MACH8_H +typedef enum { + ATI_68875 = 0, + ATI_68860, + RAMDAC_MAX +} mach_ramdac_type; + typedef struct mach_t { ati_eeprom_t eeprom; svga_t svga; @@ -39,7 +45,7 @@ typedef struct mach_t { uint8_t irq_state; int index; - int ramdac_type; + mach_ramdac_type ramdac_type; int old_mode; uint16_t config1; @@ -137,6 +143,7 @@ typedef struct mach_t { int16_t dx_end; int16_t dy; int16_t dy_end; + int16_t dx_first_row_start; int16_t dx_start; int16_t dy_start; int16_t cy; diff --git a/src/include/86box/vid_cga.h b/src/include/86box/vid_cga.h index a503d12ba..2198154ed 100644 --- a/src/include/86box/vid_cga.h +++ b/src/include/86box/vid_cga.h @@ -8,23 +8,69 @@ * * Emulation of the old and new IBM CGA graphics cards. * - * - * * Authors: Sarah Walker, * Miran Grca, + * Connor Hyde / starfrost, * * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 Miran Grca. + * Copyright 2025 starfrost (refactoring). */ #ifndef VIDEO_CGA_H #define VIDEO_CGA_H +// Mode flags for the CGA. +// Set by writing to 3D8 +typedef enum cga_mode_flags_e { + CGA_MODE_FLAG_HIGHRES = 1 << 0, // 80-column text mode + CGA_MODE_FLAG_GRAPHICS = 1 << 1, // Graphics mode + CGA_MODE_FLAG_BW = 1 << 2, // Black and white + CGA_MODE_FLAG_VIDEO_ENABLE = 1 << 3, // 0 = no video (as if the video was 0) + CGA_MODE_FLAG_HIGHRES_GRAPHICS = 1 << 4, // 640*200 mode. Corrupts text mode if CGA_MODE_FLAG_GRAPHICS not set. + CGA_MODE_FLAG_BLINK = 1 << 5, // If this is set, bit 5 of textmode characters blinks. Otherwise it is a high-intensity bg mode. +} cga_mode_flags; + +// Motorola MC6845 CRTC registers +typedef enum cga_crtc_registers_e { + CGA_CRTC_HTOTAL = 0x0, // Horizontal total (total number of characters incl. hsync) + CGA_CRTC_HDISP = 0x1, // Horizontal display + CGA_CRTC_HSYNC_POS = 0x2, // Horizontal position of horizontal ysnc + CGA_CRTC_HSYNC_WIDTH = 0x3, // Width of horizontal sync + CGA_CRTC_VTOTAL = 0x4, // Vertical total (total number of scanlines incl. vsync) + CGA_CRTC_VTOTAL_ADJUST = 0x5, // Vertical total adjust value + CGA_CRTC_VDISP = 0x6, // Vertical display (total number of displayed scanline) + CGA_CRTC_VSYNC = 0x7, // Vertical sync scanline number + CGA_CRTC_INTERLACE = 0x8, // Interlacing mode + CGA_CRTC_MAX_SCANLINE_ADDR = 0x9, // Maximum scanline address + CGA_CRTC_CURSOR_START = 0xA, // Cursor start scanline + CGA_CRTC_CURSOR_END = 0xB, // Cursor end scanline + CGA_CRTC_START_ADDR_HIGH = 0xC, // Screen start address high 8 bits + CGA_CRTC_START_ADDR_LOW = 0xD, // Screen start address low 8 bits + CGA_CRTC_CURSOR_ADDR_HIGH = 0xE, // Cursor address high 8 bits + CGA_CRTC_CURSOR_ADDR_LOW = 0xF, // Cursor address low 8 bits + CGA_CRTC_LIGHT_PEN_ADDR_HIGH = 0x10, // Light pen address high 8 bits (not currently supported) + CGA_CRTC_LIGHT_PEN_ADDR_LOW = 0x11, // Light pen address low 8 bits (not currently supported) +} cga_crtc_registers; + +// Registers for the CGA +typedef enum cga_registers_e { + CGA_REGISTER_CRTC_INDEX = 0x3D4, + CGA_REGISTER_CRTC_DATA = 0x3D5, + CGA_REGISTER_MODE_CONTROL = 0x3D8, + CGA_REGISTER_COLOR_SELECT = 0x3D9, + CGA_REGISTER_STATUS = 0x3DA, + CGA_REGISTER_CLEAR_LIGHT_PEN_LATCH = 0x3DB, + CGA_REGISTER_SET_LIGHT_PEN_LATCH = 0x3DC, +} cga_registers; + +#define CGA_NUM_CRTC_REGS 32 + typedef struct cga_t { mem_mapping_t mapping; int crtcreg; - uint8_t crtc[32]; + uint8_t crtc[CGA_NUM_CRTC_REGS]; uint8_t cgastat; @@ -36,17 +82,16 @@ typedef struct cga_t { int fontbase; int linepos; int displine; - int sc; + int scanline; int vc; int cgadispon; - int con; - int coff; + int cursorvisible; // Determines if the cursor is visible FOR THE CURRENT SCANLINE. int cursoron; int cgablink; int vsynctime; int vadj; - uint16_t ma; - uint16_t maback; + uint16_t memaddr; + uint16_t memaddr_backup; int oddeven; uint64_t dispontime; @@ -79,11 +124,11 @@ uint8_t cga_read(uint32_t addr, void *priv); void cga_recalctimings(cga_t *cga); void cga_poll(void *priv); -#ifdef EMU_DEVICE_H -extern const device_config_t cga_config[]; - -extern const device_t cga_device; -extern const device_t cga_pravetz_device; -#endif - +//#ifdef EMU_DEVICE_H +//extern const device_config_t cga_config[]; +// +//extern const device_t cga_device; +//extern const device_t cga_pravetz_device; +//#endif +// #endif /*VIDEO_CGA_H*/ diff --git a/src/include/86box/vid_colorplus.h b/src/include/86box/vid_colorplus.h index 5acd4c8a2..8716f72fb 100644 --- a/src/include/86box/vid_colorplus.h +++ b/src/include/86box/vid_colorplus.h @@ -4,6 +4,8 @@ typedef struct colorplus_t { cga_t cga; uint8_t control; + + lpt_t * lpt; } colorplus_t; void colorplus_init(colorplus_t *colorplus); diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index 0e28820ff..beef6f98d 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -39,7 +39,7 @@ typedef struct ega_t { uint8_t lb; uint8_t lc; uint8_t ld; - uint8_t stat; + uint8_t status; uint8_t colourcompare; uint8_t colournocare; uint8_t scrblank; @@ -68,12 +68,12 @@ typedef struct ega_t { int chain4; int chain2_read; int chain2_write; - int con; + int cursorvisible; int oddeven_page; int oddeven_chain; int vc; int real_vc; - int sc; + int scanline; int dispon; int hdisp_on; int cursoron; @@ -115,14 +115,14 @@ typedef struct ega_t { int chipset; int mono_display; - int mdacols[256][2][2]; + int mda_attr_to_color_table[256][2][2]; uint32_t charseta; uint32_t charsetb; - uint32_t ma_latch; - uint32_t ma; - uint32_t maback; - uint32_t ca; + uint32_t memaddr_latch; + uint32_t memaddr; + uint32_t memaddr_backup; + uint32_t cursoraddr; uint32_t vram_limit; uint32_t overscan_color; uint32_t cca; @@ -148,6 +148,8 @@ typedef struct ega_t { card should not attempt to display anything. */ void (*render_override)(void *priv); void * priv_parent; + + uint8_t alt_addr; /* 0 for 0x3XX range, 1 for 0x2XX range */ } ega_t; #endif @@ -187,11 +189,11 @@ extern void ega_set_type(void *priv, uint32_t local); extern int firstline_draw; extern int lastline_draw; extern int displine; -extern int sc; +extern int scanline; -extern uint32_t ma; -extern uint32_t ca; -extern int con; +extern uint32_t memaddr; +extern uint32_t cursoraddr; +extern int cursorvisible; extern int cursoron; extern int cgablink; diff --git a/src/include/86box/vid_ega_render_remap.h b/src/include/86box/vid_ega_render_remap.h index b01bb2b0e..1b0f7676c 100644 --- a/src/include/86box/vid_ega_render_remap.h +++ b/src/include/86box/vid_ega_render_remap.h @@ -33,9 +33,9 @@ } \ \ if (nr & VAR_ROW0_MA13) \ - out_addr = (out_addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); \ + out_addr = (out_addr & ~0x8000) | ((ega->scanline & 1) ? 0x8000 : 0); \ if (nr & VAR_ROW1_MA14) \ - out_addr = (out_addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); \ + out_addr = (out_addr & ~0x10000) | ((ega->scanline & 2) ? 0x10000 : 0); \ \ return out_addr; \ } diff --git a/src/include/86box/vid_hercules.h b/src/include/86box/vid_hercules.h index c58a50aa3..05f2673a5 100644 --- a/src/include/86box/vid_hercules.h +++ b/src/include/86box/vid_hercules.h @@ -13,10 +13,12 @@ * Authors: Sarah Walker, * Miran Grca, * Jasmine Iwanek, - * + * Connor Hyde / starfrost, + */ #ifndef VIDEO_MDA_H #define VIDEO_MDA_H +// Defines +#define MDA_CRTC_NUM_REGISTERS 32 + +// Enums & structures + +typedef enum mda_registers_e +{ + MDA_REGISTER_START = 0x3B0, + + MDA_REGISTER_CRTC_INDEX = 0x3B4, + MDA_REGISTER_CRTC_DATA = 0x3B5, + MDA_REGISTER_MODE_CONTROL = 0x3B8, + MDA_REGISTER_CRT_STATUS = 0x3BA, + MDA_REGISTER_PARALLEL_DATA = 0x3BC, + MDA_REGISTER_PRINTER_STATUS = 0x3BD, + MDA_REGISTER_PRINTER_CONTROL = 0x3BE, + + MDA_REGISTER_END = 0x3BF, +} mda_registers; + +// Motorola MC6845 CRTC registers (without light pen for some reason) +typedef enum mda_crtc_registers_e +{ + MDA_CRTC_HTOTAL = 0x0, // Horizontal total (total number of characters incl. hsync) + MDA_CRTC_HDISP = 0x1, // Horizontal display + MDA_CRTC_HSYNC_POS = 0x2, // Horizontal position of horizontal ysnc + MDA_CRTC_HSYNC_WIDTH = 0x3, // Width of horizontal sync + MDA_CRTC_VTOTAL = 0x4, // Vertical total (total number of scanlines incl. vsync) + MDA_CRTC_VTOTAL_ADJUST = 0x5, // Vertical total adjust value + MDA_CRTC_VDISP = 0x6, // Vertical display (total number of displayed scanline) + MDA_CRTC_VSYNC = 0x7, // Vertical sync scanline number + MDA_CRTC_INTERLACE = 0x8, // Interlacing mode + MDA_CRTC_MAX_SCANLINE_ADDR = 0x9, // Maximum scanline address + MDA_CRTC_CURSOR_START = 0xA, // Cursor start scanline + MDA_CRTC_CURSOR_END = 0xB, // Cursor end scanline + MDA_CRTC_START_ADDR_HIGH = 0xC, // Screen start address high 8 bits + MDA_CRTC_START_ADDR_LOW = 0xD, // Screen start address low 8 bits + MDA_CRTC_CURSOR_ADDR_HIGH = 0xE, // Cursor address high 8 bits + MDA_CRTC_CURSOR_ADDR_LOW = 0xF, // Cursor address low 8 bits +} mda_crtc_registers; + +typedef enum mda_mode_flags_e +{ + MDA_MODE_HIGHRES = 1 << 0, // MUST be enabled for sane operation + MDA_MODE_BW = 1 << 1, // UNUSED in most cases. Not present on Hercules + MDA_MODE_VIDEO_ENABLE = 1 << 3, + MDA_MODE_BLINK = 1 << 5, +} mda_mode_flags; + +typedef enum mda_colors_e +{ + MDA_COLOR_BLACK = 0, + MDA_COLOR_BLUE = 1, + MDA_COLOR_GREEN = 2, + MDA_COLOR_CYAN = 3, + MDA_COLOR_RED = 4, + MDA_COLOR_MAGENTA = 5, + MDA_COLOR_BROWN = 6, + MDA_COLOR_WHITE = 7, + MDA_COLOR_GREY = 8, + MDA_COLOR_BRIGHT_BLUE = 9, + MDA_COLOR_BRIGHT_GREEN = 10, + MDA_COLOR_BRIGHT_CYAN = 11, + MDA_COLOR_BRIGHT_RED = 12, + MDA_COLOR_BRIGHT_MAGENTA = 13, + MDA_COLOR_BRIGHT_YELLOW = 14, + MDA_COLOR_BRIGHT_WHITE = 15, +} mda_colors; + typedef struct mda_t { mem_mapping_t mapping; - uint8_t crtc[32]; - int crtcreg; + uint8_t crtc[MDA_CRTC_NUM_REGISTERS]; + int32_t crtcreg; - uint8_t ctrl; - uint8_t stat; + uint8_t mode; + uint8_t status; - uint64_t dispontime; - uint64_t dispofftime; - pc_timer_t timer; + uint64_t dispontime; + uint64_t dispofftime; + pc_timer_t timer; - int firstline; - int lastline; + int32_t firstline; + int32_t lastline; - int fontbase; - int linepos; - int displine; - int vc; - int sc; - uint16_t ma; - uint16_t maback; - int con; - int coff; - int cursoron; - int dispon; - int blink; - int vsynctime; - int vadj; - int monitor_index; - int prev_monitor_index; + int32_t fontbase; + int32_t linepos; + int32_t displine; + int32_t vc; + int32_t scanline; + uint16_t memaddr; + uint16_t memaddr_backup; + int32_t cursorvisible; + int32_t cursoron; + int32_t dispon; + int32_t blink; + int32_t vsynctime; + int32_t vadj; + int32_t monitor_index; + int32_t prev_monitor_index; + int32_t monitor_type; // Used for MDA Colour support (REV0 u64) - uint8_t *vram; + uint8_t *vram; + lpt_t *lpt; } mda_t; #define VIDEO_MONITOR_PROLOGUE() \ diff --git a/src/include/86box/vid_pgc.h b/src/include/86box/vid_pgc.h index 35e2d9e42..dd6a45b98 100644 --- a/src/include/86box/vid_pgc.h +++ b/src/include/86box/vid_pgc.h @@ -115,14 +115,13 @@ typedef struct pgc { int displine; int vc; int cgadispon; - int con; - int coff; + int cursorvisible; int cursoron; int cgablink; int vsynctime; int vadj; - uint16_t ma; - uint16_t maback; + uint16_t memaddr; + uint16_t memaddr_backup; int oddeven; uint64_t dispontime; diff --git a/src/include/86box/vid_quadcolor.h b/src/include/86box/vid_quadcolor.h new file mode 100644 index 000000000..41b39dfb0 --- /dev/null +++ b/src/include/86box/vid_quadcolor.h @@ -0,0 +1,93 @@ +/* + * 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. + * + * Quadram Quadcolor I / I+II emulation + * + * Authors: Benedikt Freisen, + * Jasmine Iwanek, + * + * Copyright 2024 Benedikt Freisen. + Copyright 2025 Jasmine Iwanek. + */ + +#ifndef _VID_QUADCOLOR_H_ +#define _VID_QUADCOLOR_H_ + +typedef struct quadcolor_t { + mem_mapping_t mapping; + mem_mapping_t mapping_2; + + int crtcreg; +#if 0 + uint8_t crtc[CGA_NUM_CRTC_REGS]; +#else + uint8_t crtc[32]; +#endif + uint8_t cgastat; + + uint8_t cgamode; + uint8_t cgacol; + + uint8_t lp_strobe; + + uint8_t quadcolor_ctrl; + uint8_t quadcolor_2_oe; + uint16_t page_offset; + + int fontbase; + int linepos; + int displine; + int scanline; + int vc; + int cgadispon; + int cursorvisible; // Determines if the cursor is visible FOR THE CURRENT SCANLINE. + int cursoron; + int cgablink; + int vsynctime; + int vadj; + uint16_t memaddr; + uint16_t memaddr_backup; + int oddeven; + + int qc2idx; + uint8_t qc2mask; + + uint64_t dispontime; + uint64_t dispofftime; + pc_timer_t timer; + + int firstline; + int lastline; + + int drawcursor; + + int fullchange; + + uint8_t *vram; + uint8_t *vram_2; + + uint8_t charbuffer[256]; + + int revision; + int composite; + int rgb_type; + int double_type; + + int has_2nd_charset; + int has_quadcolor_2; +} quadcolor_t; + +void quadcolor_init(quadcolor_t *quadcolor); +void quadcolor_out(uint16_t addr, uint8_t val, void *priv); +uint8_t quadcolor_in(uint16_t addr, void *priv); +void quadcolor_write(uint32_t addr, uint8_t val, void *priv); +uint8_t quadcolor_read(uint32_t addr, void *priv); +void quadcolor_recalctimings(quadcolor_t *quadcolor); +void quadcolor_poll(void *priv); + +#endif /* _VID_QUADCOLOR_H_ */ diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 6de73f9f9..5492da18a 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -30,6 +30,7 @@ # define FLAG_S3_911_16BIT 256 # define FLAG_512K_MASK 512 # define FLAG_NO_SHIFT3 1024 /* Needed for Bochs VBE. */ +# define FLAG_PRECISETIME 2048 /* Needed for Copper demo if on dynarec. */ struct monitor_t; typedef struct hwcursor_t { @@ -100,12 +101,12 @@ typedef struct svga_t { int dispon; int hdisp_on; int vc; - int sc; + int scanline; int linepos; int vslines; int linecountff; int oddeven; - int con; + int cursorvisible; int cursoron; int blink; int scrollcache; @@ -116,6 +117,7 @@ typedef struct svga_t { int lastline_draw; int displine; int fullchange; + int left_overscan; int x_add; int y_add; int pan; @@ -135,6 +137,9 @@ typedef struct svga_t { int packed_4bpp; int ps_bit_bug; int ati_4color; + int vblankend; + int render_line_offset; + int start_retrace_latch; /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : 0MB-1MB - VRAM @@ -151,15 +156,15 @@ typedef struct svga_t { uint32_t charseta; uint32_t charsetb; uint32_t adv_flags; - uint32_t ma_latch; + uint32_t memaddr_latch; uint32_t ca_adj; - uint32_t ma; - uint32_t maback; + uint32_t memaddr; + uint32_t memaddr_backup; uint32_t write_bank; uint32_t read_bank; uint32_t extra_banks[2]; uint32_t banked_mask; - uint32_t ca; + uint32_t cursoraddr; uint32_t overscan_color; uint32_t *map8; uint32_t pallook[512]; @@ -280,6 +285,10 @@ typedef struct svga_t { you should set this flag when entering that mode*/ int disable_blink; + /*Force special shifter bypass logic for 8-bpp lowres modes. + Needed if the screen is squished on certain S3 cards.*/ + int force_shifter_bypass; + /*Force CRTC to dword mode, regardless of CR14/CR17. Required for S3 enhanced mode*/ int force_dword_mode; @@ -403,15 +412,15 @@ 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 *priv, svga_t *svga); -extern uint8_t ati68860_ramdac_in(uint16_t addr, void *priv, svga_t *svga); +extern void ati68860_ramdac_out(uint16_t addr, uint8_t val, int is_8514, void *priv, svga_t *svga); +extern uint8_t ati68860_ramdac_in(uint16_t addr, int is_8514, 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 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 ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, int is_8514, void *priv, svga_t *svga); +extern uint8_t ati68875_ramdac_in(uint16_t addr, int rs2, int rs3, int is_8514, void *priv, svga_t *svga); extern void att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); extern uint8_t att49x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); diff --git a/src/include/86box/vid_svga_render.h b/src/include/86box/vid_svga_render.h index babac7592..7ead95838 100644 --- a/src/include/86box/vid_svga_render.h +++ b/src/include/86box/vid_svga_render.h @@ -23,11 +23,11 @@ extern int firstline_draw; extern int lastline_draw; extern int displine; -extern int sc; +extern int scanline; -extern uint32_t ma; -extern uint32_t ca; -extern int con; +extern uint32_t memaddr; +extern uint32_t cursoraddr; +extern int cursorvisible; extern int cursoron; extern int cgablink; @@ -55,13 +55,10 @@ 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_4bpp_tseng_highres(svga_t *svga); extern void svga_render_8bpp_clone_highres(svga_t *svga); extern void svga_render_8bpp_tseng_lowres(svga_t *svga); extern void svga_render_8bpp_tseng_highres(svga_t *svga); -extern void svga_render_8bpp_gs_lowres(svga_t *svga); -extern void svga_render_8bpp_gs_highres(svga_t *svga); -extern void svga_render_8bpp_rgb_lowres(svga_t *svga); -extern void svga_render_8bpp_rgb_highres(svga_t *svga); extern void svga_render_15bpp_lowres(svga_t *svga); extern void svga_render_15bpp_highres(svga_t *svga); extern void svga_render_15bpp_mix_lowres(svga_t *svga); diff --git a/src/include/86box/vid_svga_render_remap.h b/src/include/86box/vid_svga_render_remap.h index ff9151c3c..d6c9fa5a6 100644 --- a/src/include/86box/vid_svga_render_remap.h +++ b/src/include/86box/vid_svga_render_remap.h @@ -47,9 +47,9 @@ } \ \ if (nr & VAR_ROW0_MA13) \ - out_addr = (out_addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); \ + out_addr = (out_addr & ~0x8000) | ((svga->scanline & 1) ? 0x8000 : 0); \ if (nr & VAR_ROW1_MA14) \ - out_addr = (out_addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); \ + out_addr = (out_addr & ~0x10000) | ((svga->scanline & 2) ? 0x10000 : 0); \ \ return out_addr; \ } diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index b2001dba9..9aac43b9f 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -19,6 +19,9 @@ #include <86box/rom.h> +#define XGA_INT_START_BLKNK_ENAB (1 << 0) +#define XGA_INT_MASK 0xf + typedef struct xga_hwcursor_t { int ena; int x; @@ -84,13 +87,13 @@ typedef struct xga_t { uint8_t border_color; uint8_t direct_color; uint8_t dma_channel; - uint8_t instance_isa; uint8_t instance_num; - uint8_t ext_mem_addr; uint8_t vga_post; uint8_t addr_test; uint8_t *vram; uint8_t *changedvram; + uint8_t int_ena; + uint8_t int_stat; int16_t hwc_pos_x; int16_t hwc_pos_y; @@ -127,7 +130,7 @@ typedef struct xga_t { int dispon; int h_disp_on; int vc; - int sc; + int scanline; int linepos; int oddeven; int firstline; @@ -149,9 +152,9 @@ typedef struct xga_t { int cursor_data_on; int pal_test; int a5_test; + int test_stage; int type; int bus; - int busy; uint32_t linear_base; uint32_t linear_size; @@ -160,17 +163,18 @@ typedef struct xga_t { uint32_t hwc_color0; uint32_t hwc_color1; uint32_t disp_start_addr; - uint32_t ma_latch; + uint32_t memaddr_latch; uint32_t vram_size; uint32_t vram_mask; uint32_t rom_addr; - uint32_t ma; - uint32_t maback; + uint32_t memaddr; + uint32_t memaddr_backup; uint32_t read_bank; uint32_t write_bank; uint32_t px_map_base; uint32_t pallook[512]; uint32_t bios_diag; + uint32_t mapping_base; PALETTE xgapal; @@ -205,6 +209,10 @@ typedef struct xga_t { uint16_t dst_map_y; uint16_t pat_map_x; uint16_t pat_map_y; + uint16_t clip_l; + uint16_t clip_r; + uint16_t clip_t; + uint16_t clip_b; int ssv_state; int pat_src; @@ -218,13 +226,13 @@ typedef struct xga_t { int y; int sx; int sy; - int dx; - int dy; int px; int py; int pattern; int command_len; int filling; + int y_len; + int x_len; uint32_t short_stroke; uint32_t color_cmp; @@ -234,6 +242,7 @@ typedef struct xga_t { uint32_t bkgd_color; uint32_t command; uint32_t dir_cmd; + uint32_t pattern_data; uint8_t px_map_format[4]; uint16_t px_map_width[4]; diff --git a/src/include/86box/vid_xga_device.h b/src/include/86box/vid_xga_device.h index e337ef9d3..7a72e76f5 100644 --- a/src/include/86box/vid_xga_device.h +++ b/src/include/86box/vid_xga_device.h @@ -20,7 +20,6 @@ #ifdef EMU_DEVICE_H extern const device_t xga_device; -extern const device_t xga_isa_device; extern const device_t inmos_isa_device; #endif #endif /*VIDEO_XGA_DEVICE_H*/ diff --git a/src/include/86box/video.h b/src/include/86box/video.h index d55275359..62fea0b9a 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -36,6 +36,10 @@ using atomic_int = std::atomic_int; #define getcolg(color) (((color) >> 8) & 0xFF) #define getcolb(color) ((color) & 0xFF) +#ifdef __cplusplus +extern "C" { +#endif + enum { VID_NONE = 0, VID_INTERNAL @@ -49,10 +53,6 @@ enum { FULLSCR_SCALE_INT43 }; -#ifdef __cplusplus -extern "C" { -#endif - enum { VIDEO_ISA = 0, VIDEO_MCA, @@ -71,6 +71,12 @@ enum { #define VIDEO_FLAG_TYPE_SECONDARY VIDEO_FLAG_TYPE_SPECIAL +#define FONT_IBM_MDA_437_PATH "roms/video/mda/mda.rom" +#define FONT_IBM_MDA_437_NORDIC_PATH "roms/video/mda/4733197.bin" +#define FONT_KAM_PATH "roms/video/mda/kam.bin" +#define FONT_KAMCL16_PATH "roms/video/mda/kamcl16.bin" +#define FONT_TULIP_DGA_PATH "roms/video/mda/tulip-dga-bios.bin" + typedef struct video_timings_t { int type; int write_b; @@ -182,6 +188,10 @@ extern bitmap_t *buffer32; #define efscrnsz_y (monitors[monitor_index_global].mon_efscrnsz_y) #define unscaled_size_x (monitors[monitor_index_global].mon_unscaled_size_x) #define unscaled_size_y (monitors[monitor_index_global].mon_unscaled_size_y) + +#define CGAPAL_CGA_START 16 // Where the 16-color cga text/composite starts + + extern PALETTE cgapal; extern PALETTE cgapal_mono[6]; #if 0 @@ -189,16 +199,15 @@ extern uint32_t pal_lookup[256]; #endif extern int video_fullscreen; extern int video_fullscreen_scale; -extern int video_fullscreen_first; -extern uint8_t fontdat[2048][8]; -extern uint8_t fontdatm[2048][16]; -extern uint8_t fontdat2[2048][8]; -extern uint8_t fontdatm2[2048][16]; -extern uint8_t fontdatw[512][32]; -extern uint8_t fontdat8x12[256][16]; -extern uint8_t fontdat12x18[256][36]; -extern dbcs_font_t *fontdatksc5601; -extern dbcs_font_t *fontdatksc5601_user; +extern uint8_t fontdat[2048][8]; /* IBM CGA font */ +extern uint8_t fontdatm[2048][16]; /* IBM MDA font */ +extern uint8_t fontdat2[2048][8]; /* IBM CGA 2nd instance font */ +extern uint8_t fontdatm2[2048][16]; /* IBM MDA 2nd instance font */ +extern uint8_t fontdatw[512][32]; /* Wyse700 font */ +extern uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ +extern uint8_t fontdat12x18[256][36]; /* IM1024 font */ +extern dbcs_font_t *fontdatksc5601; /* Korean KSC-5601 font */ +extern dbcs_font_t *fontdatksc5601_user; /* Korean KSC-5601 user defined font */ extern uint32_t *video_6to8; extern uint32_t *video_8togs; extern uint32_t *video_8to32; @@ -278,8 +287,8 @@ 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); -extern void loadfont_ex(char *s, int format, int offset); -extern void loadfont(char *s, int format); +extern void loadfont_ex(char *fn, int format, int offset); +extern void loadfont(char *fn, int format); extern int get_actual_size_x(void); extern int get_actual_size_y(void); @@ -349,11 +358,14 @@ extern const device_t chips_69000_onboard_device; /* Cirrus Logic GD54xx */ extern const device_t gd5401_isa_device; +extern const device_t gd5401_onboard_device; extern const device_t gd5402_isa_device; extern const device_t gd5402_onboard_device; extern const device_t gd5420_isa_device; +extern const device_t gd5420_onboard_device; extern const device_t gd5422_isa_device; extern const device_t gd5424_vlb_device; +extern const device_t gd5424_onboard_device; extern const device_t gd5426_isa_device; extern const device_t gd5426_diamond_speedstar_pro_a1_isa_device; extern const device_t gd5426_vlb_device; @@ -366,6 +378,7 @@ extern const device_t gd5428_boca_isa_device; extern const device_t gd5428_mca_device; extern const device_t gd5426_mca_device; extern const device_t gd5428_onboard_device; +extern const device_t gd5428_onboard_vlb_device; 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; @@ -386,9 +399,17 @@ extern const device_t gd5446_pci_device; extern const device_t gd5446_stb_pci_device; extern const device_t gd5480_pci_device; + +/* IBM CGA*/ +extern const device_t cga_device; + +/* pravetz CGA */ +extern const device_t cga_pravetz_device; + /* Compaq CGA */ extern const device_t compaq_cga_device; extern const device_t compaq_cga_2_device; +extern const device_t compaq_plasma_device; /* Olivetti OGC */ extern const device_t ogc_device; @@ -461,6 +482,7 @@ extern const device_t if386jega_device; /* Oak OTI-0x7 */ extern const device_t oti037c_device; +extern const device_t oti037_pbl300sx_device; extern const device_t oti067_device; extern const device_t oti067_acer386_device; extern const device_t oti067_ama932j_device; @@ -476,6 +498,9 @@ extern const device_t paradise_wd90c11_megapc_device; extern const device_t paradise_wd90c11_device; extern const device_t paradise_wd90c30_device; +/* Quadram Quadcolor I / I + II */ +extern const device_t quadcolor_device; + /* Realtek (S)VGA */ extern const device_t realtek_rtg3105_device; extern const device_t realtek_rtg3106_device; @@ -488,6 +513,7 @@ extern const device_t s3_metheus_86c928_isa_device; extern const device_t s3_metheus_86c928_vlb_device; extern const device_t s3_spea_mercury_lite_86c928_pci_device; extern const device_t s3_spea_mirage_86c801_isa_device; +extern const device_t s3_winner1000_805_isa_device; extern const device_t s3_86c805_onboard_vlb_device; extern const device_t s3_spea_mirage_86c805_vlb_device; extern const device_t s3_mirocrystal_8s_805_vlb_device; @@ -602,6 +628,11 @@ extern const device_t velocity_200_agp_device; /* Wyse 700 */ extern const device_t wy700_device; +/* Tandy */ +extern const device_t tandy_1000_video_device; +extern const device_t tandy_1000hx_video_device; +extern const device_t tandy_1000sl_video_device; + #endif #endif /*EMU_VIDEO_H*/ diff --git a/src/include/86box/zip.h b/src/include/86box/zip.h deleted file mode 100644 index 443ab1327..000000000 --- a/src/include/86box/zip.h +++ /dev/null @@ -1,149 +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 Iomega ZIP drive with SCSI(-like) - * commands, for both ATAPI and SCSI usage. - * - * - * - * Authors: Miran Grca, - * - * Copyright 2018-2025 Miran Grca. - */ - -#ifndef EMU_ZIP_H -#define EMU_ZIP_H - -#define ZIP_NUM 4 - -#define BUF_SIZE 32768 - -#define ZIP_TIME 10.0 - -#define ZIP_SECTORS (96 * 2048) - -#define ZIP_250_SECTORS (489532) - -#define ZIP_IMAGE_HISTORY 10 - -enum { - ZIP_BUS_DISABLED = 0, - ZIP_BUS_ATAPI = 5, - ZIP_BUS_SCSI = 6, - ZIP_BUS_USB = 7 -}; - -typedef struct zip_drive_t { - uint8_t id; - - union { - uint8_t res; - /* Reserved for other ID's. */ - uint8_t res0; - uint8_t res1; - uint8_t ide_channel; - uint8_t scsi_device_id; - }; - - uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */ - uint8_t bus_mode; /* Bit 0 = PIO suported; - Bit 1 = DMA supportd. */ - uint8_t read_only; /* Struct variable reserved for - media status. */ - uint8_t pad; - uint8_t pad0; - - FILE * 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; -} zip_drive_t; - -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 - - void * log; - - uint8_t * buffer; - uint8_t atapi_cdb[16]; - uint8_t current_cdb[16]; - uint8_t sense[256]; - - uint8_t id; - uint8_t cur_lun; - uint8_t pad0; - uint8_t pad1; - - uint16_t max_transfer_len; - uint16_t pad2; - - int requested_blocks; - int packet_status; - int total_length; - int do_page_save; - int unit_attention; - int request_pos; - int old_len; - int transition; - - uint32_t sector_pos; - uint32_t sector_len; - uint32_t packet_len; - uint32_t block_len; - - double callback; - - uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen); -} zip_t; - -extern zip_t *zip[ZIP_NUM]; -extern zip_drive_t zip_drives[ZIP_NUM]; -extern uint8_t atapi_zip_drives[8]; -extern uint8_t scsi_zip_drives[16]; - -#define zip_sense_error dev->sense[0] -#define zip_sense_key dev->sense[2] -#define zip_info *(uint32_t *) &(dev->sense[3]) -#define zip_asc dev->sense[12] -#define zip_ascq dev->sense[13] - -#ifdef __cplusplus -extern "C" { -#endif - -extern void zip_disk_close(const zip_t *dev); -extern void zip_disk_reload(const zip_t *dev); -extern void zip_insert(zip_t *dev); - -extern void zip_global_init(void); -extern void zip_hard_reset(void); - -extern void zip_reset(scsi_common_t *sc); -extern int zip_is_empty(const uint8_t id); -extern void zip_load(const zip_t *dev, const char *fn, const int skip_insert); -extern void zip_close(void); - -#ifdef __cplusplus -} -#endif - -#endif /*EMU_ZIP_H*/ diff --git a/src/io.c b/src/io.c index 9554c971d..45dd4cb3d 100644 --- a/src/io.c +++ b/src/io.c @@ -445,10 +445,10 @@ outb(uint16_t port, uint8_t val) } } - if (!found) { + if (!found || (port == 0x84)) { cycles -= io_delay; #ifdef USE_DYNAREC - if (cpu_use_dynarec && ((port == 0xeb) || (port == 0xed))) + if (cpu_use_dynarec && ((port == 0x84) || (port == 0xeb) || (port == 0xed))) update_tsc(); #endif } diff --git a/src/lpt.c b/src/lpt.c deleted file mode 100644 index 26174d96b..000000000 --- a/src/lpt.c +++ /dev/null @@ -1,264 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/io.h> -#include <86box/lpt.h> -#include <86box/pic.h> -#include <86box/sound.h> -#include <86box/prt_devs.h> -#include <86box/thread.h> -#include <86box/timer.h> -#include <86box/device.h> -#include <86box/network.h> - -lpt_port_t lpt_ports[PARALLEL_MAX]; - -const lpt_device_t lpt_none_device = { - .name = "None", - .internal_name = "none", - .init = NULL, - .close = NULL, - .write_data = NULL, - .write_ctrl = NULL, - .read_data = NULL, - .read_status = NULL, - .read_ctrl = NULL -}; - -static const struct { - const char *internal_name; - const lpt_device_t *device; -} lpt_devices[] = { - // clang-format off - {"none", &lpt_none_device }, - {"dss", &dss_device }, - {"lpt_dac", &lpt_dac_device }, - {"lpt_dac_stereo", &lpt_dac_stereo_device }, - {"text_prt", &lpt_prt_text_device }, - {"dot_matrix", &lpt_prt_escp_device }, - {"postscript", &lpt_prt_ps_device }, -#ifdef USE_PCL - {"pcl", &lpt_prt_pcl_device }, -#endif - {"plip", &lpt_plip_device }, - {"dongle_savquest", &lpt_hasp_savquest_device }, - {"", NULL } - // clang-format on -}; - -const char * -lpt_device_get_name(int id) -{ - if (strlen(lpt_devices[id].internal_name) == 0) - return NULL; - if (!lpt_devices[id].device) - return "None"; - return lpt_devices[id].device->name; -} - -const char * -lpt_device_get_internal_name(int id) -{ - if (strlen(lpt_devices[id].internal_name) == 0) - return NULL; - return lpt_devices[id].internal_name; -} - -int -lpt_device_get_from_internal_name(char *s) -{ - int c = 0; - - while (strlen(lpt_devices[c].internal_name) != 0) { - if (strcmp(lpt_devices[c].internal_name, s) == 0) - return c; - c++; - } - - return 0; -} - -void -lpt_devices_init(void) -{ - for (uint8_t i = 0; i < PARALLEL_MAX; i++) { - lpt_ports[i].dt = (lpt_device_t *) lpt_devices[lpt_ports[i].device].device; - - if (lpt_ports[i].dt && lpt_ports[i].dt->init) - lpt_ports[i].priv = lpt_ports[i].dt->init(&lpt_ports[i]); - } -} - -void -lpt_devices_close(void) -{ - lpt_port_t *dev; - - for (uint8_t i = 0; i < PARALLEL_MAX; i++) { - dev = &lpt_ports[i]; - - if (lpt_ports[i].dt && lpt_ports[i].dt->close) - dev->dt->close(dev->priv); - - dev->dt = NULL; - } -} - -void -lpt_write(uint16_t port, uint8_t val, void *priv) -{ - lpt_port_t *dev = (lpt_port_t *) priv; - - switch (port & 3) { - case 0: - if (dev->dt && dev->dt->write_data && dev->priv) - dev->dt->write_data(val, dev->priv); - dev->dat = val; - break; - - case 1: - break; - - case 2: - if (dev->dt && dev->dt->write_ctrl && dev->priv) - dev->dt->write_ctrl(val, dev->priv); - dev->ctrl = val; - dev->enable_irq = val & 0x10; - break; - - default: - break; - } -} - -uint8_t -lpt_read(uint16_t port, void *priv) -{ - uint8_t ret = 0xff; - lpt_port_t *dev = (lpt_port_t *) priv; - - switch (port & 3) { - case 0: - if (dev->dt && dev->dt->read_data && dev->priv) - ret = dev->dt->read_data(dev->priv); - else - ret = dev->dat; - break; - - case 1: - if (dev->dt && dev->dt->read_status && dev->priv) - ret = dev->dt->read_status(dev->priv) | 0x07; - else - ret = 0xdf; - break; - - case 2: - if (dev->dt && dev->dt->read_ctrl && dev->priv) - ret = (dev->dt->read_ctrl(dev->priv) & 0xef) | dev->enable_irq; - else - ret = 0xe0 | dev->ctrl | dev->enable_irq; - break; - - default: - break; - } - - return ret; -} - -uint8_t -lpt_read_port(int port, uint16_t reg) -{ - lpt_port_t *dev = &(lpt_ports[port]); - uint8_t ret = lpt_read(reg, dev); - - return ret; -} - -uint8_t -lpt_read_status(int port) -{ - lpt_port_t *dev = &(lpt_ports[port]); - uint8_t ret = 0xff; - - if (dev->dt && dev->dt->read_status && dev->priv) - ret = dev->dt->read_status(dev->priv) | 0x07; - else - ret = 0xdf; - - return ret; -} - -void -lpt_irq(void *priv, int raise) -{ - const lpt_port_t *dev = (lpt_port_t *) priv; - - if (dev->enable_irq && (dev->irq != 0xff)) { - if (raise) - picint(1 << dev->irq); - else - picintc(1 << dev->irq); - } -} - -void -lpt_init(void) -{ - uint16_t default_ports[PARALLEL_MAX] = { LPT1_ADDR, LPT2_ADDR, LPT_MDA_ADDR, LPT4_ADDR }; - uint8_t default_irqs[PARALLEL_MAX] = { LPT1_IRQ, LPT2_IRQ, LPT_MDA_IRQ, LPT4_IRQ }; - - for (uint8_t i = 0; i < PARALLEL_MAX; i++) { - lpt_ports[i].addr = 0xffff; - lpt_ports[i].irq = 0xff; - lpt_ports[i].enable_irq = 0x10; - - if (lpt_ports[i].enabled) { - lpt_port_setup(i, default_ports[i]); - lpt_port_irq(i, default_irqs[i]); - } - } -} - -void -lpt_port_setup(int i, uint16_t port) -{ - if (lpt_ports[i].enabled) { - if (lpt_ports[i].addr != 0xffff) - io_removehandler(lpt_ports[i].addr, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); - if (port != 0xffff) - io_sethandler(port, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); - lpt_ports[i].addr = port; - } else - lpt_ports[i].addr = 0xffff; -} - -void -lpt_port_irq(int i, uint8_t irq) -{ - if (lpt_ports[i].enabled) - lpt_ports[i].irq = irq; - else - lpt_ports[i].irq = 0xff; -} - -void -lpt_port_remove(int i) -{ - if (lpt_ports[i].enabled && (lpt_ports[i].addr != 0xffff)) { - io_removehandler(lpt_ports[i].addr, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); - lpt_ports[i].addr = 0xffff; - } -} - -void -lpt1_remove_ams(void) -{ - if (lpt_ports[0].enabled) - io_removehandler(lpt_ports[0].addr + 1, 0x0002, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[0]); -} diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index ff6a66801..63f9baf61 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -20,13 +20,14 @@ add_library(mch OBJECT machine_table.c m_xt.c m_xt_compaq.c + m_xt_laserxt.c m_xt_philips.c m_xt_t1000.c - m_xt_t1000_vid.c m_xt_xi8088.c m_xt_zenith.c m_pcjr.c m_amstrad.c + m_amstrad_pc5x86.c m_europc.c m_elt.c m_xt_olivetti.c @@ -36,7 +37,6 @@ add_library(mch OBJECT m_at_commodore.c m_at_grid.c m_at_t3100e.c - m_at_t3100e_vid.c m_ps1.c m_ps1_hdc.c m_ps2_isa.c @@ -55,24 +55,3 @@ add_library(mch OBJECT m_at_socket370.c m_at_misc.c ) - -if(AN430TX) - target_compile_definitions(mch PRIVATE USE_AN430TX) -endif() - -if(DESKPRO386) - target_compile_definitions(mch PRIVATE USE_DESKPRO386) -endif() - -if(LASERXT) - target_sources(mch PRIVATE m_xt_laserxt.c) - target_compile_definitions(mch PRIVATE USE_LASERXT) -endif() - -if(OLIVETTI) - target_compile_definitions(mch PRIVATE USE_OLIVETTI) -endif() - -if(OPEN_AT) - target_compile_definitions(mch PRIVATE USE_OPEN_AT) -endif() diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 3dba578bd..17bcb62bd 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -105,7 +105,7 @@ typedef struct amsvid_t { int cga_enabled; /* 1640 */ uint8_t cgacol; uint8_t cgamode; - uint8_t stat; + uint8_t status; uint8_t plane_write; /* 1512/200 */ uint8_t plane_read; /* 1512/200 */ uint8_t border; /* 1512/200 */ @@ -113,18 +113,17 @@ typedef struct amsvid_t { int fontbase; /* 1512/200 */ int linepos; int displine; - int sc; + int scanline; int vc; int cgadispon; - int con; - int coff; + int cursorvisible; int cursoron; int cgablink; int vsynctime; int fullchange; int vadj; - uint16_t ma; - uint16_t maback; + uint16_t memaddr; + uint16_t memaddr_backup; int dispon; int blink; uint64_t dispontime; /* 1512/1640 */ @@ -156,7 +155,9 @@ typedef struct amstrad_t { /* Video stuff. */ amsvid_t *vid; + fdc_t *fdc; + lpt_t *lpt; } amstrad_t; uint32_t amstrad_latch; @@ -291,7 +292,7 @@ vid_in_1512(uint16_t addr, void *priv) break; case 0x03da: - ret = vid->stat; + ret = vid->status; break; default: @@ -340,7 +341,7 @@ static void vid_poll_1512(void *priv) { amsvid_t *vid = (amsvid_t *) priv; - uint16_t ca = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff; + uint16_t cursoraddr = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff; int drawcursor; int x; int c; @@ -354,13 +355,13 @@ vid_poll_1512(void *priv) uint16_t dat4; int cols[4]; int col; - int oldsc; + int scanline_old; if (!vid->linepos) { timer_advance_u64(&vid->timer, vid->dispofftime); - vid->stat |= 1; + vid->status |= 1; vid->linepos = 1; - oldsc = vid->sc; + scanline_old = vid->scanline; if (vid->dispon) { if (vid->displine < vid->firstline) { vid->firstline = vid->displine; @@ -370,26 +371,26 @@ vid_poll_1512(void *priv) for (c = 0; c < 8; c++) { if ((vid->cgamode & 0x12) == 0x12) { buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = (vid->border & 15) + 16; - if (vid->cgamode & 1) { + if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) { buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = 0; } else { buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = 0; } } else { buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = (vid->cgacol & 15) + 16; - if (vid->cgamode & 1) { + if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) { buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = (vid->cgacol & 15) + 16; } else { buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = (vid->cgacol & 15) + 16; } } } - if (vid->cgamode & 1) { + if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) { for (x = 0; x < 80; x++) { - chr = vid->vram[(vid->ma << 1) & 0x3fff]; - attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff]; - drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron); - if (vid->cgamode & 0x20) { + chr = vid->vram[(vid->memaddr<< 1) & 0x3fff]; + attr = vid->vram[((vid->memaddr<< 1) + 1) & 0x3fff]; + drawcursor = ((vid->memaddr== cursoraddr) && vid->cursorvisible && vid->cursoron); + if (vid->cgamode & CGA_MODE_FLAG_BLINK) { cols[1] = (attr & 15) + 16; cols[0] = ((attr >> 4) & 7) + 16; if ((vid->blink & 16) && (attr & 0x80) && !drawcursor) @@ -400,21 +401,23 @@ vid_poll_1512(void *priv) } if (drawcursor) { for (c = 0; c < 8; c++) { - buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[vid->fontbase + chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[vid->fontbase + chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } } else { for (c = 0; c < 8; c++) { - buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[vid->fontbase + chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[vid->fontbase + chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } - vid->ma++; + vid->memaddr++; } - } else if (!(vid->cgamode & 2)) { + } else if (!(vid->cgamode & CGA_MODE_FLAG_GRAPHICS)) { for (x = 0; x < 40; x++) { - chr = vid->vram[(vid->ma << 1) & 0x3fff]; - attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff]; - drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron); - if (vid->cgamode & 0x20) { + chr = vid->vram[(vid->memaddr<< 1) & 0x3fff]; + attr = vid->vram[((vid->memaddr<< 1) + 1) & 0x3fff]; + drawcursor = ((vid->memaddr == cursoraddr) + && vid->cursorvisible && vid->cursoron); + + if (vid->cgamode & CGA_MODE_FLAG_BLINK) { cols[1] = (attr & 15) + 16; cols[0] = ((attr >> 4) & 7) + 16; if ((vid->blink & 16) && (attr & 0x80)) @@ -423,21 +426,21 @@ vid_poll_1512(void *priv) cols[1] = (attr & 15) + 16; cols[0] = (attr >> 4) + 16; } - vid->ma++; + vid->memaddr++; if (drawcursor) { for (c = 0; c < 8; c++) { - buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[vid->fontbase + chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[vid->fontbase + chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } } else { for (c = 0; c < 8; c++) { - buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[vid->fontbase + chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[vid->fontbase + chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } } - } else if (!(vid->cgamode & 16)) { + } else if (!(vid->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) { cols[0] = (vid->cgacol & 15) | 16; col = (vid->cgacol & 16) ? 24 : 16; - if (vid->cgamode & 4) { + if (vid->cgamode & CGA_MODE_FLAG_BW) { cols[1] = col | 3; cols[2] = col | 4; cols[3] = col | 7; @@ -451,8 +454,8 @@ vid_poll_1512(void *priv) cols[3] = col | 6; } for (x = 0; x < 40; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1]; - vid->ma++; + dat = (vid->vram[((vid->memaddr<< 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000)] << 8) | vid->vram[((vid->memaddr<< 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000) + 1]; + vid->memaddr++; for (c = 0; c < 8; c++) { buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; dat <<= 2; @@ -460,13 +463,13 @@ vid_poll_1512(void *priv) } } else { for (x = 0; x < 40; x++) { - ca = ((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000); - dat = (vid->vram[ca] << 8) | vid->vram[ca + 1]; - dat2 = (vid->vram[ca + 0x4000] << 8) | vid->vram[ca + 0x4001]; - dat3 = (vid->vram[ca + 0x8000] << 8) | vid->vram[ca + 0x8001]; - dat4 = (vid->vram[ca + 0xc000] << 8) | vid->vram[ca + 0xc001]; + cursoraddr = ((vid->memaddr<< 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000); + dat = (vid->vram[cursoraddr] << 8) | vid->vram[cursoraddr + 1]; + dat2 = (vid->vram[cursoraddr + 0x4000] << 8) | vid->vram[cursoraddr + 0x4001]; + dat3 = (vid->vram[cursoraddr + 0x8000] << 8) | vid->vram[cursoraddr + 0x8001]; + dat4 = (vid->vram[cursoraddr + 0xc000] << 8) | vid->vram[cursoraddr + 0xc001]; - vid->ma++; + vid->memaddr++; for (c = 0; c < 16; c++) { buffer32->line[vid->displine << 1][(x << 4) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] = (((dat >> 15) | ((dat2 >> 15) << 1) | ((dat3 >> 15) << 2) | ((dat4 >> 15) << 3)) & (vid->cgacol & 15)) + 16; dat <<= 1; @@ -478,7 +481,7 @@ vid_poll_1512(void *priv) } } else { cols[0] = ((vid->cgamode & 0x12) == 0x12) ? 0 : (vid->cgacol & 15) + 16; - if (vid->cgamode & 1) { + if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) { hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 3) + 16, cols[0]); hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 3) + 16, cols[0]); } else { @@ -487,7 +490,7 @@ vid_poll_1512(void *priv) } } - if (vid->cgamode & 1) + if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) x = (vid->crtc[1] << 3) + 16; else x = (vid->crtc[1] << 4) + 16; @@ -495,9 +498,9 @@ vid_poll_1512(void *priv) video_process_8(x, vid->displine << 1); video_process_8(x, (vid->displine << 1) + 1); - vid->sc = oldsc; + vid->scanline = scanline_old; if (vid->vsynctime) - vid->stat |= 8; + vid->status |= 8; vid->displine++; if (vid->displine >= 360) vid->displine = 0; @@ -506,30 +509,29 @@ vid_poll_1512(void *priv) if ((vid->lastline - vid->firstline) == 199) vid->dispon = 0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/ if (vid->dispon) - vid->stat &= ~1; + vid->status &= ~1; vid->linepos = 0; if (vid->vsynctime) { vid->vsynctime--; if (!vid->vsynctime) - vid->stat &= ~8; + vid->status &= ~8; } - if (vid->sc == (vid->crtc[11] & 31)) { - vid->con = 0; - vid->coff = 1; + if (vid->scanline == (vid->crtc[11] & 31)) { + vid->cursorvisible = 0; } if (vid->vadj) { - vid->sc++; - vid->sc &= 31; - vid->ma = vid->maback; + vid->scanline++; + vid->scanline &= 31; + vid->memaddr= vid->memaddr_backup; vid->vadj--; if (!vid->vadj) { vid->dispon = 1; - vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff; - vid->sc = 0; + vid->memaddr= vid->memaddr_backup = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff; + vid->scanline = 0; } - } else if (vid->sc == vid->crtc[9]) { - vid->maback = vid->ma; - vid->sc = 0; + } else if (vid->scanline == vid->crtc[9]) { + vid->memaddr_backup = vid->memaddr; + vid->scanline = 0; vid->vc++; vid->vc &= 127; @@ -547,7 +549,7 @@ vid_poll_1512(void *priv) vid->displine = 0; vid->vsynctime = 46; - if (vid->cgamode & 1) + if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) x = (vid->crtc[1] << 3) + 16; else x = (vid->crtc[1] << 4) + 16; @@ -584,15 +586,15 @@ vid_poll_1512(void *priv) video_res_x = xsize; video_res_y = ysize; - if (vid->cgamode & 1) { + if (vid->cgamode & CGA_MODE_FLAG_HIGHRES) { video_res_x /= 8; video_res_y /= vid->crtc[9] + 1; video_bpp = 0; - } else if (!(vid->cgamode & 2)) { + } else if (!(vid->cgamode & CGA_MODE_FLAG_GRAPHICS)) { video_res_x /= 16; video_res_y /= vid->crtc[9] + 1; video_bpp = 0; - } else if (!(vid->cgamode & 16)) { + } else if (!(vid->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) { video_res_x /= 2; video_bpp = 2; } else { @@ -604,12 +606,12 @@ vid_poll_1512(void *priv) vid->blink++; } } else { - vid->sc++; - vid->sc &= 31; - vid->ma = vid->maback; + vid->scanline++; + vid->scanline &= 31; + vid->memaddr= vid->memaddr_backup; } - if (vid->sc == (vid->crtc[10] & 31)) - vid->con = 1; + if (vid->scanline == (vid->crtc[10] & 31)) + vid->cursorvisible = 1; } } @@ -1046,7 +1048,7 @@ vid_in_200(uint16_t addr, void *priv) switch (addr) { case 0x03b8: - return (mda->ctrl); + return (mda->mode); case 0x03d8: return (cga->cgamode); @@ -1108,9 +1110,9 @@ vid_out_200(uint16_t addr, uint8_t val, void *priv) } return; case 0x3b8: - old = mda->ctrl; - mda->ctrl = val; - if ((mda->ctrl ^ old) & 3) + old = mda->mode; + mda->mode = val; + if ((mda->mode ^ old) & 3) mda_recalctimings(mda); vid->crtc_index &= 0x1F; vid->crtc_index |= 0x80; @@ -1212,11 +1214,11 @@ vid_out_200(uint16_t addr, uint8_t val, void *priv) static void lcd_draw_char_80(amsvid_t *vid, uint32_t *buffer, uint8_t chr, - uint8_t attr, int drawcursor, int blink, int sc, + uint8_t attr, int drawcursor, int blink, int scanline, int mode160, uint8_t control) { int c; - uint8_t bits = fontdat[chr + vid->cga.fontbase][sc]; + uint8_t bits = fontdat[chr + vid->cga.fontbase][scanline]; uint8_t bright = 0; uint16_t mask; @@ -1247,10 +1249,10 @@ lcd_draw_char_80(amsvid_t *vid, uint32_t *buffer, uint8_t chr, static void lcd_draw_char_40(amsvid_t *vid, uint32_t *buffer, uint8_t chr, - uint8_t attr, int drawcursor, int blink, int sc, + uint8_t attr, int drawcursor, int blink, int scanline, uint8_t control) { - uint8_t bits = fontdat[chr + vid->cga.fontbase][sc]; + uint8_t bits = fontdat[chr + vid->cga.fontbase][scanline]; uint8_t mask = 0x80; if (attr & 8) /* bright */ @@ -1271,92 +1273,91 @@ static void lcdm_poll(amsvid_t *vid) { mda_t *mda = &vid->mda; - uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; + uint16_t cursoraddr = (mda->crtc[MDA_CRTC_CURSOR_ADDR_LOW] | (mda->crtc[MDA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff; int drawcursor; int x; int oldvc; uint8_t chr; uint8_t attr; - int oldsc; + int scanline_old; int blink; if (!mda->linepos) { timer_advance_u64(&vid->timer, mda->dispofftime); - mda->stat |= 1; + mda->status |= 1; mda->linepos = 1; - oldsc = mda->sc; - if ((mda->crtc[8] & 3) == 3) - mda->sc = (mda->sc << 1) & 7; + scanline_old = mda->scanline; + if ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3) + mda->scanline = (mda->scanline << 1) & 7; if (mda->dispon) { if (mda->displine < mda->firstline) mda->firstline = mda->displine; mda->lastline = mda->displine; - for (x = 0; x < mda->crtc[1]; x++) { - chr = mda->vram[(mda->ma << 1) & 0xfff]; - attr = mda->vram[((mda->ma << 1) + 1) & 0xfff]; - drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron); - blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); + for (x = 0; x < mda->crtc[MDA_CRTC_HDISP]; x++) { + chr = mda->vram[(mda->memaddr<< 1) & 0xfff]; + attr = mda->vram[((mda->memaddr<< 1) + 1) & 0xfff]; + drawcursor = ((mda->memaddr== cursoraddr) && mda->cursorvisible && mda->cursoron); + blink = ((mda->blink & 16) && (mda->mode & MDA_MODE_BLINK) && (attr & 0x80) && !drawcursor); - lcd_draw_char_80(vid, &(buffer32->line[mda->displine])[x * 8], chr, attr, drawcursor, blink, mda->sc, 0, mda->ctrl); - mda->ma++; + lcd_draw_char_80(vid, &(buffer32->line[mda->displine])[x * 8], chr, attr, drawcursor, blink, mda->scanline, 0, mda->mode); + mda->memaddr++; } } - mda->sc = oldsc; - if (mda->vc == mda->crtc[7] && !mda->sc) - mda->stat |= 8; + mda->scanline = scanline_old; + if (mda->vc == mda->crtc[MDA_CRTC_VSYNC] && !mda->scanline) + mda->status |= 8; mda->displine++; if (mda->displine >= 500) mda->displine = 0; } else { timer_advance_u64(&vid->timer, mda->dispontime); if (mda->dispon) - mda->stat &= ~1; + mda->status &= ~1; mda->linepos = 0; if (mda->vsynctime) { mda->vsynctime--; if (!mda->vsynctime) - mda->stat &= ~8; + mda->status &= ~8; } - if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) { - mda->con = 0; - mda->coff = 1; + if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_END] & 31) || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 && mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_END] & 31) >> 1))) { + mda->cursorvisible = 0; } if (mda->vadj) { - mda->sc++; - mda->sc &= 31; - mda->ma = mda->maback; + mda->scanline++; + mda->scanline &= 31; + mda->memaddr= mda->memaddr_backup; mda->vadj--; if (!mda->vadj) { mda->dispon = 1; - mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - mda->sc = 0; + mda->memaddr= mda->memaddr_backup = (mda->crtc[MDA_CRTC_START_ADDR_LOW] | (mda->crtc[MDA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + mda->scanline = 0; } - } else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) { - mda->maback = mda->ma; - mda->sc = 0; + } else if (mda->scanline == mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR] || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 && mda->scanline == (mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR] >> 1))) { + mda->memaddr_backup = mda->memaddr; + mda->scanline = 0; oldvc = mda->vc; mda->vc++; mda->vc &= 127; - if (mda->vc == mda->crtc[6]) + if (mda->vc == mda->crtc[MDA_CRTC_VDISP]) mda->dispon = 0; - if (oldvc == mda->crtc[4]) { + if (oldvc == mda->crtc[MDA_CRTC_VTOTAL]) { mda->vc = 0; - mda->vadj = mda->crtc[5]; + mda->vadj = mda->crtc[MDA_CRTC_VTOTAL_ADJUST]; if (!mda->vadj) mda->dispon = 1; if (!mda->vadj) - mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - if ((mda->crtc[10] & 0x60) == 0x20) + mda->memaddr= mda->memaddr_backup = (mda->crtc[MDA_CRTC_START_ADDR_LOW] | (mda->crtc[MDA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + if ((mda->crtc[MDA_CRTC_CURSOR_START] & 0x60) == 0x20) mda->cursoron = 0; else mda->cursoron = mda->blink & 16; } - if (mda->vc == mda->crtc[7]) { + if (mda->vc == mda->crtc[MDA_CRTC_VSYNC]) { mda->dispon = 0; mda->displine = 0; mda->vsynctime = 16; - if (mda->crtc[7]) { - x = mda->crtc[1] * 8; + if (mda->crtc[MDA_CRTC_VSYNC]) { + x = mda->crtc[MDA_CRTC_HDISP] * 8; mda->lastline++; if ((x != xsize) || ((mda->lastline - mda->firstline) != ysize) || video_force_resize_get()) { xsize = x; @@ -1372,8 +1373,8 @@ lcdm_poll(amsvid_t *vid) } video_blit_memtoscreen(0, mda->firstline, xsize, ysize); frames++; - video_res_x = mda->crtc[1]; - video_res_y = mda->crtc[6]; + video_res_x = mda->crtc[MDA_CRTC_HDISP]; + video_res_y = mda->crtc[MDA_CRTC_VDISP]; video_bpp = 0; } mda->firstline = 1000; @@ -1381,12 +1382,12 @@ lcdm_poll(amsvid_t *vid) mda->blink++; } } else { - mda->sc++; - mda->sc &= 31; - mda->ma = mda->maback; + mda->scanline++; + mda->scanline &= 31; + mda->memaddr= mda->memaddr_backup; } - if (mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1))) - mda->con = 1; + if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_START] & 31) || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 && mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_START] & 31) >> 1))) + mda->cursorvisible = 1; } } @@ -1402,19 +1403,19 @@ lcdc_poll(amsvid_t *vid) uint8_t chr; uint8_t attr; uint16_t dat; - int oldsc; - uint16_t ca; + int scanline_old; + uint16_t cursoraddr; int blink; - ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; + cursoraddr = (cga->crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (cga->crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff; if (!cga->linepos) { timer_advance_u64(&vid->timer, cga->dispofftime); cga->cgastat |= 1; cga->linepos = 1; - oldsc = cga->sc; - if ((cga->crtc[8] & 3) == 3) - cga->sc = ((cga->sc << 1) + cga->oddeven) & 7; + scanline_old = cga->scanline; + if ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3) + cga->scanline = ((cga->scanline << 1) + cga->oddeven) & 7; if (cga->cgadispon) { if (cga->displine < cga->firstline) { cga->firstline = cga->displine; @@ -1422,30 +1423,30 @@ lcdc_poll(amsvid_t *vid) } cga->lastline = cga->displine; - if (cga->cgamode & 1) { - for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) { + for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) { chr = cga->charbuffer[x << 1]; attr = cga->charbuffer[(x << 1) + 1]; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - blink = ((cga->cgablink & 16) && (cga->cgamode & 0x20) && (attr & 0x80) && !drawcursor); - lcd_draw_char_80(vid, &(buffer32->line[cga->displine << 1])[x * 8], chr, attr, drawcursor, blink, cga->sc, cga->cgamode & 0x40, cga->cgamode); - lcd_draw_char_80(vid, &(buffer32->line[(cga->displine << 1) + 1])[x * 8], chr, attr, drawcursor, blink, cga->sc, cga->cgamode & 0x40, cga->cgamode); - cga->ma++; + drawcursor = ((cga->memaddr == cursoraddr) && cga->cursorvisible && cga->cursoron); + blink = ((cga->cgablink & 16) && (cga->cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor); + lcd_draw_char_80(vid, &(buffer32->line[cga->displine << 1])[x * 8], chr, attr, drawcursor, blink, cga->scanline, cga->cgamode & 0x40, cga->cgamode); + lcd_draw_char_80(vid, &(buffer32->line[(cga->displine << 1) + 1])[x * 8], chr, attr, drawcursor, blink, cga->scanline, cga->cgamode & 0x40, cga->cgamode); + cga->memaddr++; } - } else if (!(cga->cgamode & 2)) { - for (x = 0; x < cga->crtc[1]; x++) { - chr = cga->vram[(cga->ma << 1) & 0x3fff]; - attr = cga->vram[((cga->ma << 1) + 1) & 0x3fff]; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - blink = ((cga->cgablink & 16) && (cga->cgamode & 0x20) && (attr & 0x80) && !drawcursor); - lcd_draw_char_40(vid, &(buffer32->line[cga->displine << 1])[x * 16], chr, attr, drawcursor, blink, cga->sc, cga->cgamode); - lcd_draw_char_40(vid, &(buffer32->line[(cga->displine << 1) + 1])[x * 16], chr, attr, drawcursor, blink, cga->sc, cga->cgamode); - cga->ma++; + } else if (!(cga->cgamode & CGA_MODE_FLAG_GRAPHICS)) { + for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) { + chr = cga->vram[(cga->memaddr << 1) & 0x3fff]; + attr = cga->vram[((cga->memaddr << 1) + 1) & 0x3fff]; + drawcursor = ((cga->memaddr == cursoraddr) && cga->cursorvisible && cga->cursoron); + blink = ((cga->cgablink & 16) && (cga->cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor); + lcd_draw_char_40(vid, &(buffer32->line[cga->displine << 1])[x * 16], chr, attr, drawcursor, blink, cga->scanline, cga->cgamode); + lcd_draw_char_40(vid, &(buffer32->line[(cga->displine << 1) + 1])[x * 16], chr, attr, drawcursor, blink, cga->scanline, cga->cgamode); + cga->memaddr++; } } else { /* Graphics mode */ - for (x = 0; x < cga->crtc[1]; x++) { - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; - cga->ma++; + for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) { + dat = (cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 1) * 0x2000)] << 8) | cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 1) * 0x2000) + 1]; + cga->memaddr++; for (uint8_t c = 0; c < 16; c++) { buffer32->line[cga->displine << 1][(x << 4) + c] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + c] = (dat & 0x8000) ? blue : green; dat <<= 1; @@ -1453,22 +1454,22 @@ lcdc_poll(amsvid_t *vid) } } } else { - if (cga->cgamode & 1) { - hline(buffer32, 0, (cga->displine << 1), (cga->crtc[1] << 3), green); - hline(buffer32, 0, (cga->displine << 1) + 1, (cga->crtc[1] << 3), green); + if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) { + hline(buffer32, 0, (cga->displine << 1), (cga->crtc[CGA_CRTC_HDISP] << 3), green); + hline(buffer32, 0, (cga->displine << 1) + 1, (cga->crtc[CGA_CRTC_HDISP] << 3), green); } else { - hline(buffer32, 0, (cga->displine << 1), (cga->crtc[1] << 4), green); - hline(buffer32, 0, (cga->displine << 1) + 1, (cga->crtc[1] << 4), green); + hline(buffer32, 0, (cga->displine << 1), (cga->crtc[CGA_CRTC_HDISP] << 4), green); + hline(buffer32, 0, (cga->displine << 1) + 1, (cga->crtc[CGA_CRTC_HDISP] << 4), green); } } - if (cga->cgamode & 1) - x = (cga->crtc[1] << 3); + if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) + x = (cga->crtc[CGA_CRTC_HDISP] << 3); else - x = (cga->crtc[1] << 4); + x = (cga->crtc[CGA_CRTC_HDISP] << 4); - cga->sc = oldsc; - if (cga->vc == cga->crtc[7] && !cga->sc) + cga->scanline = scanline_old; + if (cga->vc == cga->crtc[CGA_CRTC_VSYNC] && !cga->scanline) cga->cgastat |= 8; cga->displine++; if (cga->displine >= 360) @@ -1481,54 +1482,53 @@ lcdc_poll(amsvid_t *vid) 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))) { - cga->con = 0; - cga->coff = 1; + if (cga->scanline == (cga->crtc[CGA_CRTC_CURSOR_END] & 31) || ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && cga->scanline == ((cga->crtc[CGA_CRTC_CURSOR_END] & 31) >> 1))) { + cga->cursorvisible = 0; } - if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1)) - cga->maback = cga->ma; + if ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && cga->scanline == (cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1)) + cga->memaddr_backup = cga->memaddr; if (cga->vadj) { - cga->sc++; - cga->sc &= 31; - cga->ma = cga->maback; + cga->scanline++; + cga->scanline &= 31; + cga->memaddr = cga->memaddr_backup; cga->vadj--; if (!cga->vadj) { cga->cgadispon = 1; - cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; - cga->sc = 0; + cga->memaddr = cga->memaddr_backup = (cga->crtc[CGA_CRTC_START_ADDR_LOW] | (cga->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + cga->scanline = 0; } - } else if (cga->sc == cga->crtc[9]) { - cga->maback = cga->ma; - cga->sc = 0; + } else if (cga->scanline == cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR]) { + cga->memaddr_backup = cga->memaddr; + cga->scanline = 0; oldvc = cga->vc; cga->vc++; cga->vc &= 127; - if (cga->vc == cga->crtc[6]) + if (cga->vc == cga->crtc[CGA_CRTC_VDISP]) cga->cgadispon = 0; - if (oldvc == cga->crtc[4]) { + if (oldvc == cga->crtc[CGA_CRTC_VTOTAL]) { cga->vc = 0; - cga->vadj = cga->crtc[5]; + cga->vadj = cga->crtc[CGA_CRTC_VTOTAL_ADJUST]; if (!cga->vadj) cga->cgadispon = 1; if (!cga->vadj) - cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; - if ((cga->crtc[10] & 0x60) == 0x20) + cga->memaddr = cga->memaddr_backup = (cga->crtc[CGA_CRTC_START_ADDR_LOW] | (cga->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + if ((cga->crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) cga->cursoron = 0; else cga->cursoron = cga->cgablink & 8; } - if (cga->vc == cga->crtc[7]) { + if (cga->vc == cga->crtc[CGA_CRTC_VSYNC]) { cga->cgadispon = 0; cga->displine = 0; cga->vsynctime = 16; - if (cga->crtc[7]) { - if (cga->cgamode & 1) - x = (cga->crtc[1] << 3); + if (cga->crtc[CGA_CRTC_VSYNC]) { + if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) + x = (cga->crtc[CGA_CRTC_HDISP] << 3); else - x = (cga->crtc[1] << 4); + x = (cga->crtc[CGA_CRTC_HDISP] << 4); cga->lastline++; xs_temp = x; @@ -1540,7 +1540,7 @@ lcdc_poll(amsvid_t *vid) if (ys_temp < 32) ys_temp = 400; - if ((cga->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { + if ((cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { xsize = xs_temp; ysize = ys_temp; set_screen_size(xsize, ysize); @@ -1557,15 +1557,15 @@ lcdc_poll(amsvid_t *vid) video_res_x = xsize; video_res_y = ysize; - if (cga->cgamode & 1) { + if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) { video_res_x /= 8; - video_res_y /= cga->crtc[9] + 1; + video_res_y /= cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1; video_bpp = 0; - } else if (!(cga->cgamode & 2)) { + } else if (!(cga->cgamode & CGA_MODE_FLAG_GRAPHICS)) { video_res_x /= 16; - video_res_y /= cga->crtc[9] + 1; + video_res_y /= cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1; video_bpp = 0; - } else if (!(cga->cgamode & 16)) { + } else if (!(cga->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) { video_res_x /= 2; video_bpp = 2; } else @@ -1577,17 +1577,17 @@ lcdc_poll(amsvid_t *vid) cga->oddeven ^= 1; } } else { - cga->sc++; - cga->sc &= 31; - cga->ma = cga->maback; + cga->scanline++; + cga->scanline &= 31; + cga->memaddr = cga->memaddr_backup; } 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))) - cga->con = 1; - if (cga->cgadispon && (cga->cgamode & 1)) { - for (x = 0; x < (cga->crtc[1] << 1); x++) - cga->charbuffer[x] = cga->vram[((cga->ma << 1) + x) & 0x3fff]; + if (cga->scanline == (cga->crtc[CGA_CRTC_CURSOR_START] & 31) || ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && cga->scanline == ((cga->crtc[CGA_CRTC_CURSOR_START] & 31) >> 1))) + cga->cursorvisible = 1; + if (cga->cgadispon && (cga->cgamode & CGA_MODE_FLAG_HIGHRES)) { + for (x = 0; x < (cga->crtc[CGA_CRTC_HDISP] << 1); x++) + cga->charbuffer[x] = cga->vram[((cga->memaddr << 1) + x) & 0x3fff]; } } } @@ -2247,7 +2247,7 @@ ams_write(uint16_t port, uint8_t val, void *priv) case 0x0378: case 0x0379: case 0x037a: - lpt_write(port, val, &lpt_ports[0]); + lpt_write(port, val, ams->lpt); break; case 0xdead: @@ -2267,7 +2267,7 @@ ams_read(uint16_t port, void *priv) switch (port) { case 0x0378: - ret = lpt_read(port, &lpt_ports[0]); + ret = lpt_read(port, ams->lpt); break; case 0x0379: /* printer control, also set LK1-3. @@ -2281,11 +2281,11 @@ ams_read(uint16_t port, void *priv) * 1 Italian Language. * 0 Diagnostic Mode. */ - ret = (lpt_read(port, &lpt_ports[0]) & 0xf8) | ams->language; + ret = (lpt_read(port, ams->lpt) & 0xf8) | ams->language; break; case 0x037a: /* printer status */ - ret = lpt_read(port, &lpt_ports[0]) & 0x1f; + ret = lpt_read(port, ams->lpt) & 0x1f; switch (ams->type) { case AMS_PC1512: @@ -2886,8 +2886,10 @@ machine_amstrad_init(const machine_t *model, int type) nmi_init(); - lpt1_remove_ams(); - lpt2_remove(); + ams->lpt = device_add_inst(&lpt_port_device, 1); + + lpt1_remove_ams(ams->lpt); + lpt_set_next_inst(255); io_sethandler(0x0378, 3, ams_read, NULL, NULL, ams_write, NULL, NULL, ams); @@ -2936,7 +2938,7 @@ machine_amstrad_init(const machine_t *model, int type) break; case AMS_PC1640: - loadfont("roms/video/mda/mda.rom", 0); + loadfont(FONT_IBM_MDA_437_PATH, 0); device_context(&vid_1640_device); ams->language = device_get_config_int("language"); vid_init_1640(ams); @@ -2999,7 +3001,7 @@ machine_amstrad_init(const machine_t *model, int type) mouse_set_poll(ms_poll, ams); } - standalone_gameport_type = &gameport_device; + standalone_gameport_type = &gameport_200_device; } int diff --git a/src/machine/m_amstrad_pc5x86.c b/src/machine/m_amstrad_pc5x86.c new file mode 100644 index 000000000..eafa06c1e --- /dev/null +++ b/src/machine/m_amstrad_pc5x86.c @@ -0,0 +1,68 @@ +/* + * 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. + * + * Amstrad PC5086 and PC5286 emulation. + * + * Authors: Miran Grca, + * + * Copyright 2025 Miran Grca. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the: + * + * Free Software Foundation, Inc. + * 59 Temple Place - Suite 330 + * Boston, MA 02111-1307 + * USA. + */ +#include +#include +#include <86box/86box.h> +#include "cpu.h" +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/timer.h> +#include <86box/chipset.h> +#include <86box/machine.h> +#include <86box/nvr.h> +#include <86box/keyboard.h> +#include <86box/sio.h> + +int +machine_pc5086_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/pc5086/sys_rom.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_common_init(model); + + device_add(&ct_82c100_device); + device_add(&f82c710_pc5086_device); + + device_add(&kbc_xt_device); + + device_add(&amstrad_megapc_nvr_device); /* NVR that is initialized to all 0x00's. */ + + return ret; +} diff --git a/src/machine/m_at.c b/src/machine/m_at.c index 86fbe3776..09cd9d5cd 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -95,7 +95,7 @@ machine_at_init(const machine_t *model) { machine_at_common_init(model); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); } static void @@ -103,7 +103,7 @@ machine_at_ibm_common_init(const machine_t *model) { machine_at_common_init_ex(model, 1); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); mem_remap_top(384); @@ -116,7 +116,7 @@ machine_at_ps2_init(const machine_t *model) { machine_at_common_init(model); - device_add(&keyboard_ps2_device); + device_add(&kbc_ps2_device); } void @@ -154,32 +154,68 @@ machine_at_ps2_ide_init(const machine_t *model) static const device_config_t ibmat_config[] = { // clang-format off { - .name = "bios", - .description = "BIOS Version", - .type = CONFIG_BIOS, + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, .default_string = "ibm5170_111585", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .bios = { - { .name = "62X082x (11/15/85)", .internal_name = "ibm5170_111585", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmat/BIOS_5170_15NOV85_U27.BIN", "roms/machines/ibmat/BIOS_5170_15NOV85_U47.BIN", "" } }, + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { + .name = "62X082x (11/15/85)", + .internal_name = "ibm5170_111585", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 65536, + .files = { "roms/machines/ibmat/BIOS_5170_15NOV85_U27.BIN", "roms/machines/ibmat/BIOS_5170_15NOV85_U47.BIN", "" } + }, + { + .name = "61X9266 (11/15/85) (Alt)", + .internal_name = "ibm5170_111585_alt", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 65536, + .files = { "roms/machines/ibmat/BIOS_5170_15NOV85_U27_61X9266.BIN", "roms/machines/ibmat/BIOS_5170_15NOV85_U47_61X9265.BIN", "" } + }, + { + .name = "648009x (06/10/85)", + .internal_name = "ibm5170_061085", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 65536, + .files = { "roms/machines/ibmat/BIOS_5170_10JUN85_U27.BIN", "roms/machines/ibmat/BIOS_5170_10JUN85_U47.BIN", "" } + }, + { + .name = "618102x (01/10/84)", + .internal_name = "ibm5170_011084", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 65536, + .files = { "roms/machines/ibmat/BIOS_5170_10JAN84_U27.BIN", "roms/machines/ibmat/BIOS_5170_10JAN84_U47.BIN", "" } + }, + // The following are Diagnostic ROMs. + { + .name = "Supersoft Diagnostics", + .internal_name = "diag_supersoft", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 2, + .size = 65536, + .files = { "roms/machines/diagnostic/5170_EVEN_LOW_U27_27256.bin", "roms/machines/diagnostic/5170_ODD_HIGH_U47_27256.bin", "" } + }, - { .name = "61X9266 (11/15/85) (Alt)", .internal_name = "ibm5170_111585_alt", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmat/BIOS_5170_15NOV85_U27_61X9266.BIN", "roms/machines/ibmat/BIOS_5170_15NOV85_U47_61X9265.BIN", "" } }, - - { .name = "648009x (06/10/85)", .internal_name = "ibm5170_061085", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmat/BIOS_5170_10JUN85_U27.BIN", "roms/machines/ibmat/BIOS_5170_10JUN85_U47.BIN", "" } }, - - { .name = "618102x (01/10/84)", .internal_name = "ibm5170_011084", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmat/BIOS_5170_10JAN84_U27.BIN", "roms/machines/ibmat/BIOS_5170_10JAN84_U47.BIN", "" } }, { .files_no = 0 } }, }, { - .name = "enable_5161", + .name = "enable_5161", .description = "IBM 5161 Expansion Unit", - .type = CONFIG_BINARY, + .type = CONFIG_BINARY, .default_int = 0 }, { .name = "", .description = "", .type = CONFIG_END } @@ -362,7 +398,7 @@ machine_at_siemens_init(const machine_t *model) machine_at_common_init_ex(model, 1); - device_add(&keyboard_at_siemens_device); + device_add(&kbc_at_siemens_device); mem_remap_top(384); @@ -372,37 +408,3 @@ machine_at_siemens_init(const machine_t *model) return ret; } -int -machine_at_wellamerastar_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved("roms/machines/wellamerastar/W_3.031_L.BIN", - "roms/machines/wellamerastar/W_3.031_H.BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_ibm_common_init(model); - - return ret; -} - -#ifdef USE_OPEN_AT -int -machine_at_openat_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/openat/bios.bin", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_ibm_common_init(model); - - return ret; -} -#endif /* USE_OPEN_AT */ diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index b084bfbbd..8f2c9215f 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -37,6 +37,7 @@ #include <86box/hdc.h> #include <86box/nvr.h> #include <86box/port_6x.h> +#define USE_SIO_DETECT #include <86box/sio.h> #include <86box/serial.h> #include <86box/video.h> @@ -57,7 +58,7 @@ machine_at_mr286_init(const machine_t *model) return ret; machine_at_common_ide_init(model); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -68,7 +69,7 @@ machine_at_mr286_init(const machine_t *model) static void machine_at_headland_common_init(const machine_t *model, int type) { - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if ((type != 2) && (fdc_current[0] == FDC_INTERNAL)) device_add(&fdc_at_device); @@ -117,7 +118,7 @@ machine_at_ama932j_init(const machine_t *model) machine_at_headland_common_init(model, 2); - device_add(&ali5105_device); + device_add_params(&pc87310_device, (void *) (PC87310_ALI)); return ret; } @@ -135,7 +136,7 @@ machine_at_quadt286_init(const machine_t *model) return ret; machine_at_common_init(model); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -158,7 +159,7 @@ machine_at_quadt386sx_init(const machine_t *model) return ret; machine_at_common_init(model); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -168,6 +169,72 @@ machine_at_quadt386sx_init(const machine_t *model) return ret; } +static const device_config_t pbl300sx_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "pbl300sx", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "Phoenix ROM BIOS PLUS 1.10 - Revision 19910723091302", .internal_name = "pbl300sx_1991", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pbl300sx/V1.10_1113_910723.bin", "" } }, + { .name = "Phoenix ROM BIOS PLUS 1.10 - Revision 19920910", .internal_name = "pbl300sx", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pbl300sx/pb_l300sx_1992.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t pbl300sx_device = { + .name = "Packard Bell Legend 300SX", + .internal_name = "pbl300sx_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = pbl300sx_config +}; + +int +machine_at_pbl300sx_init(const machine_t *model) +{ + int ret = 0; + const char* fn; + + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&acc2036_device); + + device_add(&kbc_ps2_phoenix_device); + device_add(&um82c862f_ide_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + return ret; +} + int machine_at_neat_init(const machine_t *model) { @@ -207,7 +274,7 @@ machine_at_neat_ami_init(const machine_t *model) if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); return ret; } @@ -234,7 +301,7 @@ machine_at_ataripc4_init(const machine_t *model) if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); return ret; } @@ -251,7 +318,7 @@ machine_at_px286_init(const machine_t *model) return ret; machine_at_common_init(model); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -261,22 +328,82 @@ machine_at_px286_init(const machine_t *model) return ret; } +static void +machine_at_ctat_common_init(const machine_t *model) +{ + machine_at_common_init(model); + + device_add(&cs8220_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&kbc_at_phoenix_device); +} + int -machine_at_micronics386_init(const machine_t *model) +machine_at_dells200_init(const machine_t *model) { int ret; - ret = bios_load_interleaved("roms/machines/micronics386/386-Micronics-09-00021-EVEN.BIN", - "roms/machines/micronics386/386-Micronics-09-00021-ODD.BIN", + ret = bios_load_interleaved("roms/machines/dells200/dellL200256_LO_@DIP28.BIN", + "roms/machines/dells200/Dell200256_HI_@DIP28.BIN", 0x000f0000, 65536, 0); if (bios_only || !ret) return ret; - machine_at_init(model); + machine_at_ctat_common_init(model); - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); + return ret; +} + +int +machine_at_at122_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/at122/FINAL.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_ctat_common_init(model); + + return ret; +} + +int +machine_at_tuliptc7_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleavedr("roms/machines/tuliptc7/tc7be.bin", + "roms/machines/tuliptc7/tc7bo.bin", + 0x000f8000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_ctat_common_init(model); + + return ret; +} + +int +machine_at_wellamerastar_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/wellamerastar/W_3.031_L.BIN", + "roms/machines/wellamerastar/W_3.031_H.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_ctat_common_init(model); return ret; } @@ -288,14 +415,14 @@ machine_at_scat_init(const machine_t *model, int is_v4, int is_ami) if (machines[machine].bus_flags & MACHINE_BUS_PS2) { if (is_ami) - device_add(&keyboard_ps2_ami_device); + device_add(&kbc_ps2_ami_device); else - device_add(&keyboard_ps2_device); + device_add(&kbc_ps2_device); } else { if (is_ami) - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); else - device_add(&keyboard_at_device); + device_add(&kbc_at_device); } if (is_v4) @@ -309,7 +436,7 @@ machine_at_scatsx_init(const machine_t *model) { machine_at_common_init(model); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -379,6 +506,28 @@ machine_at_gw286ct_init(const machine_t *model) return ret; } +int +machine_at_drsm35286_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/drsm35286/syab04-665821fb81363428830424.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + device_add(&ide_isa_device); + device_add(&fdc37c651_ide_device); + + machine_at_scat_init(model, 1, 0); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + return ret; +} + int machine_at_senor_scat286_init(const machine_t *model) { @@ -411,12 +560,12 @@ machine_at_super286c_init(const machine_t *model) machine_at_common_init(model); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&neat_device); + device_add(&cs8220_device); return ret; } @@ -453,8 +602,7 @@ machine_at_spc4200p_init(const machine_t *model) machine_at_scat_init(model, 0, 1); - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&f82c710_device); device_add(&ide_isa_device); @@ -475,8 +623,7 @@ machine_at_spc4216p_init(const machine_t *model) machine_at_scat_init(model, 1, 1); - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&f82c710_device); return ret; } @@ -498,8 +645,7 @@ machine_at_spc4620p_init(const machine_t *model) machine_at_scat_init(model, 1, 1); - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&f82c710_device); device_add(&ide_isa_device); @@ -535,8 +681,7 @@ machine_at_deskmaster286_init(const machine_t *model) machine_at_scat_init(model, 0, 1); - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); + device_add(&f82c710_device); device_add(&ide_isa_device); @@ -558,7 +703,7 @@ machine_at_shuttle386sx_init(const machine_t *model) machine_at_common_init(model); device_add(&intel_82335_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -582,7 +727,7 @@ machine_at_adi386sx_init(const machine_t *model) device_add(&amstrad_megapc_nvr_device); /* NVR that is initialized to all 0x00's. */ device_add(&intel_82335_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -607,7 +752,7 @@ machine_at_wd76c10_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(¶dise_wd90c11_megapc_device); - device_add(&keyboard_ps2_quadtel_device); + device_add(&kbc_ps2_quadtel_device); device_add(&wd76c10_device); @@ -628,7 +773,7 @@ machine_at_cmdsl386sx16_init(const machine_t *model) machine_at_common_init(model); - device_add(&keyboard_ps2_device); + device_add(&kbc_ps2_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -656,7 +801,7 @@ machine_at_if386sx_init(const machine_t *model) machine_at_common_init_ex(model, 2); device_add(&amstrad_megapc_nvr_device); /* NVR that is initialized to all 0x00's. */ - device_add(&keyboard_at_phoenix_device); + device_add(&kbc_at_phoenix_device); device_add(&neat_sx_device); @@ -680,9 +825,9 @@ machine_at_scamp_common_init(const machine_t *model, int is_ps2) machine_at_common_ide_init(model); if (is_ps2) - device_add(&keyboard_ps2_ami_device); + device_add(&kbc_ps2_ami_device); else - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -704,9 +849,80 @@ machine_at_cmdsl386sx25_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&gd5402_onboard_device); - machine_at_common_ide_init(model); + machine_at_common_init_ex(model, 2); - device_add(&ali5105_device); /* The FDC is part of the ALi M5105. */ + device_add(&ide_isa_device); + + device_add_params(&pc87310_device, (void *) (PC87310_ALI)); + device_add(&vl82c113_device); /* The keyboard controller is part of the VL82c113. */ + + device_add(&vlsi_scamp_device); + + return ret; +} + +static const device_config_t dells333sl_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "dells333sl", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "Phoenix ROM BIOS PLUS 1.10 - Revision J01 (Jostens Learning Corporation OEM)", .internal_name = "dells333sl_j01", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/dells333sl/DELL386.BIN", "" } }, + { .name = "Phoenix ROM BIOS PLUS 1.10 - Revision A02", .internal_name = "dells333sl", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/dells333sl/Dell_386SX_30807_UBIOS_B400_VLSI_VL82C311_Cirrus_Logic_GD5420.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t dells333sl_device = { + .name = "Dell System 333s/L", + .internal_name = "dells333sl_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = dells333sl_config +}; + +int +machine_at_dells333sl_init(const machine_t *model) +{ + int ret = 0; + const char* fn; + + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 262144, 0); + memcpy(rom, &(rom[0x00020000]), 131072); + mem_mapping_set_addr(&bios_mapping, 0x0c0000, 0x40000); + mem_mapping_set_exec(&bios_mapping, rom); + device_context_restore(); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + machine_at_common_init_ex(model, 2); + + device_add(&ide_isa_device); + + device_add(&pc87311_device); device_add(&vl82c113_device); /* The keyboard controller is part of the VL82c113. */ device_add(&vlsi_scamp_device); @@ -787,7 +1003,7 @@ machine_at_acer100t_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&oti077_acer100t_device); - device_add(&ali5105_device); + device_add_params(&pc87310_device, (void *) (PC87310_ALI)); return ret; } @@ -808,7 +1024,7 @@ machine_at_arb1374_init(const machine_t *model) device_add(&ali1217_device); device_add(&w83787f_ide_en_device); - device_add(&keyboard_ps2_ami_device); + device_add(&kbc_ps2_ami_device); return ret; } @@ -829,7 +1045,7 @@ machine_at_sbc350a_init(const machine_t *model) device_add(&ali1217_device); device_add(&ide_isa_device); device_add(&fdc37c665_ide_pri_device); - device_add(&keyboard_ps2_ami_device); + device_add(&kbc_ps2_ami_device); return ret; } @@ -853,7 +1069,7 @@ machine_at_flytech386_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&tvga8900d_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); return ret; } @@ -873,7 +1089,7 @@ machine_at_325ax_init(const machine_t *model) device_add(&ali1217_device); device_add(&fdc_at_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); return ret; } @@ -893,7 +1109,7 @@ machine_at_mr1217_init(const machine_t *model) device_add(&ali1217_device); device_add(&fdc_at_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); return ret; } @@ -913,7 +1129,7 @@ machine_at_pja511m_init(const machine_t *model) device_add_inst(&fdc37c669_device, 1); device_add_inst(&fdc37c669_device, 2); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&ali6117d_device); device_add(&sst_flash_29ee010_device); @@ -934,7 +1150,7 @@ machine_at_prox1332_init(const machine_t *model) machine_at_common_init(model); device_add(&fdc37c669_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&ali6117d_device); device_add(&sst_flash_29ee010_device); @@ -958,7 +1174,7 @@ machine_at_pc8_init(const machine_t *model) return ret; machine_at_common_init(model); - device_add(&keyboard_at_ncr_device); + device_add(&kbc_at_ncr_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -989,9 +1205,9 @@ machine_at_3302_init(const machine_t *model) device_add(&fdc_at_device); if (gfxcard[0] == VID_INTERNAL) - device_add(¶dise_pvga1a_ncr3302_device); + device_add(machine_get_vid_device(machine)); - device_add(&keyboard_at_ncr_device); + device_add(&kbc_at_ncr_device); return ret; } @@ -1014,7 +1230,7 @@ machine_at_pc916sx_init(const machine_t *model) machine_at_common_init(model); - device_add(&keyboard_at_ncr_device); + device_add(&kbc_at_ncr_device); mem_remap_top(384); if (fdc_current[0] == FDC_INTERNAL) @@ -1023,7 +1239,6 @@ machine_at_pc916sx_init(const machine_t *model) return ret; } -#ifdef USE_OLIVETTI int machine_at_m290_init(const machine_t *model) { @@ -1035,15 +1250,16 @@ machine_at_m290_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init_ex(model, 4); - device_add(&keyboard_at_olivetti_device); + machine_at_common_init_ex(model, 6); + device_add(&amstrad_megapc_nvr_device); + + device_add(&olivetti_eva_device); device_add(&port_6x_olivetti_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&olivetti_eva_device); + device_add(&kbc_at_olivetti_device); return ret; } -#endif /* USE_OLIVETTI */ diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 5b746e3ef..0fcce36b3 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -64,7 +64,28 @@ machine_at_acc386_init(const machine_t *model) machine_at_common_init(model); device_add(&acc2168_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + +int +machine_at_asus3863364k_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/asus3863364k/am27c512dip28-64b53c26be3d8160533563.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&rabbit_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -85,7 +106,7 @@ machine_at_asus386_init(const machine_t *model) machine_at_common_init(model); device_add(&rabbit_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -105,7 +126,29 @@ machine_at_tandy4000_init(const machine_t *model) return ret; machine_at_common_init(model); - device_add(&keyboard_at_device); + device_add(&cs8230_device); + device_add(&kbc_at_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + +int +machine_at_dtk461_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/dtk461/DTK.BIO", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&sl82c461_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -118,7 +161,7 @@ machine_at_sis401_common_init(const machine_t *model) { machine_at_common_init(model); device_add(&sis_85c401_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -169,7 +212,7 @@ machine_at_av4_init(const machine_t *model) machine_at_common_init(model); device_add(&sis_85c460_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -193,7 +236,7 @@ machine_at_valuepoint433_init(const machine_t *model) // hangs without the PS/2 if (gfxcard[0] == VID_INTERNAL) device_add(&et4000w32_onboard_device); - device_add(&keyboard_ps2_device); + device_add(&kbc_ps2_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -219,7 +262,7 @@ machine_at_ecs386_init(const machine_t *model) if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); return ret; } @@ -242,7 +285,7 @@ machine_at_spc6000a_init(const machine_t *model) if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); return ret; } @@ -260,7 +303,7 @@ machine_at_ecs386v_init(const machine_t *model) machine_at_common_init(model); device_add(&ali1429_device); - device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&kbc_ps2_intel_ami_pci_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -282,7 +325,7 @@ machine_at_rycleopardlx_init(const machine_t *model) machine_at_common_init(model); device_add(&opti283_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -304,7 +347,7 @@ machine_at_486vchd_init(const machine_t *model) machine_at_common_init(model); device_add(&via_vt82c49x_device); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -325,7 +368,7 @@ machine_at_cs4031_init(const machine_t *model) machine_at_common_init(model); device_add(&cs4031_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -346,7 +389,7 @@ machine_at_pb410a_init(const machine_t *model) machine_at_ibm_common_ide_init(model); - device_add(&keyboard_ps2_device); + device_add(&kbc_ps2_device); device_add(&acc3221_device); device_add(&acc2168_device); @@ -354,7 +397,7 @@ machine_at_pb410a_init(const machine_t *model) device_add(&phoenix_486_jumper_device); if (gfxcard[0] == VID_INTERNAL) - device_add(&ht216_32_pb410a_device); + device_add(machine_get_vid_device(machine)); return ret; } @@ -370,14 +413,16 @@ machine_at_vect486vl_init(const machine_t *model) // has HDC problems if (bios_only || !ret) return ret; - machine_at_common_ide_init(model); + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + machine_at_common_init_ex(model, 2); device_add(&vl82c480_device); - if (gfxcard[0] == VID_INTERNAL) - device_add(&gd5428_onboard_device); - device_add(&vl82c113_device); + + device_add(&ide_isa_device); device_add(&fdc37c651_ide_device); return ret; @@ -394,14 +439,18 @@ machine_at_d824_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + machine_at_common_init_ex(model, 2); device_add(&vl82c480_device); - if (gfxcard[0] == VID_INTERNAL) - device_add(&gd5428_onboard_device); - - device_add(&keyboard_ps2_device); + /* + Technically, it should be the VL82C114 but we do not have + a proper datasheet of it that tells us the registers. + */ + device_add(&vl82c113_device); device_add(&ide_isa_device); device_add(&fdc37c651_device); @@ -409,6 +458,65 @@ machine_at_d824_init(const machine_t *model) return ret; } +int +machine_at_tuliptc38_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/tuliptc38/TULIP1.BIN", + 0x000f0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + device_add(&vl82c486_device); + device_add(&tulip_jumper_device); + + device_add(&vl82c113_device); + + device_add(&ide_isa_device); + device_add(&fdc37c651_ide_device); + + if (gfxcard[0] == VID_INTERNAL) { + bios_load_aux_linear("roms/machines/tuliptc38/VBIOS.BIN", + 0x000c0000, 32768, 0); + + device_add(machine_get_vid_device(machine)); + } else for (uint16_t i = 0; i < 32768; i++) + rom[i] = mem_readb_phys(0x000c0000 + i); + + mem_mapping_set_addr(&bios_mapping, 0x0c0000, 0x40000); + mem_mapping_set_exec(&bios_mapping, rom); + + return ret; +} + +int +machine_at_martin_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/martin/NONSCSI.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + device_add(&vl82c480_device); + device_add(&vl82c113_device); + + device_add(&ide_vlb_device); + device_add(&fdc37c651_ide_device); + + device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_acera1g_init(const machine_t *model) { @@ -426,9 +534,9 @@ machine_at_acera1g_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&gd5428_onboard_device); - device_add(&keyboard_ps2_acer_pci_device); + device_add(&kbc_ps2_acer_pci_device); - device_add(&ali5105_device); + device_add_params(&pc87310_device, (void *) (PC87310_ALI)); device_add(&ide_ali5213_device); return ret; @@ -448,7 +556,7 @@ machine_at_acerv10_init(const machine_t *model) machine_at_common_init(model); device_add(&sis_85c461_device); - device_add(&keyboard_ps2_acer_pci_device); + device_add(&kbc_ps2_acer_pci_device); device_add(&ide_isa_device); if (fdc_current[0] == FDC_INTERNAL) @@ -473,16 +581,47 @@ machine_at_decpclpv_init(const machine_t *model) device_add(&sis_85c461_device); if (gfxcard[0] == VID_INTERNAL) - device_add(&s3_86c805_onboard_vlb_device); + device_add(machine_get_vid_device(machine)); + + device_add(&kbc_ps2_phoenix_pci_device); - /* TODO: Phoenix MultiKey KBC */ - device_add(&keyboard_ps2_ami_pci_device); device_add(&ide_isa_2ch_device); device_add(&fdc37c663_ide_device); return ret; } +int +machine_at_dell466np_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/dell466np/466np.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&sis_85c461_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + else { + for (uint16_t i = 0; i < 32768; i++) + rom[i] = mem_readb_phys(0x000c0000 + i); + } + mem_mapping_set_addr(&bios_mapping, 0x0c0000, 0x40000); + mem_mapping_set_exec(&bios_mapping, rom); + + device_add(&kbc_ps2_phoenix_pci_device); + + device_add(&ide_isa_device); + device_add(&fdc37c661_ide_device); + + return ret; +} + static void machine_at_ali1429_common_init(const machine_t *model, int is_green) { @@ -493,7 +632,7 @@ machine_at_ali1429_common_init(const machine_t *model, int is_green) else device_add(&ali1429_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -544,9 +683,9 @@ machine_at_opti495_init(const machine_t *model) machine_at_common_init(model); - device_add(&opti495_device); + device_add(&opti495slc_device); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -559,9 +698,9 @@ machine_at_opti495_ami_common_init(const machine_t *model) { machine_at_common_init(model); - device_add(&opti495_device); + device_add(&opti495sx_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -599,6 +738,32 @@ machine_at_opti495_mr_init(const machine_t *model) return ret; } +int +machine_at_c747_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/c747/486-C747 Tandon.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + /* The EFAR chipset is a rebrand of the OPTi 495SX. */ + device_add(&opti495sx_device); + + /* + No idea what KBC it actually has but this produces the + desired behavior: command A9 does absolutely nothing. + */ + device_add(&kbc_at_siemens_device); + device_add(&um82c862f_ide_device); + + return ret; +} + int machine_at_exp4349_init(const machine_t *model) { @@ -613,7 +778,7 @@ machine_at_exp4349_init(const machine_t *model) machine_at_common_init(model); device_add(&ali1429g_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -631,7 +796,7 @@ machine_at_403tg_common_init(const machine_t *model, int nvr_hack) device_add(&opti895_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -696,10 +861,12 @@ static const device_config_t pb450_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "PCI 1.0A", .internal_name = "pb450a" /*"pci10a"*/, .bios_type = BIOS_NORMAL, + { .name = "PhoenixBIOS 4.03 - Revision PCI 1.0A", .internal_name = "pb450a_pci10a" /*"pci10a"*/, .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/OPTI802.bin", "" } }, - { .name = "PNP 1.1A", .internal_name = "pnp11a", .bios_type = BIOS_NORMAL, + { .name = "PhoenixBIOS 4.03 - Revision PNP 1.1A", .internal_name = "pb450a", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/PNP11A.bin", "" } }, + { .name = "PhoenixBIOS 4.05 - Revision P4HS20 (by Micro Firmware)", .internal_name = "pb450a_p4hs20", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/p4hs20.bin", "" } }, { .files_no = 0 } }, }, @@ -753,7 +920,7 @@ machine_at_pb450_init(const machine_t *model) device_add(&opti895_device); device_add(&opti602_device); device_add(&opti822_device); - device_add(&keyboard_ps2_phoenix_device); + device_add(&kbc_ps2_phoenix_device); device_add(&fdc37c665_ide_device); device_add(&ide_opti611_vlb_sec_device); device_add(&intel_flash_bxt_device); @@ -784,7 +951,7 @@ machine_at_pc330_6573_common_init(const machine_t *model) device_add(&opti602_device); device_add(&opti802g_device); device_add(&opti822_device); - device_add(&keyboard_ps2_ami_device); + device_add(&kbc_ps2_ami_device); device_add(&fdc37c665_ide_device); device_add(&ide_opti611_vlb_device); device_add(&intel_flash_bxt_device); @@ -835,8 +1002,9 @@ machine_at_mvi486_init(const machine_t *model) machine_at_common_init(model); - device_add(&opti495_device); - device_add(&keyboard_at_device); + device_add(&opti498_device); + + device_add(&kbc_at_device); device_add(&pc87311_ide_device); return ret; @@ -865,7 +1033,32 @@ machine_at_ami471_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); + + return ret; +} + +int +machine_at_advantage40xxd_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/advantage40xxd/AST101.09A", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add(&sis_85c471_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + device_add(&kbc_ps2_phoenix_device); + device_add(&um82c863f_ide_device); + + device_add(&intel_flash_bxt_device); return ret; } @@ -882,7 +1075,7 @@ machine_at_vli486sv2g_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&keyboard_ps2_ami_device); + device_add(&kbc_ps2_ami_device); return ret; } @@ -899,7 +1092,7 @@ machine_at_dtk486_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); return ret; } @@ -917,7 +1110,7 @@ machine_at_px471_init(const machine_t *model) machine_at_sis_85c471_common_init(model); device_add(&ide_vlb_device); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); return ret; } @@ -934,7 +1127,7 @@ machine_at_win471_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); return ret; } @@ -959,7 +1152,7 @@ machine_at_pci400ca_init(const machine_t *model) pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); device_add(&sio_device); device_add(&intel_flash_bxt_ami_device); @@ -984,7 +1177,7 @@ machine_at_vi15g_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); return ret; } @@ -1007,7 +1200,7 @@ machine_at_greenb_init(const machine_t *model) device_add(&contaq_82c597_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); return ret; } @@ -1030,7 +1223,7 @@ machine_at_4gpv5_init(const machine_t *model) device_add(&contaq_82c596a_device); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); return ret; } @@ -1070,7 +1263,7 @@ machine_at_r418_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&fdc37c665_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); return ret; } @@ -1096,7 +1289,7 @@ machine_at_m4li_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&fdc37c665_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); return ret; } @@ -1122,7 +1315,7 @@ machine_at_ls486e_init(const machine_t *model) pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&fdc37c665_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); return ret; } @@ -1148,7 +1341,7 @@ machine_at_4dps_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&w83787f_device); - device_add(&keyboard_ps2_ami_device); + device_add(&kbc_ps2_ami_device); device_add(&intel_flash_bxt_device); @@ -1175,7 +1368,7 @@ machine_at_ms4144_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&w83787f_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); device_add(&sst_flash_29ee010_device); @@ -1204,7 +1397,7 @@ machine_at_acerp3_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&fdc37c665_ide_device); - device_add(&keyboard_ps2_acer_pci_device); + device_add(&kbc_ps2_acer_pci_device); device_add(&ide_cmd640_pci_legacy_only_device); if (gfxcard[0] == VID_INTERNAL) @@ -1235,7 +1428,7 @@ machine_at_486sp3c_init(const machine_t *model) pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&fdc37c665_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&intel_flash_bxt_device); @@ -1263,7 +1456,7 @@ machine_at_4saw2_init(const machine_t *model) pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&w83787f_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&intel_flash_bxt_device); @@ -1293,7 +1486,7 @@ machine_at_alfredo_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_phoenix_device); + device_add(&kbc_ps2_phoenix_device); device_add(&sio_device); device_add(&fdc37c663_device); device_add(&intel_flash_bxt_ami_device); @@ -1322,7 +1515,7 @@ machine_at_ninja_init(const machine_t *model) pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 1, 2); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 1, 2, 1); - device_add(&keyboard_ps2_phoenix_device); + device_add(&kbc_ps2_phoenix_device); device_add(&intel_flash_bxt_ami_device); device_add(&i420ex_device); @@ -1352,7 +1545,7 @@ machine_at_bat4ip3e_init(const machine_t *model) pci_register_slot(0x0a, PCI_CARD_NORMAL, 1, 2, 1, 2); device_add(&phoenix_486_jumper_pci_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&i420ex_device); device_add(&ide_cmd640_pci_device); device_add(&fdc37c665_device); @@ -1379,7 +1572,7 @@ machine_at_486pi_init(const machine_t *model) pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1); pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 1, 2); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&fdc37c665_device); device_add(&i420ex_device); @@ -1404,7 +1597,7 @@ machine_at_sb486p_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 1, 2); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 2, 1); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&i82091aa_device); device_add(&i420ex_device); @@ -1433,7 +1626,7 @@ machine_at_486sp3_init(const machine_t *model) pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */ pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */ pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_at_ami_device); /* Uses the AMIKEY KBC */ + device_add(&kbc_at_ami_device); /* Uses the AMIKEY KBC */ device_add(&sio_device); device_add(&fdc37c663_ide_device); device_add(&sst_flash_29ee010_device); @@ -1462,7 +1655,7 @@ machine_at_amis76_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&sio_device); device_add(&fdc37c665_device); device_add(&intel_flash_bxt_ami_device); @@ -1494,7 +1687,7 @@ machine_at_pci400cb_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 0E = Slot 2 */ pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 0D = Slot 3 */ pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 0C = Slot 4 */ - device_add(&keyboard_ps2_ami_pci_device); /* Assume AMI Megakey 1993 standalone ('P') + device_add(&kbc_ps2_ami_pci_device); /* Assume AMI Megakey 1993 standalone ('P') because of the Tekram machine below. */ device_add(&ims8848_device); @@ -1524,7 +1717,7 @@ machine_at_g486ip_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 03 = Slot 1 */ pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */ pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 05 = Slot 3 */ - device_add(&keyboard_ps2_ami_pci_device); /* AMI Megakey 1993 stanalone ('P') */ + device_add(&kbc_ps2_ami_pci_device); /* AMI Megakey 1993 stanalone ('P') */ device_add(&ims8848_device); @@ -1555,7 +1748,7 @@ machine_at_486sp3g_init(const machine_t *model) pci_register_slot(0x05, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 05 = Slot 2 */ pci_register_slot(0x04, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 04 = Slot 3 */ pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_ami_pci_device); /* Uses the AMIKEY KBC */ + device_add(&kbc_ps2_ami_pci_device); /* Uses the AMIKEY KBC */ device_add(&sio_zb_device); device_add(&pc87332_398_ide_device); device_add(&sst_flash_29ee010_device); @@ -1566,6 +1759,87 @@ machine_at_486sp3g_init(const machine_t *model) return ret; } +static const device_config_t sb486pv_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "sb486pv", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "AMI WinBIOS (062594) - Revision 0108", .internal_name = "sb486pv_0108", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/sb486pv/41-0108-062594-SATURN2.rom", "" } }, + { .name = "AMI WinBIOS (062594) - Revision 0301", .internal_name = "sb486pv_0301", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/sb486pv/0301-062594-SATURN2.rom", "" } }, + { .name = "AMIBIOS 6 (071595) - Revision 1301", .internal_name = "sb486pv", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/sb486pv/amiboot.rom", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t sb486pv_device = { + .name = "ICS SB486PV", + .internal_name = "sb486pv_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = sb486pv_config +}; + +int +machine_at_sb486pv_init(const machine_t *model) +{ + int ret = 0; + const char* fn; + + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + if (!strcmp(fn, "roms/machines/sb486pv/amiboot.rom")) + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + else + ret = bios_load_linear_inverted(fn, 0x000e0000, 131072, 0); + device_context_restore(); + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_2); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0e, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x0f, PCI_CARD_VIDEO, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + device_add(&kbc_ps2_ami_pci_device); + device_add(&sio_zb_device); + device_add(&ide_rz1000_pci_single_channel_device); + device_add(&i82091aa_26e_device); + if (!strcmp(fn, "roms/machines/sb486pv/amiboot.rom")) + device_add(&intel_flash_bxt_device); + else + device_add(&intel_flash_bxt_ami_device); + + device_add(&i420zx_device); + + return ret; +} + int machine_at_486ap4_init(const machine_t *model) { @@ -1586,7 +1860,7 @@ machine_at_486ap4_init(const machine_t *model) pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 0a = Slot 2 */ pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 0b = Slot 3 */ pci_register_slot(0x0c, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 0c = Slot 4 */ - device_add(&keyboard_ps2_ami_pci_device); /* Uses the AMIKEY KBC */ + device_add(&kbc_ps2_ami_pci_device); /* Uses the AMIKEY KBC */ if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -1619,7 +1893,7 @@ machine_at_g486vpa_init(const machine_t *model) device_add(&via_vt82c49x_pci_ide_device); device_add(&via_vt82c505_device); device_add(&pc87332_398_ide_sec_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&sst_flash_29ee010_device); return ret; @@ -1648,7 +1922,7 @@ machine_at_486vipio2_init(const machine_t *model) device_add(&via_vt82c49x_pci_ide_device); device_add(&via_vt82c505_device); device_add(&w83787f_ide_sec_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&sst_flash_29ee010_device); return ret; @@ -1675,7 +1949,7 @@ machine_at_abpb4_init(const machine_t *model) device_add(&ali1489_device); device_add(&w83787f_device); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); #if 0 device_add(&intel_flash_bxt_device); #endif @@ -1705,7 +1979,7 @@ machine_at_win486pci_init(const machine_t *model) device_add(&ali1489_device); device_add(&prime3b_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); return ret; } @@ -1732,7 +2006,7 @@ machine_at_ms4145_init(const machine_t *model) device_add(&ali1489_device); device_add(&w83787f_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); device_add(&sst_flash_29ee010_device); return ret; @@ -1759,13 +2033,12 @@ machine_at_sbc490_init(const machine_t *model) pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x01, PCI_CARD_VIDEO, 4, 1, 2, 3); + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + device_add(&ali1489_device); device_add(&fdc37c665_device); - - if (gfxcard[0] == VID_INTERNAL) - device_add(&tgui9440_onboard_pci_device); - - device_add(&keyboard_ps2_ami_device); + device_add(&kbc_ps2_ami_device); device_add(&sst_flash_29ee010_device); return ret; @@ -1790,7 +2063,7 @@ machine_at_tf486_init(const machine_t *model) device_add(&ali1489_device); device_add(&w83977ef_device); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); device_add(&sst_flash_29ee010_device); return ret; @@ -1813,7 +2086,7 @@ machine_at_arb1476_init(const machine_t *model) device_add(&ali1489_device); device_add(&fdc37c669_device); - device_add(&keyboard_ps2_device); + device_add(&kbc_ps2_device); device_add(&sst_flash_29ee010_device); return ret; @@ -1837,7 +2110,7 @@ machine_at_itoxstar_init(const machine_t *model) pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x1F, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&w83977f_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&stpc_client_device); device_add(&sst_flash_29ee020_device); device_add(&w83781d_device); /* fans: Chassis, CPU, unused; temperatures: Chassis, CPU, unused */ @@ -1868,7 +2141,7 @@ machine_at_arb1423c_init(const machine_t *model) pci_register_slot(0x1E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x1D, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&w83977f_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&stpc_consumer2_device); device_add(&winbond_flash_w29c020_device); @@ -1895,7 +2168,7 @@ machine_at_arb1479_init(const machine_t *model) pci_register_slot(0x1E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x1D, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&w83977f_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&stpc_consumer2_device); device_add(&winbond_flash_w29c020_device); @@ -1919,7 +2192,7 @@ machine_at_iach488_init(const machine_t *model) pci_register_slot(0x0B, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&w83977f_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&stpc_consumer2_device); device_add(&sst_flash_29ee020_device); @@ -1947,7 +2220,7 @@ machine_at_pcm9340_init(const machine_t *model) pci_register_slot(0x1F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add_inst(&w83977f_device, 1); device_add_inst(&w83977f_device, 2); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&stpc_elite_device); device_add(&sst_flash_29ee020_device); @@ -1975,7 +2248,7 @@ machine_at_pcm5330_init(const machine_t *model) 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); + device_add(&kbc_ps2_ami_pci_device); device_add(&stpc_atlas_device); device_add(&sst_flash_29ee020_device); @@ -2008,23 +2281,71 @@ 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_ps2_ami_device); + device_add(&kbc_ps2_ami_device); return ret; } +static const device_config_t hot433a_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "hot433a", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "AMIBIOS 5 (101094) - Revision 433AUS33", .internal_name = "hot433a", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/hot433/433AUS33.ROM", "" } }, + { .name = "AwardBIOS v4.51PG - Revision 2.5 (by eSupport)", .internal_name = "hot433a_v451pg", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/hot433/2A4X5H21.BIN", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t hot433a_device = { + .name = "Shuttle HOT-433A", + .internal_name = "hot433a_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = hot433a_config +}; + int machine_at_hot433a_init(const machine_t *model) { - int ret; + int ret = 0; + const char* fn; - ret = bios_load_linear("roms/machines/hot433/433AUS33.ROM", - 0x000e0000, 131072, 0); + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + int is_award = !strcmp(device_get_config_bios("bios"), "hot433a_award"); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + if (is_award) + device_add(&amstrad_megapc_nvr_device); + else + device_add(&ami_1994_nvr_device); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -2036,9 +2357,46 @@ machine_at_hot433a_init(const machine_t *model) device_add(&umc_hb4_device); device_add(&umc_8886bf_device); - device_add(&um8669f_device); + if (is_award) + device_add(&um8663af_device); + else + device_add(&um8669f_device); device_add(&winbond_flash_w29c010_device); - device_add(&keyboard_at_ami_device); + if (is_award) + device_add(&kbc_ps2_ami_device); + else + device_add(&kbc_at_ami_device); + + pic_toggle_latch(is_award); + + return ret; +} + +int +machine_at_84xxuuda_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/84xxuuda/uud0520s.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + + device_add(&umc_hb4_device); + device_add(&umc_8886bf_device); + device_add(&um8663bf_device); + device_add(&winbond_flash_w29c010_device); + device_add(&kbc_ps2_ami_device); return ret; } @@ -2069,7 +2427,7 @@ machine_at_pl4600c_init(const machine_t *model) device_add(&umc_8886af_device); device_add(&um8663af_device); device_add(&sst_flash_29ee010_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); if (gfxcard[0] == VID_INTERNAL) device_add(&gd5430_onboard_pci_device); @@ -2108,7 +2466,7 @@ machine_at_atc1415_init(const machine_t *model) device_add(&umc_hb4_device); device_add(&umc_8886bf_device); device_add(&intel_flash_bxt_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -2140,10 +2498,10 @@ machine_at_actionpc2600_init(const machine_t *model) device_add(&umc_8886bf_device); device_add(&fdc37c665_device); device_add(&intel_flash_bxt_device); - device_add(&keyboard_ps2_tg_ami_device); + device_add(&kbc_ps2_tg_ami_device); if (gfxcard[0] == VID_INTERNAL) - device_add(&tgui9440_onboard_pci_device); + device_add(machine_get_vid_device(machine)); return ret; } @@ -2173,9 +2531,9 @@ machine_at_actiontower8400_init(const machine_t *model) device_add(&fdc37c665_device); device_add(&ide_cmd640_pci_device); device_add(&intel_flash_bxt_device); // The ActionPC 2600 has this so I'm gonna assume this does too. - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); if (gfxcard[0] == VID_INTERNAL) - device_add(&gd5430_onboard_pci_device); + device_add(machine_get_vid_device(machine)); return ret; } @@ -2204,7 +2562,7 @@ machine_at_m919_init(const machine_t *model) device_add(&umc_8886af_device); /* AF is correct - the BIOS does IDE writes to ports 108h and 109h. */ device_add(&um8663bf_device); device_add(&sst_flash_29ee010_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); return ret; } @@ -2233,7 +2591,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_ps2_ami_device); + device_add(&kbc_ps2_ami_device); return ret; } @@ -2267,7 +2625,7 @@ machine_at_ms4134_init(const machine_t *model) device_add(&ali1435_device); device_add(&sst_flash_29ee010_device); - device_add(&keyboard_ps2_ami_device); + device_add(&kbc_ps2_ami_device); return ret; } @@ -2300,7 +2658,7 @@ machine_at_tg486gp_init(const machine_t *model) device_add(&ali1435_device); device_add(&sst_flash_29ee010_device); - device_add(&keyboard_ps2_tg_ami_device); + device_add(&kbc_ps2_tg_ami_device); return ret; } @@ -2321,7 +2679,7 @@ machine_at_tg486g_init(const machine_t *model) device_add(&sis_85c471_device); device_add(&ide_isa_device); device_add(&fdc37c651_ide_device); - device_add(&keyboard_ps2_tg_ami_pci_device); + device_add(&kbc_ps2_tg_ami_pci_device); if (gfxcard[0] != VID_INTERNAL) { for (uint16_t i = 0; i < 32768; i++) @@ -2348,7 +2706,7 @@ machine_at_dvent4xx_init(const machine_t *model) device_add(&sis_85c471_device); device_add(&ide_cmd640_vlb_pri_device); device_add(&fdc37c665_ide_device); - device_add(&keyboard_ps2_phoenix_device); + device_add(&kbc_ps2_phoenix_device); if (gfxcard[0] == VID_INTERNAL) device_add(machine_get_vid_device(machine)); @@ -2370,7 +2728,7 @@ machine_at_ecsal486_init(const machine_t *model) machine_at_common_init(model); device_add(&ali1429g_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -2393,7 +2751,7 @@ machine_at_ap4100aa_init(const machine_t *model) device_add(&ami_1994_nvr_device); device_add(&ali1429g_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&ide_vlb_device); device_add(&um8663bf_device); @@ -2413,7 +2771,7 @@ machine_at_atc1762_init(const machine_t *model) machine_at_common_init(model); device_add(&ali1429g_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -2435,7 +2793,31 @@ machine_at_dataexpert386wb_init(const machine_t *model) machine_at_common_init(model); device_add(&opti391_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + +int +machine_at_isa486c_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/isa486c/asus-isa-486c-401a0-040591-657e2c17a0218417632602.bin", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&isa486c_device); + device_add(&port_92_key_device); + + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -2459,7 +2841,7 @@ machine_at_genoa486_init(const machine_t *model) device_add(&compaq_genoa_device); device_add(&port_92_key_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -2480,7 +2862,7 @@ machine_at_ga486l_init(const machine_t *model) machine_at_common_init(model); device_add(&opti381_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -2488,6 +2870,32 @@ machine_at_ga486l_init(const machine_t *model) return ret; } +int +machine_at_cobalt_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/cobalt/Cobalt_2.3.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&opti499_device); + device_add(&ide_opti611_vlb_device); + device_add(&ide_isa_sec_device); + device_add(&fdc37c665_device); + + device_add(&kbc_ps2_ami_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + return ret; +} + int machine_at_cougar_init(const machine_t *model) { @@ -2505,7 +2913,49 @@ machine_at_cougar_init(const machine_t *model) device_add(&opti499_device); device_add(&fdc37c665_ide_pri_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + +int +machine_at_micronics386_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/micronics386/386-Micronics-09-00021-EVEN.BIN", + "roms/machines/micronics386/386-Micronics-09-00021-ODD.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_init(model); + device_add(&port_92_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + +int +machine_at_micronics386px_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/micronics386/386-Micronics-09-00021-LO.BIN", + "roms/machines/micronics386/386-Micronics-09-00021-HI.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_init(model); + device_add(&port_92_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); diff --git a/src/machine/m_at_commodore.c b/src/machine/m_at_commodore.c index b9615c064..bd4468ae1 100644 --- a/src/machine/m_at_commodore.c +++ b/src/machine/m_at_commodore.c @@ -55,22 +55,22 @@ #include <86box/plat_unused.h> static serial_t *cmd_uart; +static lpt_t *cmd_lpt; static void cbm_io_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) { - lpt1_remove(); - lpt2_remove(); + lpt_port_remove(cmd_lpt); switch (val & 3) { case 1: - lpt1_setup(LPT_MDA_ADDR); + lpt_port_setup(cmd_lpt, LPT_MDA_ADDR); break; case 2: - lpt1_setup(LPT1_ADDR); + lpt_port_setup(cmd_lpt, LPT1_ADDR); break; case 3: - lpt1_setup(LPT2_ADDR); + lpt_port_setup(cmd_lpt, LPT2_ADDR); break; default: @@ -116,6 +116,10 @@ machine_at_cmdpc_init(const machine_t *model) device_add(&fdc_at_device); cmd_uart = device_add(&ns8250_device); + serial_set_next_inst(1); + + cmd_lpt = device_add(&lpt_port_device); + lpt_set_next_inst(1); cbm_io_init(); diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 904122bad..d918dbfc6 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -44,9 +44,6 @@ #include <86box/vid_cga_comp.h> #include <86box/plat_unused.h> - -static video_timings_t timing_compaq_plasma = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; - enum { COMPAQ_PORTABLEII = 0, COMPAQ_PORTABLEIII, @@ -55,669 +52,11 @@ enum { COMPAQ_DESKPRO386_05_1988 }; -#define CGA_RGB 0 -#define CGA_COMPOSITE 1 - -/*Very rough estimate*/ -#define VID_CLOCK (double) (651 * 416 * 60) - -static uint8_t cga_crtcmask[32] = { - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* Mapping of attributes to colours */ -static uint32_t amber; -static uint32_t black; -static uint32_t blinkcols[256][2]; -static uint32_t normcols[256][2]; - -/* Video options set by the motherboard; they will be picked up by the card - * on the next poll. - * - * Bit 3: Disable built-in video (for add-on card) - * Bit 2: Thin font - * Bits 0,1: Font set (not currently implemented) - */ -static int8_t cpq_st_display_internal = -1; - -static uint8_t mdaattr[256][2][2]; - -static void -compaq_plasma_display_set(uint8_t internal) -{ - cpq_st_display_internal = internal; -} - -static uint8_t -compaq_plasma_display_get(void) -{ - return cpq_st_display_internal; -} - -typedef struct compaq_plasma_t { - cga_t cga; - uint8_t port_23c6; - uint8_t internal_monitor; - uint8_t attrmap; -} compaq_plasma_t; - static int compaq_machine_type = 0; /* Compaq Deskpro 386 remaps RAM from 0xA0000-0xFFFFF to 0xFA0000-0xFFFFFF */ static mem_mapping_t ram_mapping; -static void compaq_plasma_recalcattrs(compaq_plasma_t *self); - -static void -compaq_plasma_recalctimings(compaq_plasma_t *self) -{ - double _dispontime; - double _dispofftime; - double disptime; - - if (!self->internal_monitor && !(self->port_23c6 & 1)) { - cga_recalctimings(&self->cga); - return; - } - - disptime = 651; - _dispontime = 640; - _dispofftime = disptime - _dispontime; - self->cga.dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32)); - self->cga.dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32)); -} - -static void -compaq_plasma_waitstates(UNUSED(void *priv)) -{ - int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; - int ws; - - ws = ws_array[cycles & 0xf]; - sub_cycles(ws); -} - -static void -compaq_plasma_write(uint32_t addr, uint8_t val, void *priv) -{ - compaq_plasma_t *self = (compaq_plasma_t *) priv; - - self->cga.vram[addr & 0x7fff] = val; - compaq_plasma_waitstates(&self->cga); -} - -static uint8_t -compaq_plasma_read(uint32_t addr, void *priv) -{ - compaq_plasma_t *self = (compaq_plasma_t *) priv; - uint8_t ret; - - compaq_plasma_waitstates(&self->cga); - ret = (self->cga.vram[addr & 0x7fff]); - - return ret; -} - -static void -compaq_plasma_out(uint16_t addr, uint8_t val, void *priv) -{ - compaq_plasma_t *self = (compaq_plasma_t *) priv; - uint8_t old; - - switch (addr) { - /* Emulated CRTC, register select */ - case 0x3d4: - cga_out(addr, val, &self->cga); - break; - - /* Emulated CRTC, value */ - case 0x3d5: - old = self->cga.crtc[self->cga.crtcreg]; - self->cga.crtc[self->cga.crtcreg] = val & cga_crtcmask[self->cga.crtcreg]; - - /* Register 0x12 controls the attribute mappings for the - * plasma screen. */ - if (self->cga.crtcreg == 0x12) { - self->attrmap = val; - compaq_plasma_recalcattrs(self); - break; - } - - if (old != val) { - if (self->cga.crtcreg < 0xe || self->cga.crtcreg > 0x10) { - self->cga.fullchange = changeframecount; - compaq_plasma_recalctimings(self); - } - } - break; - case 0x3d8: - case 0x3d9: - cga_out(addr, val, &self->cga); - break; - - case 0x13c6: - compaq_plasma_display_set((val & 8) ? 1 : 0); - break; - - case 0x23c6: - self->port_23c6 = val; - if (val & 8) /* Disable internal CGA */ - mem_mapping_disable(&self->cga.mapping); - else - mem_mapping_enable(&self->cga.mapping); - break; - - default: - break; - } -} - -static uint8_t -compaq_plasma_in(uint16_t addr, void *priv) -{ - compaq_plasma_t *self = (compaq_plasma_t *) priv; - uint8_t ret = 0xff; - - switch (addr) { - case 0x3d4: - case 0x3da: - ret = cga_in(addr, &self->cga); - break; - - case 0x3d5: - if (self->cga.crtcreg == 0x12) { - ret = self->attrmap & 0x0f; - if (self->internal_monitor) - ret |= 0x30; /* Plasma / CRT */ - } else - ret = cga_in(addr, &self->cga); - break; - - case 0x13c6: - ret = compaq_plasma_display_get() ? 8 : 0; - ret |= 4; - break; - - case 0x1bc6: - ret = 0; - if (compaq_plasma_display_get()) { - if ((self->cga.cgamode & 0x12) == 0x12) { - if (self->port_23c6 & 8) - ret |= 0x40; - else - ret |= 0x20; - } - } - break; - - case 0x23c6: - ret = 0; - break; - - default: - break; - } - - return ret; -} - -static void -compaq_plasma_poll(void *priv) -{ - compaq_plasma_t *self = (compaq_plasma_t *) priv; - uint8_t chr; - uint8_t attr; - uint8_t sc; - uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff; - uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x7fff; - uint16_t addr; - int drawcursor; - int cursorline; - int blink = 0; - int underline = 0; - uint32_t ink = 0; - uint32_t fg = (self->cga.cgacol & 0x0f) ? amber : black; - uint32_t bg = black; - uint32_t cols[2]; - uint8_t dat; - uint8_t pattern; - uint32_t ink0 = 0; - uint32_t ink1 = 0; - - /* Switch between internal plasma and external CRT display. */ - if ((cpq_st_display_internal != -1) && (cpq_st_display_internal != self->internal_monitor)) { - self->internal_monitor = cpq_st_display_internal; - compaq_plasma_recalctimings(self); - } - - /* graphic mode and not mode 40h */ - if (!self->internal_monitor && !(self->port_23c6 & 1)) { - cga_poll(&self->cga); - return; - } - - /* mode 40h or text mode */ - if (!self->cga.linepos) { - timer_advance_u64(&self->cga.timer, self->cga.dispofftime); - self->cga.cgastat |= 1; - self->cga.linepos = 1; - if (self->cga.cgadispon) { - if (self->cga.displine == 0) { - video_wait_for_buffer(); - } - if (self->cga.cgamode & 2) { - if (self->cga.cgamode & 0x10) { - /* 640x400 mode */ - if (self->port_23c6 & 1) /* 640*400 */ { - addr = ((self->cga.displine) & 1) * 0x2000 + ((self->cga.displine >> 1) & 1) * 0x4000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1); - } else { - addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1); - } - for (uint8_t x = 0; x < 80; x++) { - dat = self->cga.vram[addr & 0x7FFF]; - addr++; - - for (uint8_t c = 0; c < 8; c++) { - ink = (dat & 0x80) ? fg : bg; - if (!(self->cga.cgamode & 8)) - ink = black; - (buffer32->line[self->cga.displine])[x * 8 + c] = ink; - dat <<= 1; - } - } - } else { - addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1); - for (uint8_t x = 0; x < 80; x++) { - dat = self->cga.vram[addr & 0x7fff]; - addr++; - - for (uint8_t c = 0; c < 4; c++) { - pattern = (dat & 0xC0) >> 6; - if (!(self->cga.cgamode & 8)) - pattern = 0; - - switch (pattern & 3) { - case 0: - ink0 = ink1 = black; - break; - case 1: - if (self->cga.displine & 1) { - ink0 = black; - ink1 = black; - } else { - ink0 = amber; - ink1 = black; - } - break; - case 2: - if (self->cga.displine & 1) { - ink0 = black; - ink1 = amber; - } else { - ink0 = amber; - ink1 = black; - } - break; - case 3: - ink0 = ink1 = amber; - break; - - default: - break; - } - buffer32->line[self->cga.displine][x * 8 + 2 * c] = ink0; - buffer32->line[self->cga.displine][x * 8 + 2 * c + 1] = ink1; - dat <<= 2; - } - } - } - } else if (self->cga.cgamode & 1) { - /* 80-col */ - sc = self->cga.displine & 0x0f; - addr = ((ma & ~1) + (self->cga.displine >> 4) * 80) * 2; - ma += (self->cga.displine >> 4) * 80; - - if ((self->cga.crtc[0x0a] & 0x60) == 0x20) - cursorline = 0; - else - cursorline = ((self->cga.crtc[0x0a] & 0x0f) * 2 <= sc) && ((self->cga.crtc[0x0b] & 0x0F) * 2 >= sc); - - /* for each text column */ - for (uint8_t x = 0; x < 80; x++) { - /* video output enabled */ - chr = self->cga.vram[(addr + 2 * x) & 0x7FFF]; - attr = self->cga.vram[(addr + 2 * x + 1) & 0x7FFF]; - drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16)); - - blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6)); - /* blink active */ - if (self->cga.cgamode & 0x20) { - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - /* attribute 7 active and not cursor */ - if (blink) { - /* set blinking */ - cols[1] = cols[0]; - } - } else { - /* Set intensity bit */ - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - /* character underline active and 7th row of pixels in character height being drawn */ - if (underline && (sc == 7)) { - /* for each pixel in character width */ - for (uint8_t c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 3) + c] = mdaattr[attr][blink][1]; - } else if (drawcursor) { - for (uint8_t c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); - } else { - for (uint8_t c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm2[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - - ++ma; - } - } else { /* 40-col */ - sc = self->cga.displine & 0x0f; - addr = ((ma & ~1) + (self->cga.displine >> 4) * 40) * 2; - ma += (self->cga.displine >> 4) * 40; - - if ((self->cga.crtc[0x0a] & 0x60) == 0x20) - cursorline = 0; - else - cursorline = ((self->cga.crtc[0x0a] & 0x0f) * 2 <= sc) && ((self->cga.crtc[0x0b] & 0x0F) * 2 >= sc); - - for (uint8_t x = 0; x < 40; x++) { - chr = self->cga.vram[(addr + 2 * x) & 0x7FFF]; - attr = self->cga.vram[(addr + 2 * x + 1) & 0x7FFF]; - drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16)); - - blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6)); - /* blink active */ - if (self->cga.cgamode & 0x20) { - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - /* attribute 7 active and not cursor */ - if (blink) { - /* set blinking */ - cols[1] = cols[0]; - } - } else { - /* Set intensity bit */ - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - /* character underline active and 7th row of pixels in character height being drawn */ - if (underline && (sc == 7)) { - /* for each pixel in character width */ - for (uint8_t c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 4) + (c * 2)] = buffer32->line[self->cga.displine][(x << 4) + (c * 2) + 1] = mdaattr[attr][blink][1]; - } else if (drawcursor) { - for (uint8_t c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm2[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); - } else { - for (uint8_t c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm2[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - ++ma; - } - } - } - self->cga.displine++; - /* Hardcode a fixed refresh rate and VSYNC timing */ - if (self->cga.displine == 400) { /* Start of VSYNC */ - self->cga.cgastat |= 8; - self->cga.cgadispon = 0; - } - if (self->cga.displine == 416) { /* End of VSYNC */ - self->cga.displine = 0; - self->cga.cgastat &= ~8; - self->cga.cgadispon = 1; - } - } else { - if (self->cga.cgadispon) - self->cga.cgastat &= ~1; - - timer_advance_u64(&self->cga.timer, self->cga.dispontime); - self->cga.linepos = 0; - - if (self->cga.displine == 400) { - /* Hardcode 640x400 window size */ - if ((640 != xsize) || (400 != ysize) || video_force_resize_get()) { - xsize = 640; - ysize = 400; - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - set_screen_size(xsize, ysize); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen(0, 0, xsize, ysize); - frames++; - - /* Fixed 640x400 resolution */ - video_res_x = 640; - video_res_y = 400; - - if (self->cga.cgamode & 0x02) { - if (self->cga.cgamode & 0x10) - video_bpp = 1; - else - video_bpp = 2; - } else - video_bpp = 0; - - self->cga.cgablink++; - } - } -} - -static void -compaq_plasma_mdaattr_rebuild(void) -{ - for (uint16_t c = 0; c < 256; c++) { - mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16; - if (c & 8) - mdaattr[c][0][1] = 15 + 16; - else - mdaattr[c][0][1] = 7 + 16; - } - - mdaattr[0x70][0][1] = 16; - mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15; - mdaattr[0xF0][0][1] = 16; - mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15; - mdaattr[0x78][0][1] = 16 + 7; - mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15; - mdaattr[0xF8][0][1] = 16 + 7; - mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15; - mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16; - mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16; - mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16; - mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16; -} - -static void -compaq_plasma_recalcattrs(compaq_plasma_t *self) -{ - int n; - - /* val behaves as follows: - * Bit 0: Attributes 01-06, 08-0E are inverse video - * Bit 1: Attributes 01-06, 08-0E are bold - * Bit 2: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF - * are inverse video - * Bit 3: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF - * are bold */ - - /* Set up colours */ - amber = makecol(0xff, 0x7d, 0x00); - black = makecol(0x64, 0x0c, 0x00); - - /* Initialize the attribute mapping. Start by defaulting everything - * to black on amber, and with bold set by bit 3 */ - for (n = 0; n < 256; n++) { - blinkcols[n][0] = normcols[n][0] = amber; - blinkcols[n][1] = normcols[n][1] = black; - } - - /* Colours 0x11-0xFF are controlled by bits 2 and 3 of the - * passed value. Exclude x0 and x8, which are always black on - * amber. */ - for (n = 0x11; n <= 0xFF; n++) { - if ((n & 7) == 0) - continue; - if (self->attrmap & 4) { /* Inverse */ - blinkcols[n][0] = normcols[n][0] = amber; - blinkcols[n][1] = normcols[n][1] = black; - } else { /* Normal */ - blinkcols[n][0] = normcols[n][0] = black; - blinkcols[n][1] = normcols[n][1] = amber; - } - } - /* Set up the 01-0E range, controlled by bits 0 and 1 of the - * passed value. When blinking is enabled this also affects 81-8E. */ - for (n = 0x01; n <= 0x0E; n++) { - if (n == 7) - continue; - if (self->attrmap & 1) { - blinkcols[n][0] = normcols[n][0] = amber; - blinkcols[n][1] = normcols[n][1] = black; - blinkcols[n + 128][0] = amber; - blinkcols[n + 128][1] = black; - } else { - blinkcols[n][0] = normcols[n][0] = black; - blinkcols[n][1] = normcols[n][1] = amber; - blinkcols[n + 128][0] = black; - blinkcols[n + 128][1] = amber; - } - } - /* Colours 07 and 0F are always amber on black. If blinking is - * enabled so are 87 and 8F. */ - for (n = 0x07; n <= 0x0F; n += 8) { - blinkcols[n][0] = normcols[n][0] = black; - blinkcols[n][1] = normcols[n][1] = amber; - blinkcols[n + 128][0] = black; - blinkcols[n + 128][1] = amber; - } - /* When not blinking, colours 81-8F are always amber on black. */ - for (n = 0x81; n <= 0x8F; n++) { - normcols[n][0] = black; - normcols[n][1] = amber; - } - - /* Finally do the ones which are solid black. These differ between - * the normal and blinking mappings */ - for (n = 0; n <= 0xFF; n += 0x11) - normcols[n][0] = normcols[n][1] = black; - - /* In the blinking range, 00 11 22 .. 77 and 80 91 A2 .. F7 are black */ - for (n = 0; n <= 0x77; n += 0x11) { - blinkcols[n][0] = blinkcols[n][1] = black; - blinkcols[n + 128][0] = blinkcols[n + 128][1] = black; - } -} - -static void * -compaq_plasma_init(UNUSED(const device_t *info)) -{ - compaq_plasma_t *self = calloc(1, sizeof(compaq_plasma_t)); - - video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma); - if (compaq_machine_type == COMPAQ_PORTABLEIII) - loadfont_ex("roms/machines/portableiii/K Combined.bin", 11, 0x4bb2); - else - loadfont_ex("roms/machines/portableiii/P.2 Combined.bin", 11, 0x4b49); - - self->cga.composite = 0; - self->cga.revision = 0; - - self->cga.vram = malloc(0x8000); - self->internal_monitor = 1; - - cga_comp_init(self->cga.revision); - timer_add(&self->cga.timer, compaq_plasma_poll, self, 1); - mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, compaq_plasma_read, NULL, NULL, compaq_plasma_write, NULL, NULL, NULL /*self->cga.vram*/, MEM_MAPPING_EXTERNAL, self); - io_sethandler(0x03d0, 0x0010, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); - io_sethandler(0x13c6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); - io_sethandler(0x1bc6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); - io_sethandler(0x23c6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); - - /* Default attribute mapping is 4 */ - self->attrmap = 4; - compaq_plasma_recalcattrs(self); - - self->cga.cgastat = 0xf4; - overscan_x = overscan_y = 16; - - self->cga.rgb_type = device_get_config_int("rgb_type"); - cga_palette = (self->cga.rgb_type << 1); - cgapal_rebuild(); - compaq_plasma_mdaattr_rebuild(); - - return self; -} - -static void -compaq_plasma_close(void *priv) -{ - compaq_plasma_t *self = (compaq_plasma_t *) priv; - - free(self->cga.vram); - free(self); -} - -static void -compaq_plasma_speed_changed(void *priv) -{ - compaq_plasma_t *self = (compaq_plasma_t *) priv; - - compaq_plasma_recalctimings(self); -} - -const device_config_t compaq_plasma_config[] = { - // clang-format off - { - .name = "rgb_type", - .description = "RGB type", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "Color", .value = 0 }, - { .description = "Green Monochrome", .value = 1 }, - { .description = "Amber Monochrome", .value = 2 }, - { .description = "Gray Monochrome", .value = 3 }, - { .description = "" } - } - }, - { .name = "", .description = "", .type = CONFIG_END } - // clang-format on -}; - -const device_t compaq_plasma_device = { - .name = "Compaq Plasma", - .internal_name = "compaq_plasma", - .flags = 0, - .local = 0, - .init = compaq_plasma_init, - .close = compaq_plasma_close, - .reset = NULL, - .available = NULL, - .speed_changed = compaq_plasma_speed_changed, - .force_redraw = NULL, - .config = compaq_plasma_config -}; static uint8_t read_ram(uint32_t addr, UNUSED(void *priv)) @@ -793,7 +132,8 @@ machine_at_compaq_init(const machine_t *model, int type) switch (type) { case COMPAQ_PORTABLEII: - machine_at_init(model); + machine_at_common_init(model); + device_add(&kbc_at_compaq_device); break; case COMPAQ_PORTABLEIII: @@ -801,7 +141,9 @@ 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_common_init(model); + device_add(&kbc_at_compaq_device); break; case COMPAQ_PORTABLEIII386: @@ -811,14 +153,14 @@ machine_at_compaq_init(const machine_t *model, int type) device_add(&compaq_plasma_device); device_add(&compaq_386_device); machine_at_common_init(model); - device_add(&keyboard_at_compaq_device); + device_add(&kbc_at_compaq_device); break; case COMPAQ_DESKPRO386: case COMPAQ_DESKPRO386_05_1988: device_add(&compaq_386_device); machine_at_common_init(model); - device_add(&keyboard_at_compaq_device); + device_add(&kbc_at_compaq_device); break; default: diff --git a/src/machine/m_at_grid.c b/src/machine/m_at_grid.c index 03b7288b9..448749589 100644 --- a/src/machine/m_at_grid.c +++ b/src/machine/m_at_grid.c @@ -342,7 +342,7 @@ int machine_at_grid1520_init(const machine_t *model) { machine_at_common_ide_init(model); mem_remap_top(384); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); // for now just select CGA with amber monitor //device_add(&cga_device); diff --git a/src/machine/m_at_misc.c b/src/machine/m_at_misc.c index d4264f07e..b6d16246c 100644 --- a/src/machine/m_at_misc.c +++ b/src/machine/m_at_misc.c @@ -66,7 +66,7 @@ machine_at_vpc2007_init(const machine_t *model) device_add(&i440bx_no_agp_device); device_add(&piix4e_device); device_add(&w83977f_370_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); /* real VPC provides invalid SPD data */ diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index a3ff921e3..0bbadca0c 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -40,6 +40,36 @@ #include <86box/clock.h> #include <86box/snd_ac97.h> +int +machine_at_acerv62x_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/acerv62x/v62xc0s1.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, 5, 0, 0, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + device_add(&i440fx_device); + device_add(&piix3_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX5 | FDC37C93X_APM)); + device_add(&sst_flash_29ee020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 128); + + return ret; +} + int machine_at_p65up5_cpknd_init(const machine_t *model) { @@ -79,7 +109,7 @@ machine_at_kn97_init(const machine_t *model) pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&w83877f_device); device_add(&intel_flash_bxt_device); device_add(&lm78_device); /* fans: Chassis, CPU, Power; temperature: MB */ @@ -112,7 +142,7 @@ machine_at_lx6_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440lx_device); device_add(&piix4e_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83977tf_device); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); @@ -120,6 +150,41 @@ machine_at_lx6_init(const machine_t *model) return ret; } +int +machine_at_optiplexgxa_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/optiplexgxa/DELL.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(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x11, PCI_CARD_NETWORK, 4, 0, 0, 0); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 2, 1); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x0F, PCI_CARD_BRIDGE, 0, 0, 0, 0); + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(machine_get_snd_device(machine)); + + device_add(&i440lx_device); + device_add(&piix4_device); + machine_at_optiplex_21152_init(); + device_add_params(&pc87307_device, (void *) (PCX730X_PHOENIX_42 | PCX7307_PC87307)); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + return ret; +} + int machine_at_spitfire_init(const machine_t *model) { @@ -131,7 +196,7 @@ machine_at_spitfire_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init_ex(model, 2); + machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -143,7 +208,7 @@ machine_at_spitfire_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440lx_device); device_add(&piix4e_device); - device_add(&fdc37c935_no_nvr_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX5 | FDC37C93X_NORMAL | FDC37C93X_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); device_add(&lm78_device); /* no reporting in BIOS */ @@ -179,8 +244,7 @@ machine_at_ma30d_init(const machine_t *model) 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_params(&fdc37c67x_device, (void *) (FDC37XXX2 | FDC37XXXX_370)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -208,7 +272,7 @@ machine_at_p6i440e2_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440ex_device); device_add(&piix4_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83977tf_device); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x03, 256); @@ -244,7 +308,7 @@ machine_at_p2bls_init(const machine_t *model) 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(&kbc_ps2_ami_pci_device); device_add(&w83977ef_device); #if 0 device_add(ics9xxx_get(ICS9150_08)); /* setting proper speeds requires some interaction with the AS97127F ASIC */ @@ -281,7 +345,7 @@ machine_at_lgibmx7g_init(const machine_t *model) 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(&kbc_ps2_ami_pci_device); device_add(&w83977tf_device); device_add(&winbond_flash_w29c020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -314,7 +378,7 @@ machine_at_p3bf_init(const machine_t *model) 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(&kbc_ps2_ami_pci_device); device_add(&w83977ef_device); device_add(ics9xxx_get(ICS9250_08)); device_add(&sst_flash_39sf020_device); @@ -351,7 +415,7 @@ machine_at_bf6_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&w83977ef_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -382,7 +446,7 @@ machine_at_bx6_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&w83977f_device); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); @@ -414,7 +478,7 @@ machine_at_ax6bc_init(const machine_t *model) 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(&kbc_ps2_ami_pci_device); device_add(&w83977tf_device); device_add(&sst_flash_29ee020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -446,7 +510,7 @@ machine_at_atc6310bxii_init(const machine_t *model) 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(&kbc_ps2_pci_device); device_add(&w83977ef_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -477,7 +541,7 @@ machine_at_686bx_init(const machine_t *model) 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(&kbc_ps2_ami_pci_device); device_add(&w83977tf_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); @@ -517,7 +581,7 @@ machine_at_p6sba_init(const machine_t *model) device_add(&i440bx_device); device_add(&piix4e_device); device_add(&w83977tf_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */ @@ -554,8 +618,7 @@ machine_at_s1846_init(const machine_t *model) pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); - device_add(&pc87309_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add_params(&pc87309_device, (void *) (PCX730X_AMI | PC87309_PC87309)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -591,7 +654,7 @@ machine_at_ficka6130_init(const machine_t *model) device_add(&via_apro_device); device_add(&via_vt82c596a_device); device_add(&w83877tf_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&sst_flash_29ee020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -624,7 +687,7 @@ machine_at_p3v133_init(const machine_t *model) device_add(&via_apro133_device); device_add(&via_vt82c596b_device); device_add(&w83977ef_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(ics9xxx_get(ICS9248_39)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 512); @@ -661,7 +724,7 @@ machine_at_p3v4x_init(const machine_t *model) device_add(&via_apro133a_device); device_add(&via_vt82c596b_device); device_add(&w83977ef_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(ics9xxx_get(ICS9250_18)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); @@ -694,7 +757,7 @@ machine_at_gt694va_init(const machine_t *model) device_add(&via_apro133a_device); device_add(&via_vt82c596b_device); device_add(&w83977ef_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 1024); device_add(&w83782d_device); /* fans: CPU, unused, unused; temperatures: System, CPU1, unused */ @@ -732,10 +795,9 @@ machine_at_vei8_init(const machine_t *model) 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(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&i440bx_device); + device_add(&i440zx_device); device_add(&piix4e_device); - device_add(&fdc37m60x_370_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add_params(&fdc37m60x_device, (void *) (FDC37XXX2 | FDC37XXXX_370)); device_add(ics9xxx_get(ICS9250_08)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x3, 512); @@ -764,7 +826,7 @@ machine_at_ms6168_common_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&voodoo_3_2000_agp_onboard_8m_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); @@ -860,7 +922,7 @@ machine_at_p6f99_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); device_add(&sis_5600_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&it8661f_device); device_add(&winbond_flash_w29c020_device); @@ -893,7 +955,7 @@ machine_at_m747_init(const machine_t *model) pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); device_add(&sis_5600_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&it8661f_device); device_add(&winbond_flash_w29c020_device); diff --git a/src/machine/m_at_slot2.c b/src/machine/m_at_slot2.c index da160c138..b9c556206 100644 --- a/src/machine/m_at_slot2.c +++ b/src/machine/m_at_slot2.c @@ -65,7 +65,7 @@ machine_at_6gxu_init(const machine_t *model) device_add(&i440gx_device); device_add(&piix4e_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&w83977ef_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); @@ -102,7 +102,7 @@ machine_at_s2dge_init(const machine_t *model) device_add(&i440gx_device); device_add(&piix4e_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83977tf_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); @@ -140,8 +140,7 @@ machine_at_fw6400gx_init(const machine_t *model) device_add(&i440gx_device); device_add(&piix4e_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87309_15c_device); + device_add_params(&pc87309_device, (void *) (PCX730X_15C | PCX730X_AMI | PC87309_PC87309)); device_add(ics9xxx_get(ICS9250_08)); device_add(&sst_flash_29ee020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 512); diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 3f8db4e8c..fe87564e7 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -64,7 +64,7 @@ machine_at_s370slm_init(const machine_t *model) device_add(&i440lx_device); device_add(&piix4e_device); device_add(&w83977tf_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_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 */ @@ -99,7 +99,7 @@ machine_at_prosignias31x_bx_init(const machine_t *model) device_add(&i440bx_device); device_add(&piix4e_device); device_add(&w83977ef_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&winbond_flash_w29c020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); device_add(&gl520sm_2d_device); /* fans: CPU, Chassis; temperature: System */ @@ -139,7 +139,7 @@ machine_at_s1857_init(const machine_t *model) 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(&kbc_ps2_ami_pci_device); device_add(&w83977ef_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -177,7 +177,7 @@ machine_at_p6bap_init(const machine_t *model) 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(&kbc_ps2_ami_pci_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -212,7 +212,7 @@ machine_at_p6bat_init(const machine_t *model) device_add(&via_apro133_device); device_add(&via_vt82c596b_device); device_add(&w83977ef_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -248,8 +248,9 @@ machine_at_cubx_init(const machine_t *model) 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(&kbc_ps2_ami_pci_device); device_add(&w83977ef_device); + device_add(&ide_cmd648_ter_qua_onboard_device); device_add(ics9xxx_get(ICS9250_08)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); @@ -282,7 +283,7 @@ machine_at_atc7020bxii_init(const machine_t *model) 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(&kbc_ps2_pci_device); device_add(&w83977ef_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); @@ -314,7 +315,7 @@ machine_at_m773_init(const machine_t *model) 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(&kbc_ps2_ami_pci_device); device_add(&it8671f_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); @@ -355,7 +356,7 @@ machine_at_ambx133_init(const machine_t *model) device_add(&i440bx_device); device_add(&piix4e_device); device_add(&w83977ef_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_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 */ @@ -386,17 +387,16 @@ machine_at_awo671r_init(const machine_t *model) 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(0x0D, PCI_CARD_VIDEO, 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(&kbc_ps2_pci_device); device_add(&sst_flash_39sf020_device); - if (gfxcard[0] == VID_INTERNAL) { - device_add(&chips_69000_onboard_device); - } + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); spd_register(SPD_TYPE_SDRAM, 0x3, 256); return ret; @@ -427,7 +427,7 @@ machine_at_63a1_init(const machine_t *model) device_add(&i440zx_device); device_add(&piix4e_device); device_add(&w83977tf_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); @@ -458,7 +458,7 @@ machine_at_apas3_init(const machine_t *model) device_add(&via_apro_device); device_add(&via_vt82c586b_device); device_add(&fdc37c669_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -492,7 +492,7 @@ machine_at_cuv4xls_init(const machine_t *model) 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(&kbc_ps2_ami_pci_device); device_add(ics9xxx_get(ICS9250_18)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 1024); @@ -528,7 +528,7 @@ machine_at_6via90ap_init(const machine_t *model) 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(&kbc_ps2_ami_pci_device); device_add(ics9xxx_get(ICS9250_18)); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 1024); @@ -563,7 +563,7 @@ machine_at_7sbb_init(const machine_t *model) pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&sis_5600_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&it8661f_device); device_add(&sst_flash_29ee020_device); /* assumed */ diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index c747d8cc0..402489d89 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -41,6 +41,77 @@ #include <86box/video.h> #include <86box/machine.h> +int +machine_at_v12p_init(const machine_t *model) + +{ + int ret = 0; + const char* fn; + + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + + machine_at_common_init(model); + + device_add(&ide_isa_device); + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SCSI, 1, 4, 3, 2); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 2, 1, 4, 3); + pci_register_slot(0x03, PCI_CARD_NORMAL, 3, 2, 1, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 4, 0, 0, 0); + pci_register_slot(0x05, PCI_CARD_NORMAL, 0, 0, 0, 0); + device_add(&i430lx_device); + device_add(&kbc_ps2_acer_pci_device); + device_add(&sio_zb_device); + device_add_params(&pc87310_device, (void *) (PC87310_ALI)); + device_add(&amd_am28f010_flash_device); + + return ret; +} + +static const device_config_t v12p_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "v12p", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "Acer BIOS V1.2 - Revision R1.4", .internal_name = "v12p_r14", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/v12p/v12p_14.bin", "" } }, + { .name = "Acer BIOS V1.2 - Revision R1.6", .internal_name = "v12p", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/v12p/v12p_16.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t v12p_device = { + .name = "Acer V12P", + .internal_name = "v12p_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = v12p_config +}; + void machine_at_premiere_common_init(const machine_t *model, int pci_switch) { @@ -56,9 +127,10 @@ machine_at_premiere_common_init(const machine_t *model, int pci_switch) pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_phoenix_device); + device_add(&kbc_ps2_phoenix_device); device_add(&sio_zb_device); - device_add(&fdc37c665_device); + device_add(&ide_rz1000_pci_single_channel_device); + device_add(&fdc37c665_ide_sec_device); device_add(&intel_flash_bxt_ami_device); } @@ -80,7 +152,7 @@ machine_at_sp4_common_init(const machine_t *model) pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_85c50x_device); device_add(&ide_cmd640_pci_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&fdc37c665_device); device_add(&intel_flash_bxt_device); } @@ -106,7 +178,7 @@ machine_at_excaliburpci_init(const machine_t *model) pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&fdc37c665_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&ide_cmd640_pci_legacy_only_device); device_add(&i430lx_device); @@ -136,7 +208,7 @@ machine_at_p5mp3_init(const machine_t *model) pci_register_slot(0x03, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 03 = Slot 3 */ pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&fdc_at_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&sio_zb_device); device_add(&catalyst_flash_device); @@ -156,7 +228,9 @@ machine_at_dellxp60_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); + machine_at_common_init_ex(model, 2); + + device_add(&amstrad_megapc_nvr_device); device_add(&ide_pci_device); pci_init(PCI_CONFIG_TYPE_2); @@ -169,7 +243,7 @@ machine_at_dellxp60_init(const machine_t *model) pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430lx_device); - device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&kbc_ps2_phoenix_device); device_add(&sio_zb_device); device_add(&fdc37c665_device); device_add(&intel_flash_bxt_ami_device); @@ -188,8 +262,10 @@ machine_at_opti560l_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init(model); - device_add(&ide_pci_2ch_device); + machine_at_common_init_ex(model, 2); + + device_add(&amstrad_megapc_nvr_device); + device_add(&ide_pci_device); pci_init(PCI_CONFIG_TYPE_2); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -198,7 +274,7 @@ machine_at_opti560l_init(const machine_t *model) pci_register_slot(0x08, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430lx_device); - device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&kbc_ps2_phoenix_device); device_add(&sio_zb_device); device_add(&i82091aa_device); device_add(&intel_flash_bxt_ami_device); @@ -218,7 +294,22 @@ machine_at_ambradp60_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_premiere_common_init(model, 0); + machine_at_common_init_ex(model, 2); + + device_add(&amstrad_megapc_nvr_device); + device_add(&ide_pci_device); + + pci_init(PCI_CONFIG_TYPE_2); + 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(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); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&kbc_ps2_phoenix_device); + device_add(&sio_zb_device); + device_add(&fdc37c665_ide_pri_device); + device_add(&intel_flash_bxt_ami_device); device_add(&i430lx_device); @@ -238,7 +329,7 @@ machine_at_valuepointp60_init(const machine_t *model) return ret; machine_at_common_init(model); - device_add(&ide_pci_2ch_device); + device_add(&ide_pci_device); pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -248,9 +339,9 @@ machine_at_valuepointp60_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_ps1_pci_device); + device_add(&kbc_ps2_ps1_pci_device); device_add(&sio_device); - device_add(&fdc37c665_device); + device_add(&fdc37c665_ide_device); device_add(&intel_flash_bxt_ami_device); device_add(&i430lx_device); @@ -297,7 +388,7 @@ machine_at_award_common_init(const machine_t *model) if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); device_add(&sio_zb_device); device_add(&intel_flash_bxt_device); } @@ -348,7 +439,7 @@ machine_at_pb520r_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&gd5434_onboard_pci_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&sio_zb_device); device_add(&i82091aa_ide_device); device_add(&intel_flash_bxt_ami_device); @@ -378,7 +469,7 @@ machine_at_m5pi_init(const machine_t *model) pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430lx_device); device_add(&sio_zb_device); - device_add(&keyboard_ps2_phoenix_device); + device_add(&kbc_ps2_phoenix_device); device_add(&ide_w83769f_pci_single_channel_device); device_add(&fdc37c665_ide_sec_device); device_add(&intel_flash_bxt_ami_device); @@ -409,7 +500,7 @@ machine_at_globalyst330_p5_init(const machine_t *model) device_add(&opti5x7_pci_device); device_add(&opti822_device); device_add(&sst_flash_29ee010_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -433,7 +524,7 @@ machine_at_excalibur_init(const machine_t *model) device_add(&opti5x7_device); device_add(&ide_opti611_vlb_device); device_add(&fdc37c661_device); - device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&kbc_ps2_intel_ami_pci_device); return ret; } @@ -462,7 +553,7 @@ machine_at_p5vl_init(const machine_t *model) device_add(&opti5x7_pci_device); device_add(&opti822_device); device_add(&sst_flash_29ee010_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -493,7 +584,7 @@ machine_at_excaliburpci2_init(const machine_t *model) pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&fdc37c665_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&ide_cmd640_pci_legacy_only_device); device_add(&sis_85c50x_device); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 02922b425..0088bc188 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -40,6 +40,7 @@ #include <86box/sio.h> #include <86box/video.h> #include <86box/machine.h> +#include <86box/sound.h> int machine_at_plato_init(const machine_t *model) @@ -79,6 +80,85 @@ machine_at_dellplato_init(const machine_t *model) return ret; } +int +machine_at_d842_init(const machine_t *model) + +{ + int ret = 0; + const char* fn; + + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + + machine_at_common_init(model); + + device_add(&ide_pci_2ch_device); + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Onboard */ + pci_register_slot(0x03, PCI_CARD_VIDEO, 4, 0, 0, 0); /* Onboard */ + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); /* Slot 01 */ + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 1, 3, 4); /* Slot 02 */ + + device_add(&kbc_ps2_pci_device); + device_add(&i430nx_device); + device_add(&sio_zb_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + +static const device_config_t d842_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "d842", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "PhoenixBIOS Pentium 1.03 - Revision 1.03.842", .internal_name = "d842_103", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842.BIN", "" } }, + { .name = "PhoenixBIOS Pentium 1.03 - Revision 1.09.842", .internal_name = "d842_109", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jul96.bin", "" } }, + { .name = "PhoenixBIOS Pentium 1.03 - Revision 1.10.842", .internal_name = "d842", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jun98_1.bin", "" } }, + { .name = "PhoenixBIOS 4.04 - Revision 1.05.842", .internal_name = "d842_105", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_mar96.bin", "" } }, + { .name = "PhoenixBIOS 4.04 - Revision 1.06.842", .internal_name = "d842_106", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_apr98.bin", "" } }, + { .name = "PhoenixBIOS 4.04 - Revision 1.07.842", .internal_name = "d842_107", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d842/d842_jun98.BIN", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t d842_device = { + .name = "Siemens-Nixdorf D842", + .internal_name = "d842_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = d842_config +}; + int machine_at_ambradp90_init(const machine_t *model) { @@ -110,19 +190,19 @@ machine_at_p54np4_init(const machine_t *model) return ret; machine_at_common_init(model); + device_add(&ide_vlb_2ch_device); - pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_init(PCI_CONFIG_TYPE_2 | PCI_CAN_SWITCH_TYPE); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 03 = Slot 1 */ - pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */ + pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 07 = Slot 1 */ + pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 06 = Slot 2 */ pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */ - pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */ - pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */ + pci_register_slot(0x04, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 04 = Slot 4 */ pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430nx_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&sio_zb_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&fdc37c665_ide_pri_device); - device_add(&ncr53c810_onboard_pci_device); device_add(&intel_flash_bxt_device); return ret; @@ -156,7 +236,7 @@ machine_at_tek932_init(const machine_t *model) if (bios_only || !ret) return ret; - + machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_2 | PCI_CAN_SWITCH_TYPE); @@ -166,11 +246,11 @@ machine_at_tek932_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 3, 2, 4); - device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&kbc_ps2_intel_ami_pci_device); device_add(&i430nx_device); device_add(&sio_zb_device); - device_add(&fdc37c665_ide_device); device_add(&ide_vlb_device); + device_add(&fdc37c665_ide_pri_device); device_add(&intel_flash_bxt_ami_device); return ret; @@ -198,7 +278,7 @@ machine_at_acerv30_init(const machine_t *model) pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i430fx_device); device_add(&piix_device); - device_add(&keyboard_ps2_acer_pci_device); + device_add(&kbc_ps2_acer_pci_device); device_add(&fdc37c665_device); device_add(&sst_flash_29ee010_device); @@ -227,7 +307,7 @@ machine_at_apollo_init(const machine_t *model) pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); device_add(&pc87332_398_device); @@ -236,6 +316,43 @@ machine_at_apollo_init(const machine_t *model) return ret; } +int +machine_at_optiplexgxl_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/optiplexgxl/DELL.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + device_add(&amstrad_megapc_nvr_device); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 3, 4, 2, 1); + pci_register_slot(0x10, PCI_CARD_VIDEO, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + + if (gfxcard[0] == VID_INTERNAL) + 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(&kbc_ps2_phoenix_pci_device); + device_add(&i430fx_device); + device_add(&piix_device); + device_add(&pc87332_device); + device_add(&dell_jumper_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + static void machine_at_zappa_gpio_init(void) { @@ -290,10 +407,9 @@ machine_at_zappa_init(const machine_t *model) pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_intel_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); - device_add(&pc87306_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); device_add(&intel_flash_bxt_ami_device); return ret; @@ -318,7 +434,7 @@ machine_at_powermatev_init(const machine_t *model) pci_register_slot(0x08, PCI_CARD_NORMAL, 0, 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); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); device_add(&fdc37c665_device); @@ -347,7 +463,7 @@ machine_at_hawk_init(const machine_t *model) pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_tg_ami_pci_device); + device_add(&kbc_ps2_tg_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); device_add(&fdc37c665_device); @@ -356,6 +472,7 @@ machine_at_hawk_init(const machine_t *model) return ret; } + int machine_at_pt2000_init(const machine_t *model) { @@ -377,7 +494,7 @@ machine_at_pt2000_init(const machine_t *model) pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Should be VIA, but we do not emulate that yet. */ - device_add(&keyboard_ps2_holtek_device); + device_add(&kbc_ps2_holtek_device); device_add(&i430fx_device); device_add(&piix_device); device_add(&pc87332_398_device); @@ -400,7 +517,7 @@ machine_at_pat54pv_init(const machine_t *model) machine_at_common_init(model); device_add(&opti5x7_device); - device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&kbc_ps2_intel_ami_pci_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -430,7 +547,7 @@ machine_at_hot543_init(const machine_t *model) device_add(&opti5x7_pci_device); device_add(&opti822_device); device_add(&sst_flash_29ee010_device); - device_add(&keyboard_at_device); + device_add(&kbc_at_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); @@ -460,7 +577,7 @@ machine_at_ncselp90_init(const machine_t *model) device_add(&opti5x7_pci_device); device_add(&opti822_device); device_add(&sst_flash_29ee010_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&ide_opti611_vlb_device); device_add(&fdc37c665_ide_sec_device); device_add(&ide_vlb_2ch_device); @@ -508,7 +625,7 @@ machine_at_sq588_init(const machine_t *model) pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_85c50x_device); device_add(&ide_cmd640_pci_single_channel_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&fdc37c665_ide_device); device_add(&sst_flash_29ee010_device); @@ -537,7 +654,7 @@ machine_at_p54sps_init(const machine_t *model) pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_85c50x_device); device_add(&ide_pci_2ch_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); device_add(&w83787f_device); device_add(&sst_flash_29ee010_device); @@ -568,7 +685,7 @@ machine_at_ms5109_init(const machine_t *model) pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_550x_85c503_device); device_add(&ide_w83769f_pci_device); - device_add(&keyboard_ps2_ami_device); + device_add(&kbc_ps2_ami_device); device_add(&w83787f_device); device_add(&sst_flash_29ee010_device); @@ -602,7 +719,7 @@ machine_at_torino_init(const machine_t *model) device_add(&sis_550x_85c503_device); device_add(&ide_um8673f_device); - device_add(&keyboard_ps2_tg_ami_device); + device_add(&kbc_ps2_tg_ami_device); device_add(&fdc37c665_device); device_add(&intel_flash_bxt_ami_device); @@ -634,7 +751,7 @@ machine_at_hot539_init(const machine_t *model) device_add(&umc_8890_device); device_add(&umc_8886af_device); device_add(&sst_flash_29ee010_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&um8663af_device); return ret; diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 3fe883323..d5fdc7e0f 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -24,7 +24,6 @@ #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> @@ -45,6 +44,16 @@ #include <86box/scsi_ncr53c8xx.h> #include <86box/thread.h> #include <86box/network.h> +#include <86box/pci.h> + +void +machine_at_optiplex_21152_init(void) +{ + uint8_t bus_index = pci_bridge_get_bus_index(device_add(&dec21152_device)); + pci_register_bus_slot(bus_index, 0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_bus_slot(bus_index, 0x0a, PCI_CARD_NORMAL, 4, 2, 1, 3); + pci_register_bus_slot(bus_index, 0x0b, PCI_CARD_NORMAL, 1, 3, 4, 2); +} int machine_at_acerv35n_init(const machine_t *model) @@ -69,7 +78,8 @@ machine_at_acerv35n_init(const machine_t *model) pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&fdc37c932fr_device); + /* The chip is not marked FR but the BIOS accesses register 06h of GPIO. */ + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX5 | FDC37C93X_FR)); device_add(&sst_flash_29ee010_device); return ret; @@ -101,7 +111,7 @@ machine_at_ap5vm_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&fdc37c665_device); device_add(&ncr53c810_onboard_pci_device); device_add(&intel_flash_bxt_device); @@ -131,7 +141,7 @@ machine_at_p55t2p4_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&w83877f_device); device_add(&intel_flash_bxt_device); @@ -160,7 +170,7 @@ machine_at_m7shi_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX5 | FDC37C93X_NORMAL)); device_add(&intel_flash_bxt_device); return ret; @@ -234,8 +244,7 @@ machine_at_tc430hx_init(const machine_t *model) device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87306_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); device_add(&intel_flash_bxt_ami_device); return ret; @@ -273,8 +282,7 @@ machine_at_infinia7200_init(const machine_t *model) device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87306_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); device_add(&intel_flash_bxt_ami_device); return ret; @@ -332,8 +340,7 @@ machine_at_cu430hx_common_init(const machine_t *model) device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87306_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); device_add(&intel_flash_bxt_ami_device); } @@ -405,8 +412,7 @@ machine_at_pcv90_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87306_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); device_add(&intel_flash_bxt_ami_device); return ret; @@ -451,7 +457,7 @@ machine_at_epc2102_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&kbc_ps2_intel_ami_pci_device); device_add(&i82091aa_device); device_add(&sst_flash_39sf010_device); @@ -480,7 +486,7 @@ machine_at_p55tvp4_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); // It uses the AMIKEY KBC + device_add(&kbc_ps2_ami_pci_device); // It uses the AMIKEY KBC device_add(&w83877f_device); device_add(&intel_flash_bxt_device); @@ -508,7 +514,7 @@ machine_at_5ivg_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&prime3c_device); device_add(&intel_flash_bxt_device); @@ -537,7 +543,7 @@ machine_at_8500tvxa_init(const machine_t *model) pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 3, 2, 1); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&um8669f_device); device_add(&sst_flash_29ee010_device); @@ -568,7 +574,7 @@ machine_at_presario2240_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c932qf_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX2 | FDC37C93X_NORMAL)); device_add(&sst_flash_29ee020_device); return ret; @@ -598,7 +604,7 @@ machine_at_presario4500_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c931apm_compaq_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX1 | FDC37C93X_APM)); device_add(&sst_flash_29ee020_device); return ret; @@ -631,7 +637,7 @@ machine_at_dellhannibalp_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c932fr_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX2 | FDC37C93X_FR)); device_add(&intel_flash_bxt_ami_device); return ret; @@ -659,7 +665,7 @@ machine_at_p55va_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c932fr_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX2 | FDC37C93X_FR)); device_add(&intel_flash_bxt_device); return ret; @@ -687,7 +693,7 @@ machine_at_brio80xx_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c935_370_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX5 | FDC37C93X_NORMAL | FDC37XXXX_370)); device_add(&sst_flash_29ee020_device); return ret; @@ -724,8 +730,7 @@ machine_at_pb680_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87306_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); device_add(&intel_flash_bxt_ami_device); return ret; @@ -756,7 +761,7 @@ machine_at_pb810_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c935_370_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX5 | FDC37C93X_NORMAL | FDC37XXXX_370)); device_add(&intel_flash_bxt_device); return ret; @@ -784,7 +789,7 @@ machine_at_mb520n_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&fdc37c669_device); device_add(&intel_flash_bxt_device); @@ -813,7 +818,7 @@ machine_at_i430vx_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430vx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&um8669f_device); device_add(&intel_flash_bxt_device); @@ -851,7 +856,7 @@ machine_at_gw2kte_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c932fr_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX2 | FDC37C93X_FR)); device_add(&intel_flash_bxt_ami_device); return ret; @@ -880,8 +885,7 @@ machine_at_ma23c_init(const machine_t *model) device_add(&i430tx_device); device_add(&piix4_device); device_add(&nec_mate_unk_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&fdc37c67x_device); + device_add_params(&fdc37c67x_device, (void *) (FDC37XXX2 | FDC37XXXX_370)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -916,7 +920,7 @@ machine_at_nupro592_init(const machine_t *model) device_add(&i430tx_device); device_add(&piix4_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83977ef_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); @@ -953,7 +957,7 @@ machine_at_tx97_init(const machine_t *model) pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83877tf_acorp_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); @@ -968,27 +972,55 @@ machine_at_tx97_init(const machine_t *model) return ret; } -#ifdef USE_AN430TX +int +machine_at_optiplexgn_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/optiplexgn/DELL.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, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 2, 1); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x10, PCI_CARD_VIDEO, 4, 0, 0, 0); /* Trio64V2/GX, temporarily Trio64V2/DX is given */ + pci_register_slot(0x11, PCI_CARD_NETWORK, 4, 0, 0, 0); /* 3C905, not yet emulated */ + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + pci_register_slot(0x0F, PCI_CARD_BRIDGE, 0, 0, 0, 0); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + if ((sound_card_current[0] == SOUND_INTERNAL) && machine_get_snd_device(machine)->available()) + machine_snd = device_add(machine_get_snd_device(machine)); + + device_add(&i430tx_device); + device_add(&piix4_device); + machine_at_optiplex_21152_init(); + device_add_params(&pc87307_device, (void *) (PCX730X_PHOENIX_42 | PCX7307_PC87307)); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} + int machine_at_an430tx_init(const machine_t *model) { int ret; -# if 1 - ret = bios_load_linear_combined2("roms/machines/an430tx/P10-0095.BIO", - "roms/machines/an430tx/P10-0095.BI1", - "roms/machines/an430tx/P10-0095.BI2", - "roms/machines/an430tx/P10-0095.BI3", - "roms/machines/an430tx/P10-0095.RCV", + ret = bios_load_linear_combined2("roms/machines/an430tx/ANP0911A.BIO", + "roms/machines/an430tx/ANP0911A.BI1", + "roms/machines/an430tx/ANP0911A.BI2", + "roms/machines/an430tx/ANP0911A.BI3", + "roms/machines/an430tx/ANP0911A.RCV", 0x3a000, 160); -# else - ret = bios_load_linear_combined2("roms/machines/an430tx/P06-0062.BIO", - "roms/machines/an430tx/P06-0062.BI1", - "roms/machines/an430tx/P06-0062.BI2", - "roms/machines/an430tx/P06-0062.BI3", - "roms/machines/an430tx/P10-0095.RCV", - 0x3a000, 160); -# endif if (bios_only || !ret) return ret; @@ -997,22 +1029,25 @@ machine_at_an430tx_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ - // pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); /* PIIX4 */ 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(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87307_both_device); +#ifdef FOLLOW_THE_SPECIFICATION + device_add_params(&pc87307_device, (void *) (PCX730X_PHOENIX_42I | PCX7307_PC97307)); +#else + /* The technical specification says Phoenix, a real machnine HWINFO dump says AMI '5'. */ + device_add_params(&pc87307_device, (void *) (PCX730X_AMI | PCX7307_PC97307)); +#endif device_add(&intel_flash_bxt_ami_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); return ret; } -#endif /* USE_AN430TX */ int machine_at_ym430tx_init(const machine_t *model) @@ -1038,7 +1073,7 @@ machine_at_ym430tx_init(const machine_t *model) pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&w83977tf_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); @@ -1068,7 +1103,7 @@ machine_at_mb540n_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); /* PIIX4 */ device_add(&i430tx_device); device_add(&piix4_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&um8669f_device); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); @@ -1099,7 +1134,7 @@ machine_at_56a5_init(const machine_t *model) pci_register_slot(0x10, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&w83877f_device); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); @@ -1129,7 +1164,7 @@ machine_at_p5mms98_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83977tf_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); @@ -1161,7 +1196,7 @@ machine_at_richmond_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&it8671f_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); @@ -1194,8 +1229,7 @@ machine_at_tomahawk_init(const machine_t *model) pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&keyboard_ps2_intel_ami_pci_device); - device_add(&fdc37c67x_device); + device_add_params(&fdc37c67x_device, (void *) (FDC37XXX2 | FDC37XXXX_370)); device_add(&amd_flash_29f020a_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); device_add(&lm78_device); /* fans: Thermal, CPU, Chassis; temperature: unused */ @@ -1235,7 +1269,7 @@ machine_at_ficva502_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); device_add(&via_vpx_device); device_add(&via_vt82c586b_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&fdc37c669_370_device); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); @@ -1267,7 +1301,7 @@ machine_at_ficpa2012_init(const machine_t *model) device_add(&via_vp3_device); device_add(&via_vt82c586b_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&w83877f_device); device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x7, 512); @@ -1299,7 +1333,7 @@ machine_at_via809ds_init(const machine_t *model) device_add(&via_vp3_device); device_add(&via_vt82c586b_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&fdc37c669_device); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 512); @@ -1329,7 +1363,7 @@ machine_at_r534f_init(const machine_t *model) pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_5571_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83877f_device); device_add(&sst_flash_29ee010_device); @@ -1358,7 +1392,7 @@ machine_at_ms5146_init(const machine_t *model) pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_5571_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83877f_device); device_add(&sst_flash_29ee010_device); @@ -1387,7 +1421,7 @@ machine_at_cb52xsi_init(const machine_t *model) 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(&kbc_ps2_ami_pci_device); device_add(&fdc37c669_370_device); device_add(&sst_flash_29ee010_device); @@ -1416,7 +1450,7 @@ machine_at_sp97xv_init(const machine_t *model) pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x13, PCI_CARD_VIDEO, 1, 2, 3, 4); /* On-chip SiS graphics, absent here. */ device_add(&sis_5581_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83877f_device); device_add(&sst_flash_29ee010_device); @@ -1443,7 +1477,7 @@ machine_at_sq578_init(const machine_t *model) pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&sis_5581_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83877tf_device); device_add(&sst_flash_29ee010_device); @@ -1471,7 +1505,7 @@ machine_at_ms5172_init(const machine_t *model) pci_register_slot(0x0A, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&sis_5591_1997_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83877tf_device); device_add(&sst_flash_29ee010_device); @@ -1509,6 +1543,35 @@ machine_at_m560_init(const machine_t *model) return ret; } +int +machine_at_m5ata_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/m5ata/ATA1223.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_SOUTHBRIDGE_IDE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&ali1531_device); + device_add(&ali1543_device); /* -5 */ + spd_register(SPD_TYPE_SDRAM, 0x3, 64); + + return ret; +} + int machine_at_ms5164_init(const machine_t *model) { @@ -1553,7 +1616,7 @@ machine_at_thunderbolt_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init_ex(model, 2); + machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -1564,7 +1627,7 @@ machine_at_thunderbolt_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 3, 0, 1, 2); device_add(&i430tx_device); device_add(&piix4_device); - device_add(&fdc37c935_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX5 | FDC37C93X_NORMAL | FDC37C93X_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x3, 128); diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 4b980f2b0..706608748 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -106,10 +106,9 @@ machine_at_thor_common_init(const machine_t *model, int has_video) if (has_video && (gfxcard[0] == VID_INTERNAL)) device_add(machine_get_vid_device(machine)); - device_add(&keyboard_ps2_intel_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); - device_add(&pc87306_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); device_add(&intel_flash_bxt_ami_device); } @@ -125,7 +124,7 @@ machine_at_p54tp4xe_common_init(const machine_t *model) pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); device_add(&fdc37c665_device); @@ -184,7 +183,7 @@ machine_at_exp8551_init(const machine_t *model) pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&i430fx_device); device_add(&piix_device); device_add(&w83787f_device); @@ -359,10 +358,9 @@ machine_at_endeavor_init(const machine_t *model) 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); device_add(&piix_device); - device_add(&pc87306_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); device_add(&intel_flash_bxt_ami_device); return ret; @@ -390,7 +388,7 @@ machine_at_ms5119_init(const machine_t *model) device_add(&i430fx_device); device_add(&piix_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83787f_device); device_add(&sst_flash_29ee010_device); @@ -455,10 +453,9 @@ machine_at_pb640_init(const machine_t *model) device_add(&piix_rev02_device); if (gfxcard[0] == VID_INTERNAL) - device_add(&gd5440_onboard_pci_device); + device_add(machine_get_vid_device(machine)); - device_add(&keyboard_ps2_intel_ami_pci_device); - device_add(&pc87306_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); device_add(&intel_flash_bxt_ami_device); return ret; @@ -484,7 +481,7 @@ machine_at_mb500n_init(const machine_t *model) pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&i430fx_device); device_add(&piix_no_mirq_device); device_add(&fdc37c665_device); @@ -516,7 +513,7 @@ machine_at_fmb_init(const machine_t *model) device_add(&i430fx_device); device_add(&piix_no_mirq_device); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); device_add(&w83787f_device); device_add(&intel_flash_bxt_device); @@ -546,7 +543,7 @@ machine_at_acerm3a_init(const machine_t *model) pci_register_slot(0x10, PCI_CARD_VIDEO, 4, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX5 | FDC37C93X_NORMAL)); device_add(&sst_flash_29ee010_device); @@ -576,7 +573,7 @@ machine_at_ap53_init(const machine_t *model) pci_register_slot(0x06, PCI_CARD_VIDEO, 1, 2, 3, 4); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&fdc37c669_device); device_add(&intel_flash_bxt_device); @@ -605,13 +602,97 @@ machine_at_8500tuc_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&um8669f_device); device_add(&intel_flash_bxt_device); return ret; } +int +machine_at_d943_init(const machine_t *model) + +{ + int ret = 0; + const char* fn; + + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + + machine_at_common_init_ex(model, 2); + device_add(&amstrad_megapc_nvr_device); + + 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(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 2, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 1, 3, 2, 4); + device_add(&i430hx_device); + device_add(&piix3_device); + device_add(&kbc_ps2_pci_device); + device_add(&fdc37c665_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_EDO, 0x7, 256); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + if (sound_card_current[0] == SOUND_INTERNAL) + machine_snd = device_add(machine_get_snd_device(machine)); + + return ret; +} + +static const device_config_t d943_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "d943", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, /*W1*/ + .bios = { + { .name = "PhoenixBIOS 4.05 - Revision 1.02.943", .internal_name = "d943_oct96", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_oct96.bin", "" } }, + { .name = "PhoenixBIOS 4.05 - Revision 1.03.943", .internal_name = "d943_dec96", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_dec96.bin", "" } }, + { .name = "PhoenixBIOS 4.05 - Revision 1.05.943", .internal_name = "d943_sept97", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_sept97.bin", "" } }, + { .name = "PhoenixBIOS 4.05 - Revision 1.06.943", .internal_name = "d943", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/d943/d943_oct97.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + + + +const device_t d943_device = { + .name = "Siemens-Nixdorf D943", + .internal_name = "d943_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = d943_config +}; + int machine_at_p55t2s_init(const machine_t *model) { @@ -634,8 +715,7 @@ machine_at_p55t2s_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430hx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87306_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); device_add(&intel_flash_bxt_device); return ret; @@ -663,7 +743,7 @@ machine_at_p5vxb_init(const machine_t *model) 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(&kbc_ps2_ami_pci_device); device_add(&w83877f_device); device_add(&sst_flash_29ee010_device); @@ -700,23 +780,65 @@ machine_at_gw2kma_init(const machine_t *model) device_add(&i430vx_device); device_add(&piix3_device); - device_add(&fdc37c932fr_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX2 | FDC37C93X_FR)); device_add(&intel_flash_bxt_ami_device); return ret; } +static const device_config_t ap5s_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ap5s", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "AwardBIOS v4.50PG - Revision R1.20", .internal_name = "ap5s_450pg", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/ap5s/ap5s120.bin", "" } }, + { .name = "AwardBIOS v4.51PG - Revision R1.50", .internal_name = "ap5s_r150", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/ap5s/AP5S150.BIN", "" } }, + { .name = "AwardBIOS v4.51PG - Revision R1.60", .internal_name = "ap5s", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/ap5s/ap5s160.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ap5s_device = { + .name = "AOpen AP5S", + .internal_name = "ap5s_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ap5s_config +}; + int machine_at_ap5s_init(const machine_t *model) { - int ret; + int ret = 0; + const char* fn; - ret = bios_load_linear("roms/machines/ap5s/AP5S150.BIN", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); @@ -728,7 +850,7 @@ machine_at_ap5s_init(const machine_t *model) pci_register_slot(0x13, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_5511_device); - device_add(&keyboard_ps2_ami_device); + device_add(&kbc_ps2_ami_device); device_add(&fdc37c665_device); device_add(&sst_flash_29ee010_device); @@ -757,7 +879,7 @@ machine_at_ms5124_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&sis_5511_device); - device_add(&keyboard_ps2_ami_device); + device_add(&kbc_ps2_ami_device); device_add(&w83787f_88h_device); device_add(&sst_flash_29ee010_device); @@ -786,7 +908,7 @@ machine_at_amis727_init(const machine_t *model) pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&sis_5511_device); - device_add(&keyboard_ps2_intel_ami_pci_device); + device_add(&kbc_ps2_intel_ami_pci_device); device_add(&fdc37c665_device); device_add(&intel_flash_bxt_device); @@ -819,19 +941,64 @@ machine_at_vectra54_init(const machine_t *model) device_add(&i430fx_device); device_add(&piix_device); - device_add(&fdc37c932_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX2 | FDC37C93X_NORMAL)); device_add(&sst_flash_29ee010_device); return ret; } +static const device_config_t c5sbm2_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "5sbm2", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "AwardBIOS v4.50GP - Revision 07/17/1995", .internal_name = "5sbm2_v450gp", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/5SBM0717.BIN", "" } }, + { .name = "AwardBIOS v4.50PG - Revision 03/26/1996", .internal_name = "5sbm2", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/5SBM0326.BIN", "" } }, + { .name = "AwardBIOS v4.51PG - Revision 2.2 (by Unicore Software)", .internal_name = "5sbm2_451pg", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/2A5ICC3A.BIN", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t c5sbm2_device = { + .name = "Chaintech 5SBM/5SBM2 (M103)", + .internal_name = "5sbm2_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = c5sbm2_config +}; + int machine_at_5sbm2_init(const machine_t *model) { - int ret; + int ret = 0; + const char* fn; - ret = bios_load_linear("roms/machines/5sbm2/5SBM0717.BIN", - 0x000e0000, 131072, 0); + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); if (bios_only || !ret) return ret; @@ -845,7 +1012,7 @@ machine_at_5sbm2_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); - device_add(&keyboard_at_ami_device); + device_add(&kbc_at_ami_device); device_add(&sis_550x_device); device_add(&um8663af_device); device_add(&sst_flash_29ee010_device); @@ -877,7 +1044,7 @@ machine_at_pc140_6260_init(const machine_t *model) device_add(&gd5436_onboard_pci_device); device_add(&sis_5511_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&fdc37c669_device); device_add(&sst_flash_29ee010_device); diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 935a26fb2..e06356c2c 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -65,7 +65,7 @@ machine_at_ap61_init(const machine_t *model) device_add(&i450kx_device); device_add(&sio_zb_device); device_add(&ide_cmd646_device); - device_add(&keyboard_ps2_acer_pci_device); + device_add(&kbc_ps2_acer_pci_device); device_add(&fdc37c665_device); device_add(&sst_flash_29ee010_device); // device_add(&intel_flash_bxt_device); @@ -100,7 +100,7 @@ machine_at_p6rp4_init(const machine_t *model) device_add(&sio_zb_device); device_add(&ide_cmd646_device); /* Input port bit 2 must be 1 or CMOS Setup is disabled. */ - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&fdc37c665_device); device_add(&intel_flash_bxt_device); @@ -129,7 +129,7 @@ machine_at_686nx_init(const machine_t *model) pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); // Uses the AMIKEY keyboard controller + device_add(&kbc_ps2_ami_pci_device); // Uses the AMIKEY keyboard controller device_add(&um8669f_device); device_add(&intel_flash_bxt_device); @@ -158,7 +158,7 @@ machine_at_mb600n_init(const machine_t *model) pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&fdc37c669_device); device_add(&intel_flash_bxt_device); @@ -188,8 +188,9 @@ machine_at_acerv60n_init(const machine_t *model) pci_register_slot(0x0C, PCI_CARD_NORMAL, 2, 3, 4, 1); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX5 | FDC37C93X_NORMAL)); device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 128); return ret; } @@ -216,9 +217,7 @@ machine_at_lgibmx61_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i440fx_device); device_add(&piix3_device); - // device_add(&keyboard_ps2_ami_pci_device); - device_add(&keyboard_ps2_ami_device); - // device_add(&w83787f_device); + device_add(&kbc_ps2_ami_device); device_add(&w83877f_president_device); device_add(&sst_flash_29ee010_device); @@ -251,8 +250,7 @@ machine_at_vs440fx_init(const machine_t *model) 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_params(&pc87307_device, (void *) (PCX730X_AMI | PCX7307_PC87307)); device_add(&intel_flash_bxt_ami_device); @@ -262,6 +260,42 @@ machine_at_vs440fx_init(const machine_t *model) return ret; } +int +machine_at_dellvenus_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2("roms/machines/dellvenus/1006CS1J.BIO", + "roms/machines/dellvenus/1006CS1J.BI1", + "roms/machines/dellvenus/1006CS1J.BI2", + "roms/machines/dellvenus/1006CS1J.BI3", + "roms/machines/dellvenus/1006CS1J.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_params(&pc87307_device, (void *) (PCX730X_AMI | PCX7307_PC87307)); + + device_add(&intel_flash_bxt_ami_device); + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(machine_get_snd_device(machine)); + + return ret; +} + int machine_at_gw2kvenus_init(const machine_t *model) { @@ -288,8 +322,7 @@ machine_at_gw2kvenus_init(const machine_t *model) 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_params(&pc87307_device, (void *) (PCX730X_AMI | PCX7307_PC87307)); device_add(&intel_flash_bxt_ami_device); @@ -325,8 +358,7 @@ machine_at_ap440fx_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87307_device); + device_add_params(&pc87307_device, (void *) (PCX730X_AMI | PCX7307_PC87307)); device_add(&intel_flash_bxt_ami_device); if (sound_card_current[0] == SOUND_INTERNAL) @@ -360,7 +392,7 @@ machine_at_8600ttc_init(const machine_t *model) pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&fdc37c669_device); device_add(&intel_flash_bxt_device); @@ -389,7 +421,7 @@ machine_at_m6mi_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&i440fx_device); device_add(&piix3_device); - device_add(&fdc37c935_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX5 | FDC37C93X_NORMAL)); device_add(&intel_flash_bxt_device); return ret; @@ -410,7 +442,7 @@ machine_at_p65up5_common_init(const machine_t *model, const device_t *northbridg pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(northbridge); device_add(&piix3_ioapic_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83877f_device); device_add(&sst_flash_29ee010_device); device_add(&ioapic_device); diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index 0360b5650..6a867f8f0 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -231,7 +231,7 @@ machine_at_ax59pro_init(const machine_t *model) device_add(&via_mvp3_device); device_add(&via_vt82c586b_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&w83877tf_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); @@ -262,7 +262,7 @@ machine_at_mvp3_init(const machine_t *model) device_add(&via_mvp3_device); device_add(&via_vt82c586b_device); - device_add(&keyboard_ps2_pci_device); + device_add(&kbc_ps2_pci_device); device_add(&w83877tf_acorp_device); device_add(&sst_flash_39sf010_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); @@ -294,7 +294,7 @@ machine_at_ficva503a_init(const machine_t *model) device_add(&via_mvp3_device); device_add(&via_vt82c686a_device); /* fans: CPU1, Chassis; temperatures: CPU, System, unused */ - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); hwm_values.temperatures[0] += 2; /* CPU offset */ @@ -332,7 +332,7 @@ machine_at_5emapro_init(const machine_t *model) device_add(&via_mvp3_device); /* Rebranded as EQ82C6638 */ device_add(&via_vt82c686a_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&sst_flash_39sf010_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); device_add(&via_vt82c686_hwm_device); /* fans: CPU1, Chassis; temperatures: CPU, System, unused */ @@ -343,6 +343,38 @@ machine_at_5emapro_init(const machine_t *model) return ret; } +int +machine_at_delhi3_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/delhi3/DELHI3.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(0x13, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + + device_add(&via_mvp3_device); + device_add(&via_vt82c596a_device); + device_add(&kbc_ps2_ami_pci_device); + device_add(&w83877tf_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 256); + + if ((sound_card_current[0] == SOUND_INTERNAL) && machine_get_snd_device(machine)) + device_add(machine_get_snd_device(machine)); + + return ret; +} + int machine_at_5sg100_init(const machine_t *model) { @@ -365,7 +397,7 @@ machine_at_5sg100_init(const machine_t *model) pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 0, 0, 0, 0); device_add(&sis_5591_1997_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&kbc_ps2_ami_pci_device); device_add(&w83877tf_device); device_add(&sst_flash_29ee010_device); diff --git a/src/machine/m_at_t3100e.c b/src/machine/m_at_t3100e.c index 3c83b0cce..92daa610c 100644 --- a/src/machine/m_at_t3100e.c +++ b/src/machine/m_at_t3100e.c @@ -813,7 +813,7 @@ machine_at_t3100e_init(const machine_t *model) machine_at_common_ide_init(model); - device_add(&keyboard_at_toshiba_device); + device_add(&kbc_at_toshiba_device); if (fdc_current[0] == FDC_INTERNAL) { device_add(&fdc_at_device); diff --git a/src/machine/m_elt.c b/src/machine/m_elt.c index 812755898..2c807782c 100644 --- a/src/machine/m_elt.c +++ b/src/machine/m_elt.c @@ -58,13 +58,13 @@ static void elt_vid_off_poll(void *priv) { cga_t *cga = priv; - uint8_t hdisp = cga->crtc[1]; + uint8_t hdisp = cga->crtc[CGA_CRTC_HDISP]; /* Don't display anything. * TODO: Do something less stupid to emulate backlight off. */ - cga->crtc[1] = 0; + cga->crtc[CGA_CRTC_HDISP] = 0; cga_poll(cga); - cga->crtc[1] = hdisp; + cga->crtc[CGA_CRTC_HDISP] = hdisp; } static void @@ -190,7 +190,7 @@ machine_elt_init(const machine_t *model) /* Keyboard goes after the video, because on XT compatibles it's dealt * with by the same PPI as the config switches and we need them to * indicate the correct display type */ - device_add(&keyboard_xt_device); + device_add(&kbc_xt_device); device_add(&elt_nvr_device); diff --git a/src/machine/m_europc.c b/src/machine/m_europc.c index b98a1f51e..4f3a3b8ff 100644 --- a/src/machine/m_europc.c +++ b/src/machine/m_europc.c @@ -646,11 +646,12 @@ europc_boot(UNUSED(const device_t *info)) * (JS9) can be used to "move" it to 0x0350, to get it out of * the way of other cards that need this range. */ + sys->jim = device_get_config_hex16("js9"); io_sethandler(sys->jim, 16, jim_read, NULL, NULL, jim_write, NULL, NULL, sys); /* Only after JIM has been initialized. */ - (void) device_add(&keyboard_xt_device); + (void) device_add(&kbc_xt_device); /* Enable and set up the FDC. */ (void) device_add(&fdc_xt_device); @@ -680,14 +681,14 @@ static const device_config_t europc_config[] = { { .name = "js9", .description = "JS9 Jumper (JIM)", - .type = CONFIG_INT, + .type = CONFIG_HEX16, .default_string = "", - .default_int = 0, + .default_int = 0x0250, .file_filter = "", .spinner = { 0 }, .selection = { - { .description = "Disabled (250h)", .value = 0 }, - { .description = "Enabled (350h)", .value = 1 }, + { .description = "Disabled (250h)", .value = 0x0250 }, + { .description = "Enabled (350h)", .value = 0x0350 }, { .description = "" } }, }, diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index ca9e72fca..092c00b8f 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -48,11 +48,10 @@ #include <86box/snd_sn76489.h> #include <86box/video.h> #include <86box/vid_cga_comp.h> +#include <86box/m_pcjr.h> #include <86box/machine.h> #include <86box/plat_unused.h> -#define PCJR_RGB 0 -#define PCJR_COMPOSITE 1 #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 @@ -63,50 +62,10 @@ #define STAT_IFULL 0x02 #define STAT_OFULL 0x01 -typedef struct pcjr_t { - /* Video Controller stuff. */ - mem_mapping_t mapping; - uint8_t crtc[32]; - int crtcreg; - int array_index; - uint8_t array[32]; - int array_ff; - int memctrl; - uint8_t stat; - int addr_mode; - uint8_t *vram; - uint8_t *b8000; - int linepos; - int displine; - int sc; - int vc; - int dispon; - int con; - int coff; - int cursoron; - int blink; - int vsynctime; - int fullchange; - int vadj; - uint16_t ma; - uint16_t maback; - uint64_t dispontime; - uint64_t dispofftime; - pc_timer_t timer; - int firstline; - int lastline; - int composite; - int apply_hd; - /* Keyboard Controller stuff. */ - int latched; - int data; - int serial_data[44]; - int serial_pos; - uint8_t pa; - uint8_t pb; - pc_timer_t send_delay_timer; -} pcjr_t; +static uint8_t key_queue[16]; +static int key_queue_start = 0; +static int key_queue_end = 0; /*PCjr keyboard has no escape scancodes, and no scancodes beyond 54 Map right alt to 54h (FN) */ @@ -627,644 +586,6 @@ const scancode scancode_pcjr[512] = { // clang-format on }; -static video_timings_t timing_dram = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*No additional waitstates*/ - -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 key_queue[16]; -static int key_queue_start = 0; -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[(masked_memctrl & 0x06) << 14]; - pcjr->b8000 = &ram[(masked_memctrl & 0x30) << 11]; - } else { - pcjr->vram = &ram[(masked_memctrl & 0x07) << 14]; - pcjr->b8000 = &ram[(masked_memctrl & 0x38) << 11]; - } -} - -static void -recalc_timings(pcjr_t *pcjr) -{ - double _dispontime; - double _dispofftime; - double disptime; - - if (pcjr->array[0] & 1) { - disptime = pcjr->crtc[0] + 1; - _dispontime = pcjr->crtc[1]; - } else { - disptime = (pcjr->crtc[0] + 1) << 1; - _dispontime = pcjr->crtc[1] << 1; - } - - _dispofftime = disptime - _dispontime; - _dispontime *= CGACONST; - _dispofftime *= CGACONST; - pcjr->dispontime = (uint64_t) (_dispontime); - pcjr->dispofftime = (uint64_t) (_dispofftime); -} - -static int -vid_get_h_overscan_size(pcjr_t *pcjr) -{ - int ret; - - if (pcjr->array[0] & 1) - ret = 128; - else - ret = 256; - - return ret; -} - -static void -vid_out(uint16_t addr, uint8_t val, void *priv) -{ - pcjr_t *pcjr = (pcjr_t *) priv; - uint8_t old; - - switch (addr) { - case 0x3d0: - case 0x3d2: - case 0x3d4: - case 0x3d6: - pcjr->crtcreg = val & 0x1f; - return; - - case 0x3d1: - case 0x3d3: - case 0x3d5: - case 0x3d7: - old = pcjr->crtc[pcjr->crtcreg]; - pcjr->crtc[pcjr->crtcreg] = val & crtcmask[pcjr->crtcreg]; - if (pcjr->crtcreg == 2) - overscan_x = vid_get_h_overscan_size(pcjr); - if (old != val) { - if (pcjr->crtcreg < 0xe || pcjr->crtcreg > 0x10) { - pcjr->fullchange = changeframecount; - recalc_timings(pcjr); - } - } - return; - - case 0x3da: - if (!pcjr->array_ff) - pcjr->array_index = val & 0x1f; - else { - if (pcjr->array_index & 0x10) - val &= 0x0f; - pcjr->array[pcjr->array_index & 0x1f] = val; - if (!(pcjr->array_index & 0x1f)) - update_cga16_color(val); - } - pcjr->array_ff = !pcjr->array_ff; - break; - - case 0x3df: - pcjr->memctrl = val; - pcjr->pa = val; /* The PCjr BIOS expects the value written to 3DF to - then be readable from port 60, others it errors out - with only 64k RAM set (but somehow, still works with - 128k or more RAM). */ - pcjr->addr_mode = val >> 6; - recalc_address(pcjr); - break; - - default: - break; - } -} - -static uint8_t -vid_in(uint16_t addr, void *priv) -{ - pcjr_t *pcjr = (pcjr_t *) priv; - uint8_t ret = 0xff; - - switch (addr) { - case 0x3d0: - case 0x3d2: - case 0x3d4: - case 0x3d6: - ret = pcjr->crtcreg; - break; - - case 0x3d1: - case 0x3d3: - case 0x3d5: - case 0x3d7: - ret = pcjr->crtc[pcjr->crtcreg]; - break; - - case 0x3da: - pcjr->array_ff = 0; - pcjr->stat ^= 0x10; - ret = pcjr->stat; - break; - - default: - break; - } - - return ret; -} - -static void -vid_write(uint32_t addr, uint8_t val, void *priv) -{ - pcjr_t *pcjr = (pcjr_t *) priv; - - if (pcjr->memctrl == -1) - return; - - pcjr->b8000[addr & 0x3fff] = val; -} - -static uint8_t -vid_read(uint32_t addr, void *priv) -{ - const pcjr_t *pcjr = (pcjr_t *) priv; - - if (pcjr->memctrl == -1) - return 0xff; - - return (pcjr->b8000[addr & 0x3fff]); -} - -static int -vid_get_h_overscan_delta(pcjr_t *pcjr) -{ - int def; - int coef; - int ret; - - switch ((pcjr->array[0] & 0x13) | ((pcjr->array[3] & 0x08) << 5)) { - case 0x13: /*320x200x16*/ - def = 0x56; - coef = 8; - break; - case 0x12: /*160x200x16*/ - def = 0x2c; /* I'm going to assume a datasheet erratum here. */ - coef = 16; - break; - case 0x03: /*640x200x4*/ - def = 0x56; - coef = 8; - break; - case 0x01: /*80 column text*/ - def = 0x5a; - coef = 8; - break; - case 0x00: /*40 column text*/ - default: - def = 0x2c; - coef = 16; - break; - case 0x02: /*320x200x4*/ - def = 0x2b; - coef = 16; - break; - case 0x102: /*640x200x2*/ - def = 0x2b; - coef = 16; - break; - } - - ret = pcjr->crtc[0x02] - def; - - if (ret < -8) - ret = -8; - - if (ret > 8) - ret = 8; - - return ret * coef; -} - -static void -vid_blit_h_overscan(pcjr_t *pcjr) -{ - int cols = (pcjr->array[2] & 0xf) + 16;; - int y0 = pcjr->firstline << 1; - int y = (pcjr->lastline << 1) + 16; - int ho_s = vid_get_h_overscan_size(pcjr); - int i; - int x; - - if (pcjr->array[0] & 1) - x = (pcjr->crtc[1] << 3) + ho_s; - else - x = (pcjr->crtc[1] << 4) + ho_s; - - for (i = 0; i < 16; i++) { - hline(buffer32, 0, y0 + i, x, cols); - hline(buffer32, 0, y + i, x, cols); - - if (pcjr->composite) { - Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[y0 + i]); - Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[y + i]); - } else { - video_process_8(x, y0 + i); - video_process_8(x, y + i); - } - } -} - -static void -vid_poll(void *priv) -{ - pcjr_t *pcjr = (pcjr_t *) priv; - uint16_t ca = (pcjr->crtc[15] | (pcjr->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x; - int xs_temp; - int ys_temp; - int oldvc; - uint8_t chr; - uint8_t attr; - uint16_t dat; - int cols[4]; - int oldsc; - int l = (pcjr->displine << 1) + 16; - int ho_s = vid_get_h_overscan_size(pcjr); - int ho_d = vid_get_h_overscan_delta(pcjr) + (ho_s / 2); - - if (!pcjr->linepos) { - timer_advance_u64(&pcjr->timer, pcjr->dispofftime); - pcjr->stat &= ~1; - pcjr->linepos = 1; - oldsc = pcjr->sc; - if ((pcjr->crtc[8] & 3) == 3) - pcjr->sc = (pcjr->sc << 1) & 7; - if (pcjr->dispon) { - uint16_t offset = 0; - uint16_t mask = 0x1fff; - - if (pcjr->displine < pcjr->firstline) { - pcjr->firstline = pcjr->displine; - video_wait_for_buffer(); - } - pcjr->lastline = pcjr->displine; - cols[0] = (pcjr->array[2] & 0xf) + 16; - - if (pcjr->array[0] & 1) { - hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, cols[0]); - hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, cols[0]); - } else { - hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, cols[0]); - hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, cols[0]); - } - - switch (pcjr->addr_mode) { - case 0: /*Alpha*/ - offset = 0; - mask = 0x3fff; - break; - case 1: /*Low resolution graphics*/ - offset = (pcjr->sc & 1) * 0x2000; - break; - case 3: /*High resolution graphics*/ - offset = (pcjr->sc & 3) * 0x2000; - break; - default: - break; - } - switch ((pcjr->array[0] & 0x13) | ((pcjr->array[3] & 0x08) << 5)) { - case 0x13: /*320x200x16*/ - for (x = 0; x < pcjr->crtc[1]; x++) { - int ef_x = (x << 3) + ho_d; - dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | - pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; - pcjr->ma++; - buffer32->line[l][ef_x] = buffer32->line[l][ef_x + 1] = - buffer32->line[l + 1][ef_x] = buffer32->line[l + 1][ef_x + 1] = - pcjr->array[((dat >> 12) & pcjr->array[1] & 0x0f) + 16] + 16; - buffer32->line[l][ef_x + 2] = buffer32->line[l][ef_x + 3] = - buffer32->line[l + 1][ef_x + 2] = buffer32->line[l + 1][ef_x + 3] = - pcjr->array[((dat >> 8) & pcjr->array[1] & 0x0f) + 16] + 16; - buffer32->line[l][ef_x + 4] = buffer32->line[l][ef_x + 5] = - buffer32->line[l + 1][ef_x + 4] = buffer32->line[l + 1][ef_x + 5] = - pcjr->array[((dat >> 4) & pcjr->array[1] & 0x0f) + 16] + 16; - buffer32->line[l][ef_x + 6] = buffer32->line[l][ef_x + 7] = - buffer32->line[l + 1][ef_x + 6] = buffer32->line[l + 1][ef_x + 7] = - pcjr->array[(dat & pcjr->array[1] & 0x0f) + 16] + 16; - } - break; - case 0x12: /*160x200x16*/ - for (x = 0; x < pcjr->crtc[1]; x++) { - int ef_x = (x << 4) + ho_d; - dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | - pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; - pcjr->ma++; - buffer32->line[l][ef_x] = buffer32->line[l][ef_x + 1] = - buffer32->line[l][ef_x + 2] = buffer32->line[l][ef_x + 3] = - buffer32->line[l + 1][ef_x] = buffer32->line[l + 1][ef_x + 1] = - buffer32->line[l + 1][ef_x + 2] = buffer32->line[l + 1][ef_x + 3] = - pcjr->array[((dat >> 12) & pcjr->array[1] & 0x0f) + 16] + 16; - buffer32->line[l][ef_x + 4] = buffer32->line[l][ef_x + 5] = - buffer32->line[l][ef_x + 6] = buffer32->line[l][ef_x + 7] = - buffer32->line[l + 1][ef_x + 4] = buffer32->line[l + 1][ef_x + 5] = - buffer32->line[l + 1][ef_x + 6] = buffer32->line[l + 1][ef_x + 7] = - pcjr->array[((dat >> 8) & pcjr->array[1] & 0x0f) + 16] + 16; - buffer32->line[l][ef_x + 8] = buffer32->line[l][ef_x + 9] = - buffer32->line[l][ef_x + 10] = buffer32->line[l][ef_x + 11] = - buffer32->line[l + 1][ef_x + 8] = buffer32->line[l + 1][ef_x + 9] = - buffer32->line[l + 1][ef_x + 10] = buffer32->line[l + 1][ef_x + 11] = - pcjr->array[((dat >> 4) & pcjr->array[1] & 0x0f) + 16] + 16; - buffer32->line[l][ef_x + 12] = buffer32->line[l][ef_x + 13] = - buffer32->line[l][ef_x + 14] = buffer32->line[l][ef_x + 15] = - buffer32->line[l + 1][ef_x + 12] = buffer32->line[l + 1][ef_x + 13] = - buffer32->line[l + 1][ef_x + 14] = buffer32->line[l + 1][ef_x + 15] = - pcjr->array[(dat & pcjr->array[1] & 0x0f) + 16] + 16; - } - break; - case 0x03: /*640x200x4*/ - for (x = 0; x < pcjr->crtc[1]; x++) { - int ef_x = (x << 3) + ho_d; - dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1] << 8) | - pcjr->vram[((pcjr->ma << 1) & mask) + offset]; - pcjr->ma++; - for (uint8_t c = 0; c < 8; c++) { - chr = (dat >> 7) & 1; - chr |= ((dat >> 14) & 2); - buffer32->line[l][ef_x + c] = buffer32->line[l + 1][ef_x + c] = - pcjr->array[(chr & pcjr->array[1] & 0x0f) + 16] + 16; - dat <<= 1; - } - } - break; - case 0x01: /*80 column text*/ - for (x = 0; x < pcjr->crtc[1]; x++) { - int ef_x = (x << 3) + ho_d; - chr = pcjr->vram[((pcjr->ma << 1) & mask) + offset]; - attr = pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; - drawcursor = ((pcjr->ma == ca) && pcjr->con && pcjr->cursoron); - if (pcjr->array[3] & 4) { - cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16; - cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1] & 0x0f) + 16] + 16; - if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16; - cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1] & 0x0f) + 16] + 16; - } - if (pcjr->sc & 8) - for (uint8_t c = 0; c < 8; c++) - buffer32->line[l][ef_x + c] = - buffer32->line[l + 1][ef_x + c] = cols[0]; - else - for (uint8_t c = 0; c < 8; c++) - buffer32->line[l][ef_x + c] = - buffer32->line[l + 1][ef_x + c] = - cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - if (drawcursor) - for (uint8_t c = 0; c < 8; c++) { - buffer32->line[l][ef_x + c] ^= 15; - buffer32->line[l + 1][ef_x + c] ^= 15; - } - pcjr->ma++; - } - break; - case 0x00: /*40 column text*/ - for (x = 0; x < pcjr->crtc[1]; x++) { - int ef_x = (x << 4) + ho_d; - chr = pcjr->vram[((pcjr->ma << 1) & mask) + offset]; - attr = pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; - drawcursor = ((pcjr->ma == ca) && pcjr->con && pcjr->cursoron); - if (pcjr->array[3] & 4) { - cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16; - cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1] & 0x0f) + 16] + 16; - if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16; - cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1] & 0x0f) + 16] + 16; - } - pcjr->ma++; - if (pcjr->sc & 8) - for (uint8_t c = 0; c < 8; c++) - buffer32->line[l][ef_x + (c << 1)] = - buffer32->line[l][ef_x + (c << 1) + 1] = - buffer32->line[l + 1][ef_x + (c << 1)] = - buffer32->line[l + 1][ef_x + (c << 1) + 1] = cols[0]; - else - for (uint8_t c = 0; c < 8; c++) - buffer32->line[l][ef_x + (c << 1)] = - buffer32->line[l][ef_x + (c << 1) + 1] = - buffer32->line[l + 1][ef_x + (c << 1)] = - buffer32->line[l + 1][ef_x + (c << 1) + 1] = - cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - if (drawcursor) - for (uint8_t c = 0; c < 16; c++) { - buffer32->line[l][ef_x + c] ^= 15; - buffer32->line[l + 1][ef_x + c] ^= 15; - } - } - break; - case 0x02: /*320x200x4*/ - cols[0] = pcjr->array[0 + 16] + 16; - cols[1] = pcjr->array[1 + 16] + 16; - cols[2] = pcjr->array[2 + 16] + 16; - cols[3] = pcjr->array[3 + 16] + 16; - for (x = 0; x < pcjr->crtc[1]; x++) { - int ef_x = (x << 4) + ho_d; - dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | - pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; - pcjr->ma++; - for (uint8_t c = 0; c < 8; c++) { - buffer32->line[l][ef_x + (c << 1)] = - buffer32->line[l][ef_x + (c << 1) + 1] = - buffer32->line[l + 1][ef_x + (c << 1)] = - buffer32->line[l + 1][ef_x + (c << 1) + 1] = cols[dat >> 14]; - dat <<= 2; - } - } - break; - case 0x102: /*640x200x2*/ - cols[0] = pcjr->array[0 + 16] + 16; - cols[1] = pcjr->array[1 + 16] + 16; - for (x = 0; x < pcjr->crtc[1]; x++) { - int ef_x = (x << 4) + ho_d; - dat = (pcjr->vram[((pcjr->ma << 1) & mask) + offset] << 8) | - pcjr->vram[((pcjr->ma << 1) & mask) + offset + 1]; - pcjr->ma++; - for (uint8_t c = 0; c < 16; c++) { - buffer32->line[l][ef_x + c] = buffer32->line[l + 1][ef_x + c] = - cols[dat >> 15]; - dat <<= 1; - } - } - break; - - default: - break; - } - } else { - if (pcjr->array[3] & 4) { - if (pcjr->array[0] & 1) { - hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, (pcjr->array[2] & 0xf) + 16); - hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, (pcjr->array[2] & 0xf) + 16); - } else { - hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, (pcjr->array[2] & 0xf) + 16); - hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, (pcjr->array[2] & 0xf) + 16); - } - } else { - cols[0] = pcjr->array[0 + 16] + 16; - if (pcjr->array[0] & 1) { - hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, cols[0]); - hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, cols[0]); - } else { - hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, cols[0]); - hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, cols[0]); - } - } - } - if (pcjr->array[0] & 1) - x = (pcjr->crtc[1] << 3) + ho_s; - else - x = (pcjr->crtc[1] << 4) + ho_s; - if (pcjr->composite) { - Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[l]); - Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[l + 1]); - } else { - video_process_8(x, l); - video_process_8(x, l + 1); - } - pcjr->sc = oldsc; - if (pcjr->vc == pcjr->crtc[7] && !pcjr->sc) { - pcjr->stat |= 8; - } - pcjr->displine++; - if (pcjr->displine >= 360) - pcjr->displine = 0; - } else { - timer_advance_u64(&pcjr->timer, pcjr->dispontime); - if (pcjr->dispon) - pcjr->stat |= 1; - pcjr->linepos = 0; - if (pcjr->vsynctime) { - pcjr->vsynctime--; - if (!pcjr->vsynctime) { - pcjr->stat &= ~8; - } - } - if (pcjr->sc == (pcjr->crtc[11] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == ((pcjr->crtc[11] & 31) >> 1))) { - pcjr->con = 0; - pcjr->coff = 1; - } - if (pcjr->vadj) { - pcjr->sc++; - pcjr->sc &= 31; - pcjr->ma = pcjr->maback; - pcjr->vadj--; - if (!pcjr->vadj) { - pcjr->dispon = 1; - pcjr->ma = pcjr->maback = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff; - pcjr->sc = 0; - } - } else if (pcjr->sc == pcjr->crtc[9] || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == (pcjr->crtc[9] >> 1))) { - pcjr->maback = pcjr->ma; - pcjr->sc = 0; - oldvc = pcjr->vc; - pcjr->vc++; - pcjr->vc &= 127; - if (pcjr->vc == pcjr->crtc[6]) - pcjr->dispon = 0; - if (oldvc == pcjr->crtc[4]) { - pcjr->vc = 0; - pcjr->vadj = pcjr->crtc[5]; - if (!pcjr->vadj) - pcjr->dispon = 1; - if (!pcjr->vadj) - pcjr->ma = pcjr->maback = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff; - if ((pcjr->crtc[10] & 0x60) == 0x20) - pcjr->cursoron = 0; - else - pcjr->cursoron = pcjr->blink & 16; - } - if (pcjr->vc == pcjr->crtc[7]) { - pcjr->dispon = 0; - pcjr->displine = 0; - pcjr->vsynctime = 16; - picint(1 << 5); - if (pcjr->crtc[7]) { - if (pcjr->array[0] & 1) - x = (pcjr->crtc[1] << 3) + ho_s; - else - x = (pcjr->crtc[1] << 4) + ho_s; - pcjr->lastline++; - - xs_temp = x; - ys_temp = (pcjr->lastline - pcjr->firstline) << 1; - - if ((xs_temp > 0) && (ys_temp > 0)) { - int actual_ys = ys_temp; - - if (xs_temp < 64) - xs_temp = 656; - if (ys_temp < 32) - ys_temp = 400; - if (!enable_overscan) - xs_temp -= ho_s; - - if ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get()) { - xsize = xs_temp; - ysize = ys_temp; - - set_screen_size(xsize, ysize + (enable_overscan ? 32 : 0)); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - - vid_blit_h_overscan(pcjr); - - if (enable_overscan) { - video_blit_memtoscreen(0, pcjr->firstline << 1, - xsize, actual_ys + 32); - } else if (pcjr->apply_hd) { - video_blit_memtoscreen(ho_s / 2, (pcjr->firstline << 1) + 16, - xsize, actual_ys); - } else { - video_blit_memtoscreen(ho_d, (pcjr->firstline << 1) + 16, - xsize, actual_ys); - } - } - - frames++; - video_res_x = xsize; - video_res_y = ysize; - } - pcjr->firstline = 1000; - pcjr->lastline = 0; - pcjr->blink++; - } - } else { - pcjr->sc++; - pcjr->sc &= 31; - pcjr->ma = pcjr->maback; - } - if (pcjr->sc == (pcjr->crtc[10] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == ((pcjr->crtc[10] & 31) >> 1))) - pcjr->con = 1; - } -} static void kbd_write(uint16_t port, uint8_t val, void *priv) @@ -1435,35 +756,7 @@ speed_changed(void *priv) { pcjr_t *pcjr = (pcjr_t *) priv; - recalc_timings(pcjr); -} - -static void -pcjr_vid_init(pcjr_t *pcjr) -{ - int display_type; - - video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram); - - pcjr->memctrl = -1; - if (mem_size < 128) - pcjr->memctrl &= ~0x24; - - display_type = device_get_config_int("display_type"); - pcjr->composite = (display_type != PCJR_RGB); - pcjr->apply_hd = device_get_config_int("apply_hd"); - overscan_x = 256; - overscan_y = 32; - - mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, - vid_read, NULL, NULL, - vid_write, NULL, NULL, NULL, 0, pcjr); - io_sethandler(0x03d0, 16, - vid_in, NULL, NULL, vid_out, NULL, NULL, pcjr); - timer_add(&pcjr->timer, vid_poll, pcjr, 1); - - cga_palette = 0; - cgapal_rebuild(); + pcjr_recalc_timings(pcjr); } void @@ -1489,9 +782,11 @@ static const device_config_t pcjr_config[] = { .file_filter = "", .spinner = { 0 }, .selection = { - { .description = "RGB", .value = PCJR_RGB }, - { .description = "Composite", .value = PCJR_COMPOSITE }, - { .description = "" } + { .description = "RGB", .value = PCJR_RGB }, + { .description = "Composite", .value = PCJR_COMPOSITE }, + { .description = "RGB (no brown)", .value = PCJR_RGB_NO_BROWN }, + { .description = "RGB (IBM 5153)", .value = PCJR_RGB_IBM_5153 }, + { .description = "" } } }, { @@ -1534,6 +829,8 @@ machine_pcjr_init(UNUSED(const machine_t *model)) pcjr = calloc(1, sizeof(pcjr_t)); + is_pcjr = 1; + pic_init_pcjr(); pit_common_init(0, pit_irq0_timer_pcjr, NULL); @@ -1541,7 +838,7 @@ machine_pcjr_init(UNUSED(const machine_t *model)) /* Initialize the video controller. */ video_reset(gfxcard[0]); - loadfont("roms/video/mda/mda.rom", 0); + loadfont(FONT_IBM_MDA_437_PATH, 0); device_context(&pcjr_device); pcjr_vid_init(pcjr); device_context_restore(); @@ -1566,7 +863,8 @@ machine_pcjr_init(UNUSED(const machine_t *model)) device_add(&fdc_pcjr_device); device_add(&ns8250_pcjr_device); - serial_set_next_inst(SERIAL_MAX); /* So that serial_standalone_init() won't do anything. */ + /* So that serial_standalone_init() won't do anything. */ + serial_set_next_inst(SERIAL_MAX - 1); /* "All the inputs are 'read' with one 'IN' from address hex 201." - PCjr Technical Reference (Nov. 83), p.2-119 diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index c22463de4..cce0b9d00 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -82,6 +82,7 @@ typedef struct { uint8_t ps1_e0_regs[256]; serial_t *uart; + lpt_t *lpt; } ps1_t; static void @@ -135,7 +136,7 @@ ps1_write(uint16_t port, uint8_t val, void *priv) case 0x0102: if (!(ps->ps1_94 & 0x80)) { - lpt1_remove(); + lpt_port_remove(ps->lpt); serial_remove(ps->uart); if (val & 0x04) { if (val & 0x08) @@ -146,13 +147,13 @@ ps1_write(uint16_t port, uint8_t val, void *priv) if (val & 0x10) { switch ((val >> 5) & 3) { case 0: - lpt1_setup(LPT_MDA_ADDR); + lpt_port_setup(ps->lpt, LPT_MDA_ADDR); break; case 1: - lpt1_setup(LPT1_ADDR); + lpt_port_setup(ps->lpt, LPT1_ADDR); break; case 2: - lpt1_setup(LPT2_ADDR); + lpt_port_setup(ps->lpt, LPT2_ADDR); break; default: @@ -314,9 +315,9 @@ ps1_setup(int model) ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps); ps->uart = device_add_inst(&ns16450_device, 1); - - lpt1_remove(); - lpt1_setup(LPT_MDA_ADDR); + ps->lpt = device_add_inst(&lpt_port_device, 1); + lpt_port_remove(ps->lpt); + lpt_port_setup(ps->lpt, LPT_MDA_ADDR); mem_remap_top(384); @@ -345,7 +346,7 @@ ps1_setup(int model) 0xfc0000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL); } - lpt2_remove(); + lpt_set_next_inst(255); device_add(&ps1snd_device); @@ -394,7 +395,7 @@ ps1_common_init(const machine_t *model) dma16_init(); pic2_init(); - device_add(&keyboard_ps2_ps1_device); + device_add(&kbc_ps2_ps1_device); device_add(&port_6x_device); /* Audio uses ports 200h and 202-207h, so only initialize gameport on 201h. */ diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index 8a2760f15..d7fd2d753 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -39,6 +39,7 @@ typedef struct { ps2_190; serial_t *uart; + lpt_t *lpt; } ps2_isa_t; static void @@ -53,7 +54,7 @@ ps2_write(uint16_t port, uint8_t val, void *priv) case 0x0102: if (!(ps2->ps2_94 & 0x80)) { - lpt1_remove(); + lpt_port_remove(ps2->lpt); serial_remove(ps2->uart); if (val & 0x04) { if (val & 0x08) @@ -64,13 +65,13 @@ ps2_write(uint16_t port, uint8_t val, void *priv) if (val & 0x10) { switch ((val >> 5) & 3) { case 0: - lpt1_setup(LPT_MDA_ADDR); + lpt_port_setup(ps2->lpt, LPT_MDA_ADDR); break; case 1: - lpt1_setup(LPT1_ADDR); + lpt_port_setup(ps2->lpt, LPT1_ADDR); break; case 2: - lpt1_setup(LPT2_ADDR); + lpt_port_setup(ps2->lpt, LPT2_ADDR); break; default: @@ -166,8 +167,10 @@ ps2_isa_setup(int model, int cpu_type) ps2->uart = device_add_inst(&ns16450_device, 1); - lpt1_remove(); - lpt1_setup(LPT_MDA_ADDR); + ps2->lpt = device_add_inst(&lpt_port_device, 1); + + lpt_port_remove(ps2->lpt); + lpt_port_setup(ps2->lpt, LPT_MDA_ADDR); device_add(&port_92_device); @@ -197,7 +200,7 @@ ps2_isa_common_init(const machine_t *model) dma16_init(); pic2_init(); - device_add(&keyboard_ps2_device); + device_add(&kbc_ps2_device); device_add(&port_6x_ps2_device); } diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index d3f881b24..cdb833fd6 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -105,6 +105,7 @@ static struct ps2_t { int pending_cache_miss; serial_t *uart; + lpt_t *lpt; vga_t* mb_vga; int has_e0000_hole; @@ -477,7 +478,7 @@ model_50_write(uint16_t port, uint8_t val) { switch (port) { case 0x102: - lpt1_remove(); + lpt_port_remove(ps2.lpt); serial_remove(ps2.uart); if (val & 0x04) { if (val & 0x08) @@ -488,13 +489,13 @@ model_50_write(uint16_t port, uint8_t val) if (val & 0x10) { switch ((val >> 5) & 3) { case 0: - lpt1_setup(LPT_MDA_ADDR); + lpt_port_setup(ps2.lpt, LPT_MDA_ADDR); break; case 1: - lpt1_setup(LPT1_ADDR); + lpt_port_setup(ps2.lpt, LPT1_ADDR); break; case 2: - lpt1_setup(LPT2_ADDR); + lpt_port_setup(ps2.lpt, LPT2_ADDR); break; default: @@ -609,7 +610,7 @@ model_55sx_write(uint16_t port, uint8_t val) { switch (port) { case 0x102: - lpt1_remove(); + lpt_port_remove(ps2.lpt); serial_remove(ps2.uart); if (val & 0x04) { if (val & 0x08) @@ -620,13 +621,13 @@ model_55sx_write(uint16_t port, uint8_t val) if (val & 0x10) { switch ((val >> 5) & 3) { case 0: - lpt1_setup(LPT_MDA_ADDR); + lpt_port_setup(ps2.lpt, LPT_MDA_ADDR); break; case 1: - lpt1_setup(LPT1_ADDR); + lpt_port_setup(ps2.lpt, LPT1_ADDR); break; case 2: - lpt1_setup(LPT2_ADDR); + lpt_port_setup(ps2.lpt, LPT2_ADDR); break; default: @@ -668,7 +669,7 @@ model_70_type3_write(uint16_t port, uint8_t val) { switch (port) { case 0x102: - lpt1_remove(); + lpt_port_remove(ps2.lpt); serial_remove(ps2.uart); if (val & 0x04) { if (val & 0x08) @@ -679,13 +680,13 @@ model_70_type3_write(uint16_t port, uint8_t val) if (val & 0x10) { switch ((val >> 5) & 3) { case 0: - lpt1_setup(LPT_MDA_ADDR); + lpt_port_setup(ps2.lpt, LPT_MDA_ADDR); break; case 1: - lpt1_setup(LPT1_ADDR); + lpt_port_setup(ps2.lpt, LPT1_ADDR); break; case 2: - lpt1_setup(LPT2_ADDR); + lpt_port_setup(ps2.lpt, LPT2_ADDR); break; default: @@ -722,7 +723,7 @@ model_80_write(uint16_t port, uint8_t val) { switch (port) { case 0x102: - lpt1_remove(); + lpt_port_remove(ps2.lpt); serial_remove(ps2.uart); if (val & 0x04) { if (val & 0x08) @@ -733,13 +734,13 @@ model_80_write(uint16_t port, uint8_t val) if (val & 0x10) { switch ((val >> 5) & 3) { case 0: - lpt1_setup(LPT_MDA_ADDR); + lpt_port_setup(ps2.lpt, LPT_MDA_ADDR); break; case 1: - lpt1_setup(LPT1_ADDR); + lpt_port_setup(ps2.lpt, LPT1_ADDR); break; case 2: - lpt1_setup(LPT2_ADDR); + lpt_port_setup(ps2.lpt, LPT2_ADDR); break; default: @@ -775,7 +776,7 @@ ps55_model_50tv_write(uint16_t port, uint8_t val) ps2_mca_log(" Write SysBrd %04X %02X %04X:%04X\n", port, val, cs >> 4, cpu_state.pc); switch (port) { case 0x102: - lpt1_remove(); + lpt_port_remove(ps2.lpt); serial_remove(ps2.uart); if (val & 0x04) { if (val & 0x08) @@ -786,13 +787,13 @@ ps55_model_50tv_write(uint16_t port, uint8_t val) if (val & 0x10) { switch ((val >> 5) & 3) { case 0: - lpt1_setup(LPT_MDA_ADDR); + lpt_port_setup(ps2.lpt, LPT_MDA_ADDR); break; case 1: - lpt1_setup(LPT1_ADDR); + lpt_port_setup(ps2.lpt, LPT1_ADDR); break; case 2: - lpt1_setup(LPT2_ADDR); + lpt_port_setup(ps2.lpt, LPT2_ADDR); break; default: break; @@ -1032,7 +1033,7 @@ ps2_mca_board_common_init(void) ps2.setup = 0xff; - lpt1_setup(LPT_MDA_ADDR); + lpt_port_setup(ps2.lpt, LPT_MDA_ADDR); } static uint8_t @@ -1159,7 +1160,7 @@ ps2_mca_board_model_50_init(void) mem_remap_top(384); mca_init(4); - device_add(&keyboard_ps2_mca_2_device); + device_add(&kbc_ps2_mca_2_device); ps2.planar_read = model_50_read; ps2.planar_write = model_50_write; @@ -1180,7 +1181,7 @@ ps2_mca_board_model_60_init(void) mem_remap_top(384); mca_init(8); - device_add(&keyboard_ps2_mca_2_device); + device_add(&kbc_ps2_mca_2_device); ps2.planar_read = model_50_read; ps2.planar_write = model_50_write; @@ -1240,7 +1241,7 @@ ps2_mca_board_model_55sx_init(int has_sec_nvram, int slots) } mca_init(slots); - device_add(&keyboard_ps2_mca_1_device); + device_add(&kbc_ps2_mca_1_device); if (has_sec_nvram) device_add(&ps2_nvr_55ls_device); @@ -1419,7 +1420,7 @@ ps2_mca_board_model_70_type34_init(int is_type4, int slots) ps2.split_addr = mem_size * 1024; mca_init(slots); - device_add(&keyboard_ps2_mca_1_device); + device_add(&kbc_ps2_mca_1_device); ps2.planar_read = model_70_type3_read; ps2.planar_write = model_70_type3_write; @@ -1512,7 +1513,7 @@ ps2_mca_board_model_80_type2_init(void) ps2.split_addr = mem_size * 1024; mca_init(8); - device_add(&keyboard_ps2_mca_1_device); + device_add(&kbc_ps2_mca_1_device); ps2.planar_read = model_80_read; ps2.planar_write = model_80_write; @@ -1600,6 +1601,7 @@ machine_ps2_common_init(const machine_t *model) nmi_mask = 0x80; ps2.uart = device_add_inst(&ns16550_device, 1); + ps2.lpt = device_add_inst(&lpt_port_device, 1); ps2.has_e0000_hole = 0; } @@ -1778,7 +1780,7 @@ ps55_mca_board_model_50t_init(void) ps2.split_addr = mem_size * 1024; /* The slot 5 is reserved for the Integrated Fixed Disk II (an internal ESDI hard drive). */ mca_init(5); - device_add(&keyboard_ps2_mca_1_device); + device_add(&kbc_ps2_mca_1_device); ps2.planar_read = ps55_model_50t_read; ps2.planar_write = ps55_model_50tv_write; @@ -1822,7 +1824,7 @@ ps55_mca_board_model_50v_init(void) ps2.split_addr = mem_size * 1024; /* The slot 5 is reserved for the Integrated Fixed Disk II (an internal ESDI hard drive). */ mca_init(5); - device_add(&keyboard_ps2_mca_1_device); + device_add(&kbc_ps2_mca_1_device); ps2.planar_read = ps55_model_50v_read; ps2.planar_write = ps55_model_50tv_write; diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index 7072c5e78..1c7061d8a 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -44,12 +44,9 @@ #include <86box/video.h> #include <86box/vid_cga_comp.h> #include <86box/machine.h> +#include <86box/m_tandy.h> #include <86box/plat_unused.h> -enum { - TANDY_RGB = 0, - TANDY_COMPOSITE -}; enum { TYPE_TANDY = 0, @@ -65,80 +62,6 @@ enum { EEPROM_WRITE }; -typedef struct t1kvid_t { - mem_mapping_t mapping; - mem_mapping_t vram_mapping; - - uint8_t crtc[32]; - int crtcreg; - - int array_index; - uint8_t array[256]; - int memctrl; - uint8_t mode; - uint8_t col; - uint8_t stat; - - uint8_t *vram; - uint8_t *b8000; - uint32_t b8000_mask; - uint32_t b8000_limit; - uint8_t planar_ctrl; - uint8_t lp_strobe; - - int linepos; - int displine; - int sc; - int vc; - int dispon; - int con; - int coff; - int cursoron; - int blink; - int fullchange; - int vsynctime; - int vadj; - uint16_t ma; - uint16_t maback; - - uint64_t dispontime; - uint64_t dispofftime; - pc_timer_t timer; - int firstline; - int lastline; - - int composite; -} t1kvid_t; - -typedef struct t1keep_t { - char *path; - - int state; - int count; - int addr; - int clk; - uint16_t data; - uint16_t store[64]; -} t1keep_t; - -typedef struct tandy_t { - mem_mapping_t ram_mapping; - mem_mapping_t rom_mapping; /* SL2 */ - - uint8_t *rom; /* SL2 */ - uint8_t ram_bank; - uint8_t rom_bank; /* SL2 */ - int rom_offset; /* SL2 */ - - uint32_t base; - uint32_t mask; - int is_hx; - int is_sl2; - - t1kvid_t *vid; -} tandy_t; - -static video_timings_t timing_dram = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*No additional waitstates*/ static const scancode scancode_tandy[512] = { // clang-format off @@ -656,22 +579,8 @@ static const scancode scancode_tandy[512] = { { .mk = { 0 }, .brk = { 0 } } /* 1ff */ // clang-format on }; -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 crtcmask_sl[32] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, - 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static int eep_data_out; -static uint8_t vid_in(uint16_t addr, void *priv); -static void vid_out(uint16_t addr, uint8_t val, void *priv); +static int eep_data_out; #ifdef ENABLE_TANDY_LOG int tandy_do_log = ENABLE_TANDY_LOG; @@ -691,763 +600,7 @@ tandy_log(const char *fmt, ...) # define tandy_log(fmt, ...) #endif -static void -recalc_mapping(tandy_t *dev) -{ - t1kvid_t *vid = dev->vid; - mem_mapping_disable(&vid->mapping); - io_removehandler(0x03d0, 16, - vid_in, NULL, NULL, vid_out, NULL, NULL, dev); - - if (vid->planar_ctrl & 4) { - mem_mapping_enable(&vid->mapping); - if (vid->array[5] & 1) - mem_mapping_set_addr(&vid->mapping, 0xa0000, 0x10000); - else - mem_mapping_set_addr(&vid->mapping, 0xb8000, 0x8000); - io_sethandler(0x03d0, 16, vid_in, NULL, NULL, vid_out, NULL, NULL, dev); - } -} - -static void -recalc_timings(tandy_t *dev) -{ - t1kvid_t *vid = dev->vid; - - double _dispontime; - double _dispofftime; - double disptime; - - if (vid->mode & 1) { - disptime = vid->crtc[0] + 1; - _dispontime = vid->crtc[1]; - } else { - disptime = (vid->crtc[0] + 1) << 1; - _dispontime = vid->crtc[1] << 1; - } - - _dispofftime = disptime - _dispontime; - _dispontime *= CGACONST; - _dispofftime *= CGACONST; - vid->dispontime = (uint64_t) (_dispontime); - vid->dispofftime = (uint64_t) (_dispofftime); -} - -static void -recalc_address(tandy_t *dev) -{ - t1kvid_t *vid = dev->vid; - - if ((vid->memctrl & 0xc0) == 0xc0) { - vid->vram = &ram[((vid->memctrl & 0x06) << 14) + dev->base]; - vid->b8000 = &ram[((vid->memctrl & 0x30) << 11) + dev->base]; - vid->b8000_mask = 0x7fff; - } else { - vid->vram = &ram[((vid->memctrl & 0x07) << 14) + dev->base]; - vid->b8000 = &ram[((vid->memctrl & 0x38) << 11) + dev->base]; - vid->b8000_mask = 0x3fff; - } -} - -static void -recalc_address_sl(tandy_t *dev) -{ - t1kvid_t *vid = dev->vid; - - vid->b8000_limit = 0x8000; - - if (vid->array[5] & 1) { - vid->vram = &ram[((vid->memctrl & 0x04) << 14) + dev->base]; - vid->b8000 = &ram[((vid->memctrl & 0x20) << 11) + dev->base]; - } else if ((vid->memctrl & 0xc0) == 0xc0) { - vid->vram = &ram[((vid->memctrl & 0x06) << 14) + dev->base]; - vid->b8000 = &ram[((vid->memctrl & 0x30) << 11) + dev->base]; - } else { - vid->vram = &ram[((vid->memctrl & 0x07) << 14) + dev->base]; - vid->b8000 = &ram[((vid->memctrl & 0x38) << 11) + dev->base]; - if ((vid->memctrl & 0x38) == 0x38) - vid->b8000_limit = 0x4000; - } -} - -static void -vid_update_latch(t1kvid_t *vid) -{ - uint32_t lp_latch = vid->displine * vid->crtc[1]; - - vid->crtc[0x10] = (lp_latch >> 8) & 0x3f; - vid->crtc[0x11] = lp_latch & 0xff; -} - -static void -vid_out(uint16_t addr, uint8_t val, void *priv) -{ - tandy_t *dev = (tandy_t *) priv; - t1kvid_t *vid = dev->vid; - uint8_t old; - - if ((addr >= 0x3d0) && (addr <= 0x3d7)) - addr = (addr & 0xff9) | 0x004; - - switch (addr) { - case 0x03d4: - vid->crtcreg = val & 0x1f; - break; - - case 0x03d5: - old = vid->crtc[vid->crtcreg]; - if (dev->is_sl2) - vid->crtc[vid->crtcreg] = val & crtcmask_sl[vid->crtcreg]; - else - vid->crtc[vid->crtcreg] = val & crtcmask[vid->crtcreg]; - if (old != val) { - if (vid->crtcreg < 0xe || vid->crtcreg > 0x10) { - vid->fullchange = changeframecount; - recalc_timings(dev); - } - } - break; - - case 0x03d8: - old = vid->mode; - vid->mode = val; - if ((old ^ val) & 0x01) - recalc_timings(dev); - if (!dev->is_sl2) - update_cga16_color(vid->mode); - break; - - case 0x03d9: - vid->col = val; - break; - - case 0x03da: - vid->array_index = val & 0x1f; - break; - - case 0x3db: - if (!dev->is_sl2 && (vid->lp_strobe == 1)) - vid->lp_strobe = 0; - break; - - case 0x3dc: - if (!dev->is_sl2 && (vid->lp_strobe == 0)) { - vid->lp_strobe = 1; - vid_update_latch(vid); - } - break; - - case 0x03de: - if (vid->array_index & 16) - val &= 0xf; - vid->array[vid->array_index & 0x1f] = val; - if (dev->is_sl2) { - if ((vid->array_index & 0x1f) == 5) { - recalc_mapping(dev); - recalc_address_sl(dev); - } - } - break; - - case 0x03df: - vid->memctrl = val; - if (dev->is_sl2) - recalc_address_sl(dev); - else - recalc_address(dev); - break; - - case 0x0065: - if (val == 8) - return; /*Hack*/ - vid->planar_ctrl = val; - recalc_mapping(dev); - break; - - default: - break; - } -} - -static uint8_t -vid_in(uint16_t addr, void *priv) -{ - const tandy_t *dev = (tandy_t *) priv; - t1kvid_t *vid = dev->vid; - uint8_t ret = 0xff; - - if ((addr >= 0x3d0) && (addr <= 0x3d7)) - addr = (addr & 0xff9) | 0x004; - - switch (addr) { - case 0x03d4: - ret = vid->crtcreg; - break; - - case 0x03d5: - ret = vid->crtc[vid->crtcreg]; - break; - - case 0x03da: - ret = vid->stat; - break; - - case 0x3db: - if (!dev->is_sl2 && (vid->lp_strobe == 1)) - vid->lp_strobe = 0; - break; - - case 0x3dc: - if (!dev->is_sl2 && (vid->lp_strobe == 0)) { - vid->lp_strobe = 1; - vid_update_latch(vid); - } - break; - - default: - break; - } - - return ret; -} - -static void -vid_write(uint32_t addr, uint8_t val, void *priv) -{ - tandy_t *dev = (tandy_t *) priv; - t1kvid_t *vid = dev->vid; - - if (vid->memctrl == -1) - return; - - if (dev->is_sl2) { - if (vid->array[5] & 1) - vid->b8000[addr & 0xffff] = val; - else { - if ((addr & 0x7fff) < vid->b8000_limit) - vid->b8000[addr & 0x7fff] = val; - } - } else { - vid->b8000[addr & vid->b8000_mask] = val; - } -} - -static uint8_t -vid_read(uint32_t addr, void *priv) -{ - const tandy_t *dev = (tandy_t *) priv; - const t1kvid_t *vid = dev->vid; - - if (vid->memctrl == -1) - return 0xff; - - if (dev->is_sl2) { - if (vid->array[5] & 1) - return (vid->b8000[addr & 0xffff]); - if ((addr & 0x7fff) < vid->b8000_limit) - return (vid->b8000[addr & 0x7fff]); - else - return 0xff; - } else { - return (vid->b8000[addr & vid->b8000_mask]); - } -} - -static void -vid_poll(void *priv) -{ - tandy_t *dev = (tandy_t *) priv; - t1kvid_t *vid = dev->vid; - uint16_t ca = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x; - int c; - int xs_temp; - int ys_temp; - int oldvc; - uint8_t chr; - uint8_t attr; - uint16_t dat; - int cols[4]; - int col; - int oldsc; - - if (!vid->linepos) { - timer_advance_u64(&vid->timer, vid->dispofftime); - vid->stat |= 1; - vid->linepos = 1; - oldsc = vid->sc; - if ((vid->crtc[8] & 3) == 3) - vid->sc = (vid->sc << 1) & 7; - if (vid->dispon) { - if (vid->displine < vid->firstline) { - vid->firstline = vid->displine; - video_wait_for_buffer(); - } - vid->lastline = vid->displine; - cols[0] = (vid->array[2] & 0xf) + 16; - for (c = 0; c < 8; c++) { - if (vid->array[3] & 4) { - buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = cols[0]; - if (vid->mode & 1) { - buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = cols[0]; - } else { - buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = cols[0]; - } - } else if ((vid->mode & 0x12) == 0x12) { - buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = 0; - if (vid->mode & 1) { - buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = 0; - } else { - buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = 0; - } - } else { - buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = (vid->col & 15) + 16; - if (vid->mode & 1) { - buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = (vid->col & 15) + 16; - } else { - buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = (vid->col & 15) + 16; - } - } - } - if (dev->is_sl2 && (vid->array[5] & 1)) { /*640x200x16*/ - for (x = 0; x < vid->crtc[1] * 2; x++) { - dat = (vid->vram[(vid->ma << 1) & 0xffff] << 8) | vid->vram[((vid->ma << 1) + 1) & 0xffff]; - vid->ma++; - buffer32->line[vid->displine << 1][(x << 2) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 8] = vid->array[((dat >> 12) & 0xf) + 16] + 16; - buffer32->line[vid->displine << 1][(x << 2) + 9] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 9] = vid->array[((dat >> 8) & 0xf) + 16] + 16; - buffer32->line[vid->displine << 1][(x << 2) + 10] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 10] = vid->array[((dat >> 4) & 0xf) + 16] + 16; - buffer32->line[vid->displine << 1][(x << 2) + 11] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 11] = vid->array[(dat & 0xf) + 16] + 16; - } - } else if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/ - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1]; - vid->ma++; - buffer32->line[vid->displine << 1][(x << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 8] = buffer32->line[vid->displine << 1][(x << 3) + 9] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 9] = vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16; - buffer32->line[vid->displine << 1][(x << 3) + 10] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 10] = buffer32->line[vid->displine << 1][(x << 3) + 11] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 11] = vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16; - buffer32->line[vid->displine << 1][(x << 3) + 12] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 12] = buffer32->line[vid->displine << 1][(x << 3) + 13] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 13] = vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16; - buffer32->line[vid->displine << 1][(x << 3) + 14] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 14] = buffer32->line[vid->displine << 1][(x << 3) + 15] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 15] = vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16; - } - } else if (vid->array[3] & 0x10) { /*160x200x16*/ - for (x = 0; x < vid->crtc[1]; x++) { - if (dev->is_sl2) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1]; - } else { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1]; - } - vid->ma++; - buffer32->line[vid->displine << 1][(x << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 8] = buffer32->line[vid->displine << 1][(x << 4) + 9] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 9] = buffer32->line[vid->displine << 1][(x << 4) + 10] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 10] = buffer32->line[vid->displine << 1][(x << 4) + 11] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 11] = vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16; - buffer32->line[vid->displine << 1][(x << 4) + 12] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 12] = buffer32->line[vid->displine << 1][(x << 4) + 13] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 13] = buffer32->line[vid->displine << 1][(x << 4) + 14] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 14] = buffer32->line[vid->displine << 1][(x << 4) + 15] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 15] = vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16; - buffer32->line[vid->displine << 1][(x << 4) + 16] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 16] = buffer32->line[vid->displine << 1][(x << 4) + 17] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 17] = buffer32->line[vid->displine << 1][(x << 4) + 18] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 18] = buffer32->line[vid->displine << 1][(x << 4) + 19] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 19] = vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16; - buffer32->line[vid->displine << 1][(x << 4) + 20] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 20] = buffer32->line[vid->displine << 1][(x << 4) + 21] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 21] = buffer32->line[vid->displine << 1][(x << 4) + 22] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 22] = buffer32->line[vid->displine << 1][(x << 4) + 23] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 23] = vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16; - } - } else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/ - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 3) * 0x2000) + 1]; - vid->ma++; - for (c = 0; c < 8; c++) { - chr = (dat >> 6) & 2; - chr |= ((dat >> 15) & 1); - buffer32->line[vid->displine << 1][(x << 3) + 8 + c] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 8 + c] = vid->array[(chr & vid->array[1]) + 16] + 16; - dat <<= 1; - } - } - } else if (vid->mode & 1) { - for (x = 0; x < vid->crtc[1]; x++) { - chr = vid->vram[(vid->ma << 1) & 0x3fff]; - attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff]; - drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron); - if (vid->mode & 0x20) { - cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16; - cols[0] = vid->array[(((attr >> 4) & 7) & vid->array[1]) + 16] + 16; - if ((vid->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16; - cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16; - } - if (vid->sc & 8) { - for (c = 0; c < 8; c++) { - buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[0]; - } - } else { - for (c = 0; c < 8; c++) { - if (vid->sc == 8) { - buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0]; - } else { - buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } - if (drawcursor) { - for (c = 0; c < 8; c++) { - buffer32->line[vid->displine << 1][(x << 3) + c + 8] ^= 15; - buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] ^= 15; - } - } - vid->ma++; - } - } else if (!(vid->mode & 2)) { - for (x = 0; x < vid->crtc[1]; x++) { - chr = vid->vram[(vid->ma << 1) & 0x3fff]; - attr = vid->vram[((vid->ma << 1) + 1) & 0x3fff]; - drawcursor = ((vid->ma == ca) && vid->con && vid->cursoron); - if (vid->mode & 0x20) { - cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16; - cols[0] = vid->array[(((attr >> 4) & 7) & vid->array[1]) + 16] + 16; - if ((vid->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16; - cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16; - } - vid->ma++; - if (vid->sc & 8) { - for (c = 0; c < 8; c++) - buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = cols[0]; - } else { - for (c = 0; c < 8; c++) { - if (vid->sc == 8) { - buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0]; - } else { - buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } - if (drawcursor) { - for (c = 0; c < 16; c++) { - buffer32->line[vid->displine << 1][(x << 4) + c + 8] ^= 15; - buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] ^= 15; - } - } - } - } else if (!(vid->mode & 16)) { - cols[0] = (vid->col & 15); - col = (vid->col & 16) ? 8 : 0; - if (vid->mode & 4) { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; - } else if (vid->col & 32) { - cols[1] = col | 3; - cols[2] = col | 5; - cols[3] = col | 7; - } else { - cols[1] = col | 2; - cols[2] = col | 4; - cols[3] = col | 6; - } - cols[0] = vid->array[(cols[0] & vid->array[1]) + 16] + 16; - cols[1] = vid->array[(cols[1] & vid->array[1]) + 16] + 16; - cols[2] = vid->array[(cols[2] & vid->array[1]) + 16] + 16; - cols[3] = vid->array[(cols[3] & vid->array[1]) + 16] + 16; - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1]; - vid->ma++; - for (c = 0; c < 8; c++) { - buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - } else { - cols[0] = 0; - cols[1] = vid->array[(vid->col & vid->array[1]) + 16] + 16; - for (x = 0; x < vid->crtc[1]; x++) { - dat = (vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000)] << 8) | vid->vram[((vid->ma << 1) & 0x1fff) + ((vid->sc & 1) * 0x2000) + 1]; - vid->ma++; - for (c = 0; c < 16; c++) { - buffer32->line[vid->displine << 1][(x << 4) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - } - } - } else { - if (vid->array[3] & 4) { - if (vid->mode & 1) { - hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16); - hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16); - } else { - hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 4) + 16, (vid->array[2] & 0xf) + 16); - hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 4) + 16, (vid->array[2] & 0xf) + 16); - } - } else { - cols[0] = ((vid->mode & 0x12) == 0x12) ? 0 : (vid->col & 0xf) + 16; - if (vid->mode & 1) { - hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 3) + 16, cols[0]); - hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 3) + 16, cols[0]); - } else { - hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 4) + 16, cols[0]); - hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 4) + 16, cols[0]); - } - } - } - - if (vid->mode & 1) - x = (vid->crtc[1] << 3) + 16; - else - x = (vid->crtc[1] << 4) + 16; - if (!dev->is_sl2 && vid->composite) { - Composite_Process(vid->mode, 0, x >> 2, buffer32->line[vid->displine << 1]); - Composite_Process(vid->mode, 0, x >> 2, buffer32->line[(vid->displine << 1) + 1]); - } else { - video_process_8(x, vid->displine << 1); - video_process_8(x, (vid->displine << 1) + 1); - } - vid->sc = oldsc; - if (vid->vc == vid->crtc[7] && !vid->sc) - vid->stat |= 8; - vid->displine++; - if (vid->displine >= 360) - vid->displine = 0; - } else { - timer_advance_u64(&vid->timer, vid->dispontime); - if (vid->dispon) - vid->stat &= ~1; - vid->linepos = 0; - if (vid->vsynctime) { - vid->vsynctime--; - if (!vid->vsynctime) - vid->stat &= ~8; - } - if (vid->sc == (vid->crtc[11] & 31) || ((vid->crtc[8] & 3) == 3 && vid->sc == ((vid->crtc[11] & 31) >> 1))) { - vid->con = 0; - vid->coff = 1; - } - if (vid->vadj) { - vid->sc++; - vid->sc &= 31; - vid->ma = vid->maback; - vid->vadj--; - if (!vid->vadj) { - vid->dispon = 1; - if (dev->is_sl2 && (vid->array[5] & 1)) - vid->ma = vid->maback = vid->crtc[13] | (vid->crtc[12] << 8); - else - vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff; - vid->sc = 0; - } - } else if (vid->sc == vid->crtc[9] || ((vid->crtc[8] & 3) == 3 && vid->sc == (vid->crtc[9] >> 1))) { - vid->maback = vid->ma; - vid->sc = 0; - oldvc = vid->vc; - vid->vc++; - if (dev->is_sl2) - vid->vc &= 255; - else - vid->vc &= 127; - if (vid->vc == vid->crtc[6]) - vid->dispon = 0; - if (oldvc == vid->crtc[4]) { - vid->vc = 0; - vid->vadj = vid->crtc[5]; - if (!vid->vadj) - vid->dispon = 1; - if (!vid->vadj) { - if (dev->is_sl2 && (vid->array[5] & 1)) - vid->ma = vid->maback = vid->crtc[13] | (vid->crtc[12] << 8); - else - vid->ma = vid->maback = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff; - } - if ((vid->crtc[10] & 0x60) == 0x20) - vid->cursoron = 0; - else - vid->cursoron = vid->blink & 16; - } - if (vid->vc == vid->crtc[7]) { - vid->dispon = 0; - vid->displine = 0; - vid->vsynctime = 16; - picint(1 << 5); - if (vid->crtc[7]) { - if (vid->mode & 1) - x = (vid->crtc[1] << 3) + 16; - else - x = (vid->crtc[1] << 4) + 16; - vid->lastline++; - - xs_temp = x; - ys_temp = (vid->lastline - vid->firstline) << 1; - - if ((xs_temp > 0) && (ys_temp > 0)) { - if (xs_temp < 64) - xs_temp = 656; - if (ys_temp < 32) - ys_temp = 400; - if (!enable_overscan) - xs_temp -= 16; - - if ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get()) { - xsize = xs_temp; - ysize = ys_temp; - set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - - if (enable_overscan) { - video_blit_memtoscreen(0, (vid->firstline - 4) << 1, - xsize, ((vid->lastline - vid->firstline) + 8) << 1); - } else { - video_blit_memtoscreen(8, vid->firstline << 1, - xsize, (vid->lastline - vid->firstline) << 1); - } - } - - frames++; - - video_res_x = xsize; - video_res_y = ysize; - if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/ - video_res_x /= 2; - video_bpp = 4; - } else if (vid->array[3] & 0x10) { /*160x200x16*/ - video_res_x /= 4; - video_bpp = 4; - } else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/ - video_bpp = 2; - } else if (vid->mode & 1) { - video_res_x /= 8; - video_res_y /= vid->crtc[9] + 1; - video_bpp = 0; - } else if (!(vid->mode & 2)) { - video_res_x /= 16; - video_res_y /= vid->crtc[9] + 1; - video_bpp = 0; - } else if (!(vid->mode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else { - video_bpp = 1; - } - } - vid->firstline = 1000; - vid->lastline = 0; - vid->blink++; - } - } else { - vid->sc++; - vid->sc &= 31; - vid->ma = vid->maback; - } - if (vid->sc == (vid->crtc[10] & 31) || ((vid->crtc[8] & 3) == 3 && vid->sc == ((vid->crtc[10] & 31) >> 1))) - vid->con = 1; - } -} - -static void -vid_speed_changed(void *priv) -{ - tandy_t *dev = (tandy_t *) priv; - - recalc_timings(dev); -} - -static void -vid_close(void *priv) -{ - tandy_t *dev = (tandy_t *) priv; - - free(dev->vid); - dev->vid = NULL; -} - -static void -vid_init(tandy_t *dev) -{ - int display_type; - t1kvid_t *vid; - - vid = calloc(1, sizeof(t1kvid_t)); - vid->memctrl = -1; - - video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram); - - display_type = device_get_config_int("display_type"); - vid->composite = (display_type != TANDY_RGB); - - cga_comp_init(1); - - if (dev->is_sl2) { - vid->b8000_limit = 0x8000; - vid->planar_ctrl = 4; - overscan_x = overscan_y = 16; - - io_sethandler(0x0065, 1, vid_in, NULL, NULL, vid_out, NULL, NULL, dev); - } else - vid->b8000_mask = 0x3fff; - - timer_add(&vid->timer, vid_poll, dev, 1); - mem_mapping_add(&vid->mapping, 0xb8000, 0x08000, - vid_read, NULL, NULL, vid_write, NULL, NULL, NULL, 0, dev); - io_sethandler(0x03d0, 16, - vid_in, NULL, NULL, vid_out, NULL, NULL, dev); - - dev->vid = vid; -} - -const device_config_t vid_config[] = { - // clang-format off - { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = TANDY_RGB, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "RGB", .value = TANDY_RGB }, - { .description = "Composite", .value = TANDY_COMPOSITE }, - { .description = "" } - } - }, - { .name = "", .description = "", .type = CONFIG_END } - // clang-format on -}; - -const device_t vid_device = { - .name = "Tandy 1000", - .internal_name = "tandy1000_video", - .flags = 0, - .local = 0, - .init = NULL, - .close = vid_close, - .reset = NULL, - .available = NULL, - .speed_changed = vid_speed_changed, - .force_redraw = NULL, - .config = vid_config -}; - -const device_t vid_device_hx = { - .name = "Tandy 1000 HX", - .internal_name = "tandy1000_hx_video", - .flags = 0, - .local = 0, - .init = NULL, - .close = vid_close, - .reset = NULL, - .available = NULL, - .speed_changed = vid_speed_changed, - .force_redraw = NULL, - .config = vid_config -}; - -const device_t vid_device_sl = { - .name = "Tandy 1000SL2", - .internal_name = "tandy1000_sl_video", - .flags = 0, - .local = 1, - .init = NULL, - .close = vid_close, - .reset = NULL, - .available = NULL, - .speed_changed = vid_speed_changed, - .force_redraw = NULL, - .config = NULL -}; static void eep_write(UNUSED(uint16_t addr), uint8_t val, void *priv) @@ -1632,12 +785,12 @@ tandy_write(uint16_t addr, uint8_t val, void *priv) } if (dev->is_hx) { io_removehandler(0x03d0, 16, - vid_in, NULL, NULL, vid_out, NULL, NULL, dev); + tandy_vid_in, NULL, NULL, tandy_vid_out, NULL, NULL, dev); if (val & 0x01) mem_mapping_disable(&dev->vid->mapping); else { io_sethandler(0x03d0, 16, - vid_in, NULL, NULL, vid_out, NULL, NULL, dev); + tandy_vid_in, NULL, NULL, tandy_vid_out, NULL, NULL, dev); mem_mapping_set_addr(&dev->vid->mapping, 0xb8000, 0x8000); } } else { @@ -1656,7 +809,7 @@ tandy_write(uint16_t addr, uint8_t val, void *priv) mem_mapping_set_addr(&dev->ram_mapping, ((val >> 1) & 7) * 128 * 1024, 0x20000); - recalc_address_sl(dev); + tandy_recalc_address_sl(dev); dev->ram_bank = val; break; @@ -1792,7 +945,7 @@ machine_tandy1k_init(const machine_t *model, int type) MEM_MAPPING_INTERNAL, dev); mem_mapping_set_addr(&ram_low_mapping, 0, dev->base); - device_add(&keyboard_tandy_device); + device_add(&kbc_tandy_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_xt_tandy_device); @@ -1805,10 +958,10 @@ machine_tandy1k_init(const machine_t *model, int type) keyboard_set_table(scancode_tandy); io_sethandler(0x00a0, 1, tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev); - device_context(&vid_device); - vid_init(dev); + device_context(&tandy_1000_video_device); + tandy_vid_init(dev); device_context_restore(); - device_add_ex(&vid_device, dev); + device_add_ex(&tandy_1000_video_device, dev); device_add((type == TYPE_TANDY1000SX) ? &ncr8496_device : &sn76489_device); break; @@ -1817,10 +970,10 @@ machine_tandy1k_init(const machine_t *model, int type) keyboard_set_table(scancode_tandy); io_sethandler(0x00a0, 1, tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev); - device_context(&vid_device_hx); - vid_init(dev); + device_context(&tandy_1000hx_video_device); + tandy_vid_init(dev); device_context_restore(); - device_add_ex(&vid_device_hx, dev); + device_add_ex(&tandy_1000hx_video_device, dev); device_add(&ncr8496_device); device_add(&eep_1000hx_device); break; @@ -1830,10 +983,10 @@ machine_tandy1k_init(const machine_t *model, int type) init_rom(dev); io_sethandler(0xffe8, 8, tandy_read, NULL, NULL, tandy_write, NULL, NULL, dev); - device_context(&vid_device_sl); - vid_init(dev); + device_context(&tandy_1000sl_video_device); + tandy_vid_init(dev); device_context_restore(); - device_add_ex(&vid_device_sl, dev); + device_add_ex(&tandy_1000sl_video_device, dev); device_add(&pssj_device); device_add(&eep_1000sl2_device); break; @@ -1842,7 +995,7 @@ machine_tandy1k_init(const machine_t *model, int type) break; } - standalone_gameport_type = &gameport_device; + standalone_gameport_type = &gameport_200_device; eep_data_out = 0x0000; } diff --git a/src/machine/m_v86p.c b/src/machine/m_v86p.c index f152383d1..fbe7296f8 100644 --- a/src/machine/m_v86p.c +++ b/src/machine/m_v86p.c @@ -86,7 +86,7 @@ machine_v86p_init(const machine_t *model) device_add(&ct_82c100_device); device_add(&f82c606_device); - device_add(&keyboard_xt_device); + device_add(&kbc_xt_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_xt_device); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 13f9c52ca..2fee7873a 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -39,6 +39,7 @@ #include <86box/keyboard.h> #include <86box/rom.h> #include <86box/machine.h> +#include <86box/nvr.h> #include <86box/chipset.h> #include <86box/port_6x.h> #include <86box/video.h> @@ -56,7 +57,7 @@ machine_xt_common_init(const machine_t *model, int fixed_floppy) pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); nmi_init(); - standalone_gameport_type = &gameport_device; + standalone_gameport_type = &gameport_200_device; } static const device_config_t ibmpc_config[] = { @@ -85,7 +86,7 @@ static const device_config_t ibmpc_config[] = { { .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } }, { .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } }, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.4_8kb.bin", "" } }, { .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } }, { .files_no = 0 } @@ -159,7 +160,7 @@ machine_pc_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_pc_device); + device_add(&kbc_pc_device); machine_xt_common_init(model, 0); @@ -195,7 +196,7 @@ static const device_config_t ibmpc82_config[] = { { .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } }, { .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } }, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.4_8kb.bin", "" } }, { .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } }, { .files_no = 0 } @@ -269,7 +270,7 @@ machine_pc82_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_pc82_device); + device_add(&kbc_pc82_device); machine_xt_common_init(model, 0); @@ -282,48 +283,103 @@ machine_pc82_init(const machine_t *model) static const device_config_t ibmxt_config[] = { // clang-format off { - .name = "bios", - .description = "BIOS Version", - .type = CONFIG_BIOS, + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, .default_string = "ibm5160_1501512_5000027", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .bios = { - { .name = "1501512 (11/08/82)", .internal_name = "ibm5160_1501512_5000027", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt/BIOS_5160_08NOV82_U18_1501512.BIN", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" } }, - { .name = "1501512 (11/08/82) (Alt)", .internal_name = "ibm5160_1501512_6359116", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt/BIOS_5160_08NOV82_U18_1501512.BIN", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_6359116.BIN", "" } }, - { .name = "5000026 (08/16/82)", .internal_name = "ibm5160_5000026_5000027", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt/BIOS_5160_16AUG82_U18_5000026.BIN", "roms/machines/ibmxt/BIOS_5160_16AUG82_U19_5000027.BIN", "" } }, -#if 0 + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "1501512 (11/08/82)", + .internal_name = "ibm5160_1501512_5000027", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 65536, + .files = { "roms/machines/ibmxt/BIOS_5160_08NOV82_U18_1501512.BIN", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" } + }, + { + .name = "1501512 (11/08/82) (Alt)", + .internal_name = "ibm5160_1501512_6359116", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 65536, + .files = { "roms/machines/ibmxt/BIOS_5160_08NOV82_U18_1501512.BIN", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_6359116.BIN", "" } + }, + { + .name = "5000026 (08/16/82)", + .internal_name = "ibm5160_5000026_5000027", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 65536, + .files = { "roms/machines/ibmxt/BIOS_5160_16AUG82_U18_5000026.BIN", "roms/machines/ibmxt/BIOS_5160_16AUG82_U19_5000027.BIN", "" } + }, + // GlaBIOS for IBM XT - { .name = "GlaBIOS 0.2.5 (8088)", .internal_name = "glabios_025_8088", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/glabios/GLABIOS_0.2.5_8X.ROM", "" } }, - { .name = "GlaBIOS 0.2.5 (V20)", .internal_name = "glabios_025_v20", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/glabios/GLABIOS_0.2.5_VX.ROM", "" } }, + { + .name = "GlaBIOS 0.2.5 (8088)", + .internal_name = "glabios_025_8088", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 1, + .size = 40960, + .files = { "roms/machines/glabios/GLABIOS_0.2.5_8X.ROM", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" } + }, + { + .name = "GlaBIOS 0.2.5 (V20)", + .internal_name = "glabios_025_v20", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 1, + .size = 40960, + .files = { "roms/machines/glabios/GLABIOS_0.2.5_VX.ROM", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" } + }, // The following are Diagnostic ROMs. - { .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } }, - { .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } }, - { .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } }, -#endif + { + .name = "Supersoft Diagnostics", + .internal_name = "diag_supersoft", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 2, + .size = 65536, + .files = { "roms/machines/diagnostic/Supersoft_PCXT_32KB.bin", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" } + }, + { + .name = "Ruud's Diagnostic Rom", + .internal_name = "diag_ruuds", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 2, + .size = 65536, + .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.4_32kb.bin", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" } + }, + { + .name = "XT RAM Test", + .internal_name = "diag_xtramtest", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 2, + .size = 65536, + .files = { "roms/machines/diagnostic/xtramtest_32k.bin", "roms/machines/ibmxt/BIOS_5160_08NOV82_U19_5000027.BIN", "" } + }, { .files_no = 0 } }, }, { - .name = "enable_5161", + .name = "enable_5161", .description = "IBM 5161 Expansion Unit", - .type = CONFIG_BINARY, + .type = CONFIG_BINARY, .default_int = 1 }, { - .name = "enable_basic", + .name = "enable_basic", .description = "IBM Cassette Basic", - .type = CONFIG_BINARY, + .type = CONFIG_BINARY, .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } @@ -351,6 +407,8 @@ machine_xt_init(const machine_t *model) uint8_t enable_5161; uint8_t enable_basic; const char *fn; + uint16_t offset = 0; + uint32_t local = 0; /* No ROMs available. */ if (!device_available(model->device)) @@ -360,11 +418,17 @@ machine_xt_init(const machine_t *model) enable_5161 = machine_get_config_int("enable_5161"); enable_basic = machine_get_config_int("enable_basic"); fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); - ret = bios_load_linear(fn, 0x000fe000, 65536, 0x6000); + local = device_get_bios_local(model->device, device_get_config_bios("bios")); + + if (local == 0) // Offset for stock roms + offset = 0x6000; + ret = bios_load_linear(fn, 0x000fe000, 65536, offset); if (enable_basic && ret) { - fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); - (void) bios_load_aux_linear(fn, 0x000f8000, 24576, 0); + if (local == 0) { // needed for stock roms + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + (void) bios_load_aux_linear(fn, 0x000f8000, 24576, 0); + } fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 1); /* On the real machine, the BASIC is repeated. */ (void) bios_load_aux_linear(fn, 0x000f0000, 8192, 0); @@ -377,7 +441,7 @@ machine_xt_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_xt_device); + device_add(&kbc_xt_device); machine_xt_common_init(model, 0); @@ -398,7 +462,7 @@ machine_genxt_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_xt_device); + device_add(&kbc_xt_device); machine_xt_common_init(model, 0); @@ -408,42 +472,98 @@ machine_genxt_init(const machine_t *model) static const device_config_t ibmxt86_config[] = { // clang-format off { - .name = "bios", - .description = "BIOS Version", - .type = CONFIG_BIOS, + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, .default_string = "ibm5160_050986", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .bios = { - { .name = "1501512 (05/09/86)", .internal_name = "ibm5160_050986", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" } }, - { .name = "5000026 (01/10/86)", .internal_name = "ibm5160_011086", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt86/BIOS_5160_10JAN86_U18_62X0851_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_10JAN86_U19_62X0854_27256_F000.BIN", "" } }, - { .name = "1501512 (01/10/86) (Alt)", .internal_name = "ibm5160_011086_alt", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 65536, .files = { "roms/machines/ibmxt86/BIOS_5160_10JAN86_U18_62X0852_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_10JAN86_U19_62X0853_27256_F000.BIN", "" } }, -#if 0 + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "1501512 (05/09/86)", + .internal_name = "ibm5160_050986", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 65536, + .files = { "roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" } + }, + { + .name = "5000026 (01/10/86)", + .internal_name = "ibm5160_011086", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 65536, + .files = { "roms/machines/ibmxt86/BIOS_5160_10JAN86_U18_62X0851_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_10JAN86_U19_62X0854_27256_F000.BIN", "" } + }, + { + .name = "1501512 (01/10/86) (Alt)", + .internal_name = "ibm5160_011086_alt", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 65536, + .files = { "roms/machines/ibmxt86/BIOS_5160_10JAN86_U18_62X0852_27256_F800.BIN", "roms/machines/ibmxt86/BIOS_5160_10JAN86_U19_62X0853_27256_F000.BIN", "" } + }, + // GlaBIOS for IBM XT - { .name = "GlaBIOS 0.2.5 (8088)", .internal_name = "glabios_025_8088", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/glabios/GLABIOS_0.2.5_8X.ROM", "" } }, - { .name = "GlaBIOS 0.2.5 (V20)", .internal_name = "glabios_025_v20", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/glabios/GLABIOS_0.2.5_VX.ROM", "" } }, + { + .name = "GlaBIOS 0.2.5 (8088)", + .internal_name = "glabios_025_8088", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 1, + .size = 65536, + .files = { "roms/machines/glabios/GLABIOS_0.2.5_8X.ROM", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" } + }, + { + .name = "GlaBIOS 0.2.5 (V20)", + .internal_name = "glabios_025_v20", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 1, + .size = 65536, + .files = { "roms/machines/glabios/GLABIOS_0.2.5_VX.ROM", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" } + }, // The following are Diagnostic ROMs. - { .name = "Supersoft Diagnostics", .internal_name = "diag_supersoft", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/Supersoft_PCXT_8KB.bin", "" } }, - { .name = "Ruud's Diagnostic Rom", .internal_name = "diag_ruuds", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.3_8kb.bin", "" } }, - { .name = "XT RAM Test", .internal_name = "diag_xtramtest", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/diagnostic/xtramtest_8k.bin", "" } }, -#endif + { + .name = "Supersoft Diagnostics", + .internal_name = "diag_supersoft", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 2, + .size = 65536, + .files = { "roms/machines/diagnostic/Supersoft_PCXT_32KB.bin", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" } + }, + { + .name = "Ruud's Diagnostic Rom", + .internal_name = "diag_ruuds", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 2, + .size = 65536, + .files = { "roms/machines/diagnostic/ruuds_diagnostic_rom_v5.4_32kb.bin", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" } + }, + { + .name = "XT RAM Test", + .internal_name = "diag_xtramtest", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 2, + .size = 65536, + .files = { "roms/machines/diagnostic/xtramtest_32k.bin", "roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", "" } + }, + { .files_no = 0 } }, }, { - .name = "enable_5161", + .name = "enable_5161", .description = "IBM 5161 Expansion Unit", - .type = CONFIG_BINARY, + .type = CONFIG_BINARY, .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } @@ -470,6 +590,8 @@ machine_xt86_init(const machine_t *model) int ret = 0; uint8_t enable_5161; const char *fn; + uint16_t offset = 0; + uint32_t local = 0; /* No ROMs available. */ if (!device_available(model->device)) @@ -478,11 +600,17 @@ machine_xt86_init(const machine_t *model) device_context(model->device); enable_5161 = machine_get_config_int("enable_5161"); fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); - ret = bios_load_linear(fn, 0x000fe000, 65536, 0x6000); + local = device_get_bios_local(model->device, device_get_config_bios("bios")); + + if (local == 0) // Offset for stock roms + offset = 0x6000; + ret = bios_load_linear(fn, 0x000fe000, 65536, offset); if (ret) { - fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); - (void) bios_load_aux_linear(fn, 0x000f8000, 24576, 0); + if (local == 0) { // needed for stock roms + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + (void) bios_load_aux_linear(fn, 0x000f8000, 24576, 0); + } fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 1); (void) bios_load_aux_linear(fn, 0x000f0000, 32768, 0); } @@ -491,7 +619,7 @@ machine_xt86_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_xt86_device); + device_add(&kbc_xt86_device); machine_xt_common_init(model, 0); @@ -504,7 +632,7 @@ machine_xt86_init(const machine_t *model) static void machine_xt_clone_init(const machine_t *model, int fixed_floppy) { - device_add(&keyboard_xtclone_device); + device_add(&kbc_xtclone_device); machine_xt_common_init(model, fixed_floppy); } @@ -541,6 +669,34 @@ machine_xt_amixt_init(const machine_t *model) return ret; } +int +machine_xt_tuliptc8_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/tuliptc8/tulip-bios_xt_compact_2.bin", + 0x000fc000, 16384, 0); + + if (bios_only || !ret) + return ret; + + device_add(&kbc_xt_fe2010_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + machine_common_init(model); + + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); + + nmi_init(); + standalone_gameport_type = &gameport_200_device; + + device_add(&amstrad_megapc_nvr_device); + + return ret; +} + // TODO // Onboard EGA Graphics (NSI Logic EVC315-S on early boards STMicroelectronics EGA on later revisions) // RTC @@ -707,7 +863,7 @@ machine_xt_pxxt_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_xt_device); + device_add(&kbc_xt_device); machine_xt_common_init(model, 0); @@ -787,7 +943,7 @@ machine_xt_pravetz16_imko4_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_pravetz_device); + device_add(&kbc_pravetz_device); machine_xt_common_init(model, 0); @@ -805,7 +961,7 @@ machine_xt_pravetz16s_cpu12p_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_xt_device); + device_add(&kbc_xt_device); machine_xt_common_init(model, 0); @@ -823,7 +979,7 @@ machine_xt_micoms_xl7turbo_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_xt_device); + device_add(&kbc_xt_device); machine_xt_common_init(model, 0); @@ -857,7 +1013,7 @@ machine_xt_mpc1600_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_pc82_device); + device_add(&kbc_pc82_device); machine_xt_common_init(model, 0); @@ -880,7 +1036,7 @@ machine_xt_pcspirit_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_pc82_device); + device_add(&kbc_pc82_device); machine_xt_common_init(model, 0); @@ -898,7 +1054,7 @@ machine_xt_pc700_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_pc_device); + device_add(&kbc_pc_device); machine_xt_common_init(model, 0); @@ -916,7 +1072,7 @@ machine_xt_pc500_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_pc_device); + device_add(&kbc_pc_device); machine_xt_common_init(model, 0); @@ -990,7 +1146,7 @@ machine_xt_vendex_init(const machine_t *model) static void machine_xt_hyundai_common_init(const machine_t *model, int fixed_floppy) { - device_add(&keyboard_xt_hyundai_device); + device_add(&kbc_xt_hyundai_device); machine_xt_common_init(model, fixed_floppy); } @@ -1138,7 +1294,7 @@ machine_xt_glabios_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&keyboard_xt_device); + device_add(&kbc_xt_device); machine_xt_common_init(model, 0); diff --git a/src/machine/m_xt_compaq.c b/src/machine/m_xt_compaq.c index f8c0b6a19..a6f8164f2 100644 --- a/src/machine/m_xt_compaq.c +++ b/src/machine/m_xt_compaq.c @@ -52,14 +52,15 @@ machine_xt_compaq_deskpro_init(const machine_t *model) pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); - device_add(&keyboard_xt_compaq_device); + device_add(&kbc_xt_compaq_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_xt_device); nmi_init(); - standalone_gameport_type = &gameport_device; + standalone_gameport_type = &gameport_200_device; - lpt1_remove(); - lpt1_setup(LPT_MDA_ADDR); + lpt_t *lpt = device_add_inst(&lpt_port_device, 1); + lpt_port_setup(lpt, LPT_MDA_ADDR); + lpt_set_3bc_used(1); return ret; } @@ -79,15 +80,16 @@ machine_xt_compaq_portable_init(const machine_t *model) pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); - device_add(&keyboard_xt_compaq_device); + device_add(&kbc_xt_compaq_device); if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_xt_device); nmi_init(); if (joystick_type) - device_add(&gameport_device); + device_add(&gameport_200_device); - lpt1_remove(); - lpt1_setup(LPT_MDA_ADDR); + lpt_t *lpt = device_add_inst(&lpt_port_device, 1); + lpt_port_setup(lpt, LPT_MDA_ADDR); + lpt_set_3bc_used(1); return ret; } diff --git a/src/machine/m_xt_laserxt.c b/src/machine/m_xt_laserxt.c index c0405f99a..fcfcebaa2 100644 --- a/src/machine/m_xt_laserxt.c +++ b/src/machine/m_xt_laserxt.c @@ -1,6 +1,7 @@ /*This is the chipset used in the LaserXT series model*/ #include #include +#include #include #include #include <86box/86box.h> @@ -21,125 +22,437 @@ #include <86box/keyboard.h> #include <86box/plat_unused.h> -static int laserxt_emspage[4]; -static int laserxt_emscontrol[4]; -static mem_mapping_t laserxt_ems_mapping[4]; -static int laserxt_ems_baseaddr_index = 0; -static int laserxt_is_lxt3 = 0; +#define EMS_TOTAL_MAX 0x00100000 -static uint32_t -get_laserxt_ems_addr(uint32_t addr) +typedef struct { - if (laserxt_emspage[(addr >> 14) & 3] & 0x80) { - addr = (!laserxt_is_lxt3 ? 0x70000 + (((mem_size + 64) & 255) << 10) : 0x30000 + (((mem_size + 320) & 511) << 10)) + ((laserxt_emspage[(addr >> 14) & 3] & 0x0F) << 14) + ((laserxt_emspage[(addr >> 14) & 3] & 0x40) << 12) + (addr & 0x3FFF); - } + uint8_t page; + uint8_t ctrl; - return addr; + uint32_t phys; + uint32_t virt; + + mem_mapping_t mapping; + + uint8_t *ram; + + void *parent; +} lxt_ems_t; + +typedef struct +{ + int ems_base_idx; + + lxt_ems_t ems[4]; + + uint16_t io_base; + uint32_t base; + + uint32_t mem_size; + + uint8_t *ram; + + void *parent; +} lxt_ems_board_t; + +typedef struct +{ + int is_lxt3; + + lxt_ems_board_t *ems_boards[2]; +} lxt_t; + +static void +ems_update_virt(lxt_ems_t *dev, uint8_t new_page) +{ + lxt_ems_board_t *board = (lxt_ems_board_t *) dev->parent; + lxt_t *lxt = (lxt_t *) board->parent; + + dev->page = new_page; + + if (new_page & 0x80) { + if (lxt->is_lxt3) { + /* Point invalid pages at 1 MB which is outside the maximum. */ + if ((new_page & 0x7f) >= 0x40) + dev->virt = EMS_TOTAL_MAX; + else + dev->virt = ((new_page & 0x7f) << 14); + } else + dev->virt = ((new_page & 0x0f) << 14) + ((new_page & 0x40) << 12); + + if (dev->virt >= board->mem_size) + dev->virt = EMS_TOTAL_MAX; + } else + dev->virt = EMS_TOTAL_MAX; + + dev->ram = board->ram + dev->virt; + + if ((new_page & 0x80) && (dev->virt != EMS_TOTAL_MAX)) { + mem_mapping_enable(&dev->mapping); + + mem_mapping_set_exec(&dev->mapping, dev->ram); + mem_mapping_set_p(&dev->mapping, dev->ram); + } else + mem_mapping_disable(&dev->mapping); + + flushmmucache(); } static void -laserxt_write(uint16_t port, uint8_t val, UNUSED(void *priv)) +lxt_ems_out(uint16_t port, uint8_t val, void *priv) { - uint32_t paddr; - uint32_t vaddr; - switch (port) { - case 0x0208: - case 0x4208: - case 0x8208: - case 0xC208: - laserxt_emspage[port >> 14] = val; - paddr = 0xC0000 + (port & 0xC000) + (((laserxt_ems_baseaddr_index + (4 - (port >> 14))) & 0x0C) << 14); - if (val & 0x80) { - mem_mapping_enable(&laserxt_ems_mapping[port >> 14]); - vaddr = get_laserxt_ems_addr(paddr); - mem_mapping_set_exec(&laserxt_ems_mapping[port >> 14], ram + vaddr); - } else { - mem_mapping_disable(&laserxt_ems_mapping[port >> 14]); - } - flushmmucache(); - break; - case 0x0209: - case 0x4209: - case 0x8209: - case 0xC209: - laserxt_emscontrol[port >> 14] = val; - laserxt_ems_baseaddr_index = 0; + lxt_ems_board_t *dev = (lxt_ems_board_t *) priv; + uint8_t reg = port >> 14; + uint32_t saddrs[8] = { 0xc4000, 0xc8000, 0xcc000, 0xd0000, + 0xd4000, 0xd8000, 0xdc000, 0xe0000 }; + uint32_t saddr; + + if (port & 0x0001) { + dev->ems[reg].ctrl = val; + + if (reg < 0x03) { + dev->ems_base_idx = (dev->ems_base_idx & ~(0x04 >> (2 - reg))) | + ((dev->ems[reg].ctrl & 0x80) >> (7 - reg)); + + saddr = saddrs[dev->ems_base_idx]; + for (uint8_t i = 0; i < 4; i++) { - laserxt_ems_baseaddr_index |= (laserxt_emscontrol[i] & 0x80) >> (7 - i); + uint32_t base = saddr + (i * 0x4000); + mem_mapping_set_addr(&dev->ems[i].mapping, base, 0x4000); + if (!(dev->ems[i].page & 0x80) || (dev->ems[i].virt == EMS_TOTAL_MAX)) + mem_mapping_disable(&dev->ems[i].mapping); } + } - mem_mapping_set_addr(&laserxt_ems_mapping[0], 0xC0000 + (((laserxt_ems_baseaddr_index + 4) & 0x0C) << 14), 0x4000); - mem_mapping_set_addr(&laserxt_ems_mapping[1], 0xC4000 + (((laserxt_ems_baseaddr_index + 3) & 0x0C) << 14), 0x4000); - mem_mapping_set_addr(&laserxt_ems_mapping[2], 0xC8000 + (((laserxt_ems_baseaddr_index + 2) & 0x0C) << 14), 0x4000); - mem_mapping_set_addr(&laserxt_ems_mapping[3], 0xCC000 + (((laserxt_ems_baseaddr_index + 1) & 0x0C) << 14), 0x4000); - flushmmucache(); - break; - - default: - break; + flushmmucache(); + } else if (!(port & 0x0001)) { + dev->ems[reg].page = val; + ems_update_virt(&dev->ems[reg], val); } } static uint8_t -laserxt_read(uint16_t port, UNUSED(void *priv)) +lxt_ems_in(uint16_t port, void *priv) { - switch (port) { - case 0x0208: - case 0x4208: - case 0x8208: - case 0xC208: - return laserxt_emspage[port >> 14]; - case 0x0209: - case 0x4209: - case 0x8209: - case 0xC209: - return laserxt_emscontrol[port >> 14]; + lxt_ems_board_t *dev = (lxt_ems_board_t *) priv; + uint8_t reg = port >> 14; + uint8_t ret = 0xff; - default: - break; - } - return 0xff; + if (port & 0x0001) + ret = dev->ems[reg].ctrl; + else + ret = dev->ems[reg].page; + + return ret; } static void -mem_write_laserxtems(uint32_t addr, uint8_t val, UNUSED(void *priv)) +lxt_ems_write(uint32_t addr, uint8_t val, void *priv) { - addr = get_laserxt_ems_addr(addr); - if (addr < (mem_size << 10)) - ram[addr] = val; + uint8_t *mem = (uint8_t *) priv; + + mem[addr & 0x3fff] = val; +} + +static void +lxt_ems_writew(uint32_t addr, uint16_t val, void *priv) +{ + uint8_t *mem = (uint8_t *) priv; + + *(uint16_t *) &(mem[addr & 0x3fff]) = val; } static uint8_t -mem_read_laserxtems(uint32_t addr, UNUSED(void *priv)) +lxt_ems_read(uint32_t addr, void *priv) { - uint8_t val = 0xFF; - addr = get_laserxt_ems_addr(addr); - if (addr < (mem_size << 10)) - val = ram[addr]; - return val; + uint8_t *mem = (uint8_t *) priv; + uint8_t ret = 0xff; + + ret = mem[addr & 0x3fff]; + + return ret; +} + +static uint16_t +lxt_ems_readw(uint32_t addr, void *priv) +{ + uint8_t *mem = (uint8_t *) priv; + uint16_t ret = 0xff; + + ret = *(uint16_t *) &(mem[addr & 0x3fff]); + + return ret; +} + +static lxt_ems_board_t * +lxt_ems_init(lxt_t *parent, int en, uint16_t io, uint32_t mem) +{ + lxt_ems_board_t *dev = (lxt_ems_board_t *) calloc(1, sizeof(lxt_ems_board_t)); + + if (en) { + dev->parent = parent; + + if (io != 0x0000) { + io_sethandler(io , 0x0002, lxt_ems_in, NULL, NULL, lxt_ems_out, NULL, NULL, dev); + io_sethandler(io | 0x4000, 0x0002, lxt_ems_in, NULL, NULL, lxt_ems_out, NULL, NULL, dev); + io_sethandler(io | 0x8000, 0x0002, lxt_ems_in, NULL, NULL, lxt_ems_out, NULL, NULL, dev); + io_sethandler(io | 0xc000, 0x0002, lxt_ems_in, NULL, NULL, lxt_ems_out, NULL, NULL, dev); + } + + dev->ram = (uint8_t *) calloc(mem, sizeof(uint8_t)); + dev->mem_size = mem; + + for (uint8_t i = 0; i < 4; i++) { + uint8_t *ptr = dev->ram + (i << 14); + + if (parent->is_lxt3) + mem_mapping_add(&dev->ems[i].mapping, 0xe0000 + (i << 14), 0x4000, + lxt_ems_read, lxt_ems_readw, NULL, + lxt_ems_write, lxt_ems_writew, NULL, + ptr, 0, ptr); + else + mem_mapping_add(&dev->ems[i].mapping, 0xe0000 + (i << 14), 0x4000, + lxt_ems_read, NULL, NULL, + lxt_ems_write, NULL, NULL, + ptr, 0, ptr); + + mem_mapping_disable(&dev->ems[i].mapping); + + dev->ems[i].page = 0x7f; + dev->ems[i].ctrl = (i == 3) ? 0x00 : 0x80; + + dev->ems[i].parent = dev; + + ems_update_virt(&(dev->ems[i]), dev->ems[i].page); + } + } + + return dev; } static void -laserxt_init(int is_lxt3) +lxt_close(void *priv) { - if (mem_size > 640) { - io_sethandler(0x0208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); - io_sethandler(0x4208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); - io_sethandler(0x8208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); - io_sethandler(0xc208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); - mem_mapping_set_addr(&ram_low_mapping, 0, !is_lxt3 ? 0x70000 + (((mem_size + 64) & 255) << 10) : 0x30000 + (((mem_size + 320) & 511) << 10)); + lxt_t *dev = (lxt_t *) priv; + int ems_boards = (1 - dev->is_lxt3) + 1; + + for (int i = 0; i < ems_boards; i++) + if (dev->ems_boards[i] != NULL) { + if (dev->ems_boards[i]->ram != NULL) + free(dev->ems_boards[i]->ram); + free(dev->ems_boards[i]); + } + + free(dev); +} + +static void * +lxt_init(const device_t *info) +{ + lxt_t * dev = (lxt_t *) calloc(1, sizeof(lxt_t)); + int ems_boards = (1 - info->local) + 1; + int ems_en[2] = { 0 }; + uint16_t ems_io[2] = { 0 }; + uint32_t ems_mem[2] = { 0 }; + char conf_str[512] = { 0 }; + + dev->is_lxt3 = info->local; + + for (int i = 0; i < ems_boards; i++) { + sprintf(conf_str, "ems_%i_enable", i + 1); + ems_en[i] = device_get_config_int(conf_str); + + sprintf(conf_str, "ems_%i_base", i + 1); + ems_io[i] = device_get_config_hex16(conf_str); + + sprintf(conf_str, "ems_%i_mem_size", i + 1); + ems_mem[i] = device_get_config_int(conf_str) << 10; + + dev->ems_boards[i] = lxt_ems_init(dev, ems_en[i], ems_io[i], ems_mem[i]); } - for (uint8_t i = 0; i < 4; i++) { - laserxt_emspage[i] = 0x7F; - laserxt_emscontrol[i] = (i == 3) ? 0x00 : 0x80; - mem_mapping_add(&laserxt_ems_mapping[i], 0xE0000 + (i << 14), 0x4000, mem_read_laserxtems, NULL, NULL, mem_write_laserxtems, NULL, NULL, ram + 0xA0000 + (i << 14), 0, NULL); - mem_mapping_disable(&laserxt_ems_mapping[i]); - } mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - laserxt_is_lxt3 = is_lxt3; + + return dev; } +static const device_config_t laserxt_config[] = { + { + .name = "ems_1_base", + .description = "EMS 1 Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "0x208", .value = 0x208 }, + { .description = "0x218", .value = 0x218 }, + { .description = "0x258", .value = 0x258 }, + { .description = "0x268", .value = 0x268 }, + { .description = "0x2A8", .value = 0x2a8 }, + { .description = "0x2B8", .value = 0x2b8 }, + { .description = "0x2E8", .value = 0x2e8 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "ems_2_base", + .description = "EMS 2 Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "0x208", .value = 0x208 }, + { .description = "0x218", .value = 0x218 }, + { .description = "0x258", .value = 0x258 }, + { .description = "0x268", .value = 0x268 }, + { .description = "0x2A8", .value = 0x2a8 }, + { .description = "0x2B8", .value = 0x2b8 }, + { .description = "0x2E8", .value = 0x2e8 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "ems_1_mem_size", + .description = "EMS 1 Memory Size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 512, + .step = 32 + }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "ems_2_mem_size", + .description = "EMS 2 Memory Size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 512, + .step = 32 + }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "ems_1_enable", + .description = "Enable EMS 1", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "ems_2_enable", + .description = "Enable EMS 2", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +const device_t laserxt_device = { + .name = "VTech Laser Turbo XT", + .internal_name = "laserxt", + .flags = 0, + .local = 0, + .init = lxt_init, + .close = lxt_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = laserxt_config +}; + +static const device_config_t lxt3_config[] = { + { + .name = "ems_1_base", + .description = "EMS Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "0x208", .value = 0x208 }, + { .description = "0x218", .value = 0x218 }, + { .description = "0x258", .value = 0x258 }, + { .description = "0x268", .value = 0x268 }, + { .description = "0x2A8", .value = 0x2a8 }, + { .description = "0x2B8", .value = 0x2b8 }, + { .description = "0x2E8", .value = 0x2e8 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "ems_1_mem_size", + .description = "EMS Memory Size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 1024, + .step = 32 + }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "ems_1_enable", + .description = "Enable EMS", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +const device_t lxt3_device = { + .name = "VTech Laser Turbo XT", + .internal_name = "laserxt", + .flags = 0, + .local = 1, + .init = lxt_init, + .close = lxt_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = lxt3_config +}; + static void machine_xt_laserxt_common_init(const machine_t *model,int is_lxt3) { @@ -151,11 +464,11 @@ machine_xt_laserxt_common_init(const machine_t *model,int is_lxt3) device_add(&fdc_xt_device); nmi_init(); - standalone_gameport_type = &gameport_device; + standalone_gameport_type = &gameport_200_device; - laserxt_init(is_lxt3); + device_add(is_lxt3 ? &lxt3_device : &laserxt_device); - device_add(&keyboard_xt_lxt3_device); + device_add(&kbc_xt_lxt3_device); } int diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 34ca441ec..ef10ab5dc 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -39,6 +39,7 @@ #include <86box/nmi.h> #include <86box/mem.h> #include <86box/device.h> +#include <86box/lpt.h> #include <86box/nvr.h> #include <86box/keyboard.h> #include <86box/mouse.h> @@ -1918,7 +1919,7 @@ m19_vid_out(uint16_t addr, uint8_t val, void *priv) /* activating plantronics mode */ if (addr == 0x3dd) { /* already in graphics mode */ - if ((val & 0x30) && (vid->ogc.cga.cgamode & 0x2)) + if ((val & 0x30) && (vid->ogc.cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) vid->mode = PLANTRONICS_MODE; else vid->mode = OLIVETTI_OGC_MODE; @@ -2325,7 +2326,7 @@ machine_xt_m24_init(const machine_t *model) /* Address 66-67 = mainboard dip-switch settings */ io_sethandler(0x0065, 3, m24_read, NULL, NULL, NULL, NULL, NULL, NULL); - standalone_gameport_type = &gameport_device; + standalone_gameport_type = &gameport_200_device; nmi_init(); @@ -2366,8 +2367,8 @@ machine_xt_m240_init(const machine_t *model) m24_kbd_t *m24_kbd; nvr_t *nvr; - ret = bios_load_interleaved("roms/machines/m240/olivetti_m240_pchj_2.11_low.bin", - "roms/machines/m240/olivetti_m240_pchk_2.11_high.bin", + ret = bios_load_interleaved("roms/machines/m240/olivetti_m240_pchm_2.12_low.bin", + "roms/machines/m240/olivetti_m240_pchl_2.12_high.bin", 0x000f8000, 32768, 0); if (bios_only || !ret) @@ -2397,7 +2398,7 @@ machine_xt_m240_init(const machine_t *model) device_add(&fdc_at_device); /* io.c logs clearly show it using port 3F7 */ if (joystick_type) - device_add(&gameport_device); + device_add(&gameport_200_device); nmi_init(); @@ -2451,7 +2452,7 @@ machine_xt_m19_init(const machine_t *model) m19_vid_init(vid); device_add_ex(&m19_vid_device, vid); - device_add(&keyboard_xt_olivetti_device); + device_add(&kbc_xt_olivetti_device); pit_set_clock((uint32_t) 14318184.0); diff --git a/src/machine/m_xt_philips.c b/src/machine/m_xt_philips.c index eed54e07f..273c856a5 100644 --- a/src/machine/m_xt_philips.c +++ b/src/machine/m_xt_philips.c @@ -158,9 +158,9 @@ machine_xt_philips_common_init(const machine_t *model) nmi_init(); - standalone_gameport_type = &gameport_device; + standalone_gameport_type = &gameport_200_device; - device_add(&keyboard_pc_device); + device_add(&kbc_pc_device); device_add(&philips_device); diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index 5a787292f..080a03d19 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -899,7 +899,7 @@ machine_xt_t1000_init(const machine_t *model) machine_common_init(model); pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); - device_add(&keyboard_xt_t1x00_device); + device_add(&kbc_xt_t1x00_device); t1000.fdc = device_add(&fdc_xt_device); nmi_init(); @@ -957,7 +957,7 @@ machine_xt_t1200_init(const machine_t *model) NULL, MEM_MAPPING_EXTERNAL, &t1000); pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); - device_add(&keyboard_xt_t1x00_device); + device_add(&kbc_xt_t1x00_device); t1000.fdc = device_add(&fdc_xt_t1x00_device); nmi_init(); diff --git a/src/machine/m_xt_xi8088.c b/src/machine/m_xt_xi8088.c index 886c1be6e..0e70893fb 100644 --- a/src/machine/m_xt_xi8088.c +++ b/src/machine/m_xt_xi8088.c @@ -110,11 +110,11 @@ static const device_config_t xi8088_config[] = { .type = CONFIG_SELECTION, .selection = { { - .description = "64 kB starting from F0000", + .description = "64 KB starting from F0000", .value = 0 }, { - .description = "128 kB starting from E0000 (address MSB inverted, last 64KB first)", + .description = "128 KB starting from E0000 (address MSB inverted, last 64 KB first)", .value = 1 } }, @@ -204,12 +204,12 @@ machine_xt_xi8088_init(const machine_t *model) if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&keyboard_ps2_xi8088_device); + device_add(&kbc_ps2_xi8088_device); device_add(&port_6x_xi8088_device); nmi_init(); device_add(&ibmat_nvr_device); pic2_init(); - standalone_gameport_type = &gameport_device; + standalone_gameport_type = &gameport_200_device; device_add(&sst_flash_39sf010_device); return ret; diff --git a/src/machine/m_xt_zenith.c b/src/machine/m_xt_zenith.c index 6c5d556f2..7ff7aa171 100644 --- a/src/machine/m_xt_zenith.c +++ b/src/machine/m_xt_zenith.c @@ -45,7 +45,7 @@ #include <86box/serial.h> #include <86box/machine.h> #include <86box/io.h> -#include <86box/vid_cga.h> +#include <86box/video.h> #include <86box/plat_unused.h> typedef struct { @@ -117,7 +117,7 @@ machine_zenith_init(const machine_t *model) pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); - device_add(&keyboard_xt_zenith_device); + device_add(&kbc_xt_zenith_device); nmi_init(); } @@ -129,7 +129,8 @@ machine_zenith_init(const machine_t *model) int machine_xt_z184_init(const machine_t *model) { - int ret; + lpt_t *lpt = NULL; + int ret; ret = bios_load_linear("roms/machines/zdsupers/z184m v3.1d.10d", 0x000f8000, 32768, 0); @@ -142,11 +143,14 @@ machine_xt_z184_init(const machine_t *model) if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_xt_device); - lpt1_remove(); /* only one parallel port */ - lpt2_remove(); - lpt1_setup(LPT2_ADDR); + lpt = device_add_inst(&lpt_port_device, 1); + lpt_port_remove(lpt); + lpt_port_setup(lpt, LPT2_ADDR); + lpt_set_next_inst(255); + device_add(&ns8250_device); - serial_set_next_inst(SERIAL_MAX); /* So that serial_standalone_init() won't do anything. */ + /* So that serial_standalone_init() won't do anything. */ + serial_set_next_inst(SERIAL_MAX - 1); device_add(&cga_device); @@ -182,7 +186,8 @@ machine_xt_z151_init(const machine_t *model) int machine_xt_z159_init(const machine_t *model) { - int ret; + lpt_t *lpt = NULL; + int ret; ret = bios_load_linear("roms/machines/zdsz159/z159m v2.9e.10d", 0x000f8000, 32768, 0); @@ -196,9 +201,10 @@ machine_xt_z159_init(const machine_t *model) device_add(&fdc_xt_tandy_device); /* parallel port is on the memory board */ - lpt1_remove(); /* only one parallel port */ - lpt2_remove(); - lpt1_setup(LPT2_ADDR); + lpt = device_add_inst(&lpt_port_device, 1); + lpt_port_remove(lpt); + lpt_port_setup(lpt, LPT2_ADDR); + lpt_set_next_inst(255); return ret; } diff --git a/src/machine/machine.c b/src/machine/machine.c index b171dd505..4bd87ffd9 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -39,6 +39,7 @@ #include <86box/video.h> #include <86box/machine.h> #include <86box/isamem.h> +#include <86box/isarom.h> #include <86box/pci.h> #include <86box/plat_unused.h> @@ -97,8 +98,6 @@ machine_init_ex(int m) mem_reset(); smbase = is_am486dxl ? 0x00060000 : 0x00030000; - lpt_init(); - if (cassette_enable) device_add(&cassette_device); @@ -111,12 +110,19 @@ machine_init_ex(int m) /* Reset any ISA memory cards. */ isamem_reset(); +#if 0 + /* Reset any ISA ROM cards. */ + isarom_reset(); +#endif + /* Reset the fast off stuff. */ cpu_fast_off_reset(); pci_flags = 0x00000000; } + is_pcjr = 0; + /* All good, boot the machine! */ if (machines[m].init) ret = machines[m].init(&machines[m]); @@ -139,18 +145,24 @@ machine_init(void) int machine_available(int m) { - int ret; + int ret = 0; const device_t *dev = machine_get_device(m); - bios_only = 1; + if (dev != NULL) + ret = machine_device_available(dev); + /* + Only via machine_init_ex() if the device is NULL or + it lacks a CONFIG_BIOS field (or the CONFIG_BIOS field + is not the first in list. + */ + if (ret == 0) { + bios_only = 1; - ret = device_available(dev); - /* Do not check via machine_init_ex() if the device is not NULL and - it has a CONFIG_BIOS field. */ - if ((dev == NULL) || (ret != -1)) ret = machine_init_ex(m); - bios_only = 0; + bios_only = 0; + } else if (ret == -2) + ret = 0; return !!ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 77132b6b5..88a8527fb 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1,1219 +1,2337 @@ -/* - * 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. - * - * Handling of the emulated machines. - * - * NOTES: OpenAT wip for 286-class machine with open BIOS. - * PS2_M80-486 wip, pending receipt of TRM's for machine. - * - * - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * Jasmine Iwanek, - * - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2025 Jasmine Iwanek. - */ -#include -#include -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> -#include <86box/rom.h> -#include <86box/device.h> -#include <86box/machine.h> -#include <86box/timer.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/keyboard.h> -#include <86box/sound.h> -#include <86box/video.h> -#include <86box/plat_unused.h> -#include <86box/thread.h> -#include <86box/network.h> - -// Temporarily here till we move everything out into the right files -extern const device_t pcjr_device; -extern const device_t m19_vid_device; -extern const device_t vid_device; -extern const device_t vid_device_hx; -extern const device_t t1000_video_device; -extern const device_t xi8088_device; -extern const device_t cga_device; -extern const device_t vid_1512_device; -extern const device_t vid_1640_device; -extern const device_t vid_pc2086_device; -extern const device_t vid_pc3086_device; -extern const device_t vid_200_device; -extern const device_t vid_ppc512_device; -extern const device_t vid_device_sl; -extern const device_t t1200_video_device; -extern const device_t compaq_plasma_device; -extern const device_t ps1_2011_device; -extern const device_t ibmpc_device; -extern const device_t ibmpc82_device; -extern const device_t ibmxt_device; -extern const device_t ibmxt86_device; -extern const device_t ibmat_device; -extern const device_t ibmxt286_device; -extern const device_t pb450_device; -extern const device_t jukopc_device; -extern const device_t vendex_device; - -const machine_filter_t machine_types[] = { - { "None", MACHINE_TYPE_NONE }, - { "[1979] 8088", MACHINE_TYPE_8088 }, - { "[1978] 8086", MACHINE_TYPE_8086 }, - { "[1982] 80286", MACHINE_TYPE_286 }, - { "[1988] i386SX", MACHINE_TYPE_386SX }, - { "[1992] 486SLC", MACHINE_TYPE_486SLC }, - { "[1985] i386DX", MACHINE_TYPE_386DX }, - { "[1989] i386DX/i486", MACHINE_TYPE_386DX_486 }, - { "[1992] i486 (Socket 168 and 1)", MACHINE_TYPE_486 }, - { "[1992] i486 (Socket 2)", MACHINE_TYPE_486_S2 }, - { "[1994] i486 (Socket 3)", MACHINE_TYPE_486_S3 }, - { "[1994] i486 (Socket 3 PCI)", MACHINE_TYPE_486_S3_PCI }, - { "[1992] i486 (Miscellaneous)", MACHINE_TYPE_486_MISC }, - { "[1993] Socket 4", MACHINE_TYPE_SOCKET4 }, - { "[1994] Socket 5", MACHINE_TYPE_SOCKET5 }, - { "[1995] Socket 7 (Single Voltage)", MACHINE_TYPE_SOCKET7_3V }, - { "[1996] Socket 7 (Dual Voltage)", MACHINE_TYPE_SOCKET7 }, - { "[1998] Super Socket 7", MACHINE_TYPE_SOCKETS7 }, - { "[1995] Socket 8", MACHINE_TYPE_SOCKET8 }, - { "[1997] Slot 1", MACHINE_TYPE_SLOT1 }, - { "[1998] Slot 1/2", MACHINE_TYPE_SLOT1_2 }, - { "[1998] Slot 1/Socket 370", MACHINE_TYPE_SLOT1_370 }, - { "[1998] Slot 2", MACHINE_TYPE_SLOT2 }, - { "[1998] Socket 370", MACHINE_TYPE_SOCKET370 }, - { "Miscellaneous", MACHINE_TYPE_MISC } -}; - -const machine_filter_t machine_chipsets[] = { - { "None", MACHINE_CHIPSET_NONE }, - { "Discrete", MACHINE_CHIPSET_DISCRETE }, - { "Proprietary", MACHINE_CHIPSET_PROPRIETARY }, - { "Headland GC100A", MACHINE_CHIPSET_GC100A }, - { "Headland GC103", MACHINE_CHIPSET_GC103 }, - { "Headland HT18", MACHINE_CHIPSET_HT18 }, - { "ACC 2168", MACHINE_CHIPSET_ACC_2168 }, - { "ALi M1217", MACHINE_CHIPSET_ALI_M1217 }, - { "ALi M6117", MACHINE_CHIPSET_ALI_M6117 }, - { "ALi M1409", MACHINE_CHIPSET_ALI_M1409 }, - { "ALi M1429", MACHINE_CHIPSET_ALI_M1429 }, - { "ALi M1429G", MACHINE_CHIPSET_ALI_M1429G }, - { "ALi M1489", MACHINE_CHIPSET_ALI_M1489 }, - { "ALi ALADDiN IV+", MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS }, - { "ALi ALADDiN V", MACHINE_CHIPSET_ALI_ALADDIN_V }, - { "ALi ALADDiN-PRO II", MACHINE_CHIPSET_ALI_ALADDIN_PRO_II }, - { "C&T 82C235 SCAT", MACHINE_CHIPSET_SCAT }, - { "C&T 82C236 SCATsx", MACHINE_CHIPSET_SCAT_SX }, - { "C&T CS8221 NEAT", MACHINE_CHIPSET_NEAT }, - { "C&T CS8281 NEATsx", MACHINE_CHIPSET_NEAT_SX }, - { "C&T 386", MACHINE_CHIPSET_CT_386 }, - { "C&T CS4031", MACHINE_CHIPSET_CT_CS4031 }, - { "Contaq 82C596", MACHINE_CHIPSET_CONTAQ_82C596 }, - { "Contaq 82C597", MACHINE_CHIPSET_CONTAQ_82C597 }, - { "IMS 8848", MACHINE_CHIPSET_IMS_8848 }, - { "Intel 82335", MACHINE_CHIPSET_INTEL_82335 }, - { "Intel 420TX", MACHINE_CHIPSET_INTEL_420TX }, - { "Intel 420ZX", MACHINE_CHIPSET_INTEL_420ZX }, - { "Intel 420EX", MACHINE_CHIPSET_INTEL_420EX }, - { "Intel 430LX", MACHINE_CHIPSET_INTEL_430LX }, - { "Intel 430NX", MACHINE_CHIPSET_INTEL_430NX }, - { "Intel 430FX", MACHINE_CHIPSET_INTEL_430FX }, - { "Intel 430HX", MACHINE_CHIPSET_INTEL_430HX }, - { "Intel 430VX", MACHINE_CHIPSET_INTEL_430VX }, - { "Intel 430TX", MACHINE_CHIPSET_INTEL_430TX }, - { "Intel 450KX", MACHINE_CHIPSET_INTEL_450KX }, - { "Intel 440FX", MACHINE_CHIPSET_INTEL_440FX }, - { "Intel 440LX", MACHINE_CHIPSET_INTEL_440LX }, - { "Intel 440EX", MACHINE_CHIPSET_INTEL_440EX }, - { "Intel 440BX", MACHINE_CHIPSET_INTEL_440BX }, - { "Intel 440ZX", MACHINE_CHIPSET_INTEL_440ZX }, - { "Intel 440GX", MACHINE_CHIPSET_INTEL_440GX }, - { "OPTi 283", MACHINE_CHIPSET_OPTI_283 }, - { "OPTi 291", MACHINE_CHIPSET_OPTI_291 }, - { "OPTi 381", MACHINE_CHIPSET_OPTI_381 }, - { "OPTi 391", MACHINE_CHIPSET_OPTI_391 }, - { "OPTi 481", MACHINE_CHIPSET_OPTI_481 }, - { "OPTi 493", MACHINE_CHIPSET_OPTI_493 }, - { "OPTi 495", MACHINE_CHIPSET_OPTI_495 }, - { "OPTi 499", MACHINE_CHIPSET_OPTI_499 }, - { "OPTi 895/802G", MACHINE_CHIPSET_OPTI_895_802G }, - { "OPTi 547/597", MACHINE_CHIPSET_OPTI_547_597 }, - { "SARC RC2016A", MACHINE_CHIPSET_SARC_RC2016A }, - { "SiS 310", MACHINE_CHIPSET_SIS_310 }, - { "SiS 401", MACHINE_CHIPSET_SIS_401 }, - { "SiS 460", MACHINE_CHIPSET_SIS_460 }, - { "SiS 461", MACHINE_CHIPSET_SIS_461 }, - { "SiS 471", MACHINE_CHIPSET_SIS_471 }, - { "SiS 496", MACHINE_CHIPSET_SIS_496 }, - { "SiS 501", MACHINE_CHIPSET_SIS_501 }, - { "SiS 5501", MACHINE_CHIPSET_SIS_5501 }, - { "SiS 5511", MACHINE_CHIPSET_SIS_5511 }, - { "SiS 5571", MACHINE_CHIPSET_SIS_5571 }, - { "SiS 5581", MACHINE_CHIPSET_SIS_5581 }, - { "SiS 5591", MACHINE_CHIPSET_SIS_5591 }, - { "SiS (5)600", MACHINE_CHIPSET_SIS_5600 }, - { "SMSC VictoryBX-66", MACHINE_CHIPSET_SMSC_VICTORYBX_66 }, - { "STPC Client", MACHINE_CHIPSET_STPC_CLIENT }, - { "STPC Consumer-II", MACHINE_CHIPSET_STPC_CONSUMER_II }, - { "STPC Elite", MACHINE_CHIPSET_STPC_ELITE }, - { "STPC Atlas", MACHINE_CHIPSET_STPC_ATLAS }, - { "Symphony SL82C460 Haydn II", MACHINE_CHIPSET_SYMPHONY_SL82C460 }, - { "UMC UM82C480", MACHINE_CHIPSET_UMC_UM82C480 }, - { "UMC UM82C491", MACHINE_CHIPSET_UMC_UM82C491 }, - { "UMC UM8881", MACHINE_CHIPSET_UMC_UM8881 }, - { "UMC UM8890BF", MACHINE_CHIPSET_UMC_UM8890BF }, - { "VIA VT82C495", MACHINE_CHIPSET_VIA_VT82C495 }, - { "VIA VT82C496G", MACHINE_CHIPSET_VIA_VT82C496G }, - { "VIA Apollo VPX", MACHINE_CHIPSET_VIA_APOLLO_VPX }, - { "VIA Apollo VP3", MACHINE_CHIPSET_VIA_APOLLO_VP3 }, - { "VIA Apollo MVP3", MACHINE_CHIPSET_VIA_APOLLO_MVP3 }, - { "VIA Apollo Pro", MACHINE_CHIPSET_VIA_APOLLO_PRO }, - { "VIA Apollo Pro 133", MACHINE_CHIPSET_VIA_APOLLO_PRO_133 }, - { "VIA Apollo Pro 133A", MACHINE_CHIPSET_VIA_APOLLO_PRO_133A }, - { "VLSI SCAMP", MACHINE_CHIPSET_VLSI_SCAMP }, - { "VLSI VL82C480", MACHINE_CHIPSET_VLSI_VL82C480 }, - { "VLSI VL82C481", MACHINE_CHIPSET_VLSI_VL82C481 }, - { "VLSI VL82C486", MACHINE_CHIPSET_VLSI_VL82C486 }, - { "WD76C10", MACHINE_CHIPSET_WD76C10 } -}; - -/* Machines to add before machine freeze: - - TMC Mycomp PCI54ST; - - Zeos Quadtel 486. - - NOTE: The AMI MegaKey tests were done on a real Intel Advanced/ATX - (thanks, MrKsoft for running my AMIKEY.COM on it), but the - technical specifications of the other Intel machines confirm - that the other boards also have the MegaKey. - - NOTE: The later (ie. not AMI Color) Intel AMI BIOS'es execute a - sequence of commands (B8, BA, BB) during one of the very first - phases of POST, in a way that is only valid on the AMIKey-3 - KBC firmware, that includes the Classic PCI/ED (Ninja) BIOS - which otherwise does not execute any AMI KBC commands, which - indicates that the sequence is a leftover of whatever AMI - BIOS (likely a laptop one since the AMIKey-3 is a laptop KBC - firmware!) Intel forked. - - NOTE: The VIA VT82C42N returns 0x46 ('F') in command 0xA1 (so it - emulates the AMI KF/AMIKey KBC firmware), and 0x42 ('B') in - command 0xAF. - The version on the VIA VT82C686B southbridge also returns - 'F' in command 0xA1, but 0x45 ('E') in command 0xAF. - The version on the VIA VT82C586B southbridge also returns - 'F' in command 0xA1, but 0x44 ('D') in command 0xAF. - The version on the VIA VT82C586A southbridge also returns - 'F' in command 0xA1, but 0x43 ('C') in command 0xAF. - - NOTE: The AMI MegaKey commands blanked in the technical reference - are CC and and C4, which are Set P14 High and Set P14 Low, - respectively. Also, AMI KBC command C1, mysteriously missing - from the technical references of AMI MegaKey and earlier, is - Write Input Port, same as on AMIKey-3. -*/ - -const machine_t machines[] = { - // clang-format off - /* 8088 Machines */ +/* + * 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. + * + * Handling of the emulated machines. + * + * Authors: Miran Grca, + * Fred N. van Kempen, + * Jasmine Iwanek, + * + * Copyright 2016-2025 Miran Grca. + * Copyright 2017-2025 Fred N. van Kempen. + * Copyright 2025 Jasmine Iwanek. + */ +#include +#include +#include +#include +#include <86box/86box.h> +#include "cpu.h" +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/machine.h> +#include <86box/timer.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/keyboard.h> +#include <86box/sound.h> +#include <86box/video.h> +#include <86box/plat_unused.h> +#include <86box/thread.h> +#include <86box/network.h> + +// Temporarily here till we move everything out into the right files +extern const device_t pcjr_device; +extern const device_t m19_vid_device; +extern const device_t tandy_1000_video_device; +extern const device_t tandy_1000hx_video_device; +extern const device_t tandy_1000sl_video_device; + +extern const device_t t1000_video_device; +extern const device_t xi8088_device; +extern const device_t cga_device; +extern const device_t vid_1512_device; +extern const device_t vid_1640_device; +extern const device_t vid_pc2086_device; +extern const device_t vid_pc3086_device; +extern const device_t vid_200_device; +extern const device_t vid_ppc512_device; +extern const device_t t1200_video_device; +extern const device_t compaq_plasma_device; +extern const device_t ps1_2011_device; +extern const device_t ibmpc_device; +extern const device_t ibmpc82_device; +extern const device_t ibmxt_device; +extern const device_t ibmxt86_device; +extern const device_t ibmat_device; +extern const device_t ibmxt286_device; +extern const device_t pb450_device; +extern const device_t jukopc_device; +extern const device_t vendex_device; +extern const device_t c5sbm2_device; +extern const device_t sb486pv_device; +extern const device_t ap5s_device; +extern const device_t d842_device; +extern const device_t d943_device; +extern const device_t dells333sl_device; +extern const device_t hot433a_device; +extern const device_t pbl300sx_device; +extern const device_t v12p_device; +extern const device_t f82c710_pc5086_device; + +const machine_filter_t machine_types[] = { + { "None", MACHINE_TYPE_NONE }, + { "[1979] 8088", MACHINE_TYPE_8088 }, + { "[1978] 8086", MACHINE_TYPE_8086 }, + { "[1982] 80286", MACHINE_TYPE_286 }, + { "[1988] i386SX", MACHINE_TYPE_386SX }, + { "[1992] 486SLC", MACHINE_TYPE_486SLC }, + { "[1985] i386DX", MACHINE_TYPE_386DX }, + { "[1989] i386DX/i486", MACHINE_TYPE_386DX_486 }, + { "[1992] i486 (Socket 168 and 1)", MACHINE_TYPE_486 }, + { "[1992] i486 (Socket 2)", MACHINE_TYPE_486_S2 }, + { "[1994] i486 (Socket 3)", MACHINE_TYPE_486_S3 }, + { "[1994] i486 (Socket 3 PCI)", MACHINE_TYPE_486_S3_PCI }, + { "[1992] i486 (Miscellaneous)", MACHINE_TYPE_486_MISC }, + { "[1993] Socket 4", MACHINE_TYPE_SOCKET4 }, + { "[1994] Socket 5", MACHINE_TYPE_SOCKET5 }, + { "[1995] Socket 7 (Single Voltage)", MACHINE_TYPE_SOCKET7_3V }, + { "[1996] Socket 7 (Dual Voltage)", MACHINE_TYPE_SOCKET7 }, + { "[1998] Super Socket 7", MACHINE_TYPE_SOCKETS7 }, + { "[1995] Socket 8", MACHINE_TYPE_SOCKET8 }, + { "[1997] Slot 1", MACHINE_TYPE_SLOT1 }, + { "[1998] Slot 1/2", MACHINE_TYPE_SLOT1_2 }, + { "[1998] Slot 1/Socket 370", MACHINE_TYPE_SLOT1_370 }, + { "[1998] Slot 2", MACHINE_TYPE_SLOT2 }, + { "[1998] Socket 370", MACHINE_TYPE_SOCKET370 }, + { "Miscellaneous", MACHINE_TYPE_MISC } +}; + +const machine_filter_t machine_chipsets[] = { + { "None", MACHINE_CHIPSET_NONE }, + { "Discrete", MACHINE_CHIPSET_DISCRETE }, + { "Proprietary", MACHINE_CHIPSET_PROPRIETARY }, + { "Headland GC100A", MACHINE_CHIPSET_GC100A }, + { "Headland GC103", MACHINE_CHIPSET_GC103 }, + { "Headland HT18", MACHINE_CHIPSET_HT18 }, + { "ACC 2036", MACHINE_CHIPSET_ACC_2036 }, + { "ACC 2168", MACHINE_CHIPSET_ACC_2168 }, + { "ALi M1217", MACHINE_CHIPSET_ALI_M1217 }, + { "ALi M6117", MACHINE_CHIPSET_ALI_M6117 }, + { "ALi M1409", MACHINE_CHIPSET_ALI_M1409 }, + { "ALi M1429", MACHINE_CHIPSET_ALI_M1429 }, + { "ALi M1429G", MACHINE_CHIPSET_ALI_M1429G }, + { "ALi M1489", MACHINE_CHIPSET_ALI_M1489 }, + { "ALi ALADDiN IV+", MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS }, + { "ALi ALADDiN V", MACHINE_CHIPSET_ALI_ALADDIN_V }, + { "ALi ALADDiN-PRO II", MACHINE_CHIPSET_ALI_ALADDIN_PRO_II }, + { "C&T PC/AT", MACHINE_CHIPSET_CT_AT }, + { "C&T 386/AT", MACHINE_CHIPSET_CT_386 }, + { "C&T 82C235 SCAT", MACHINE_CHIPSET_SCAT }, + { "C&T 82C236 SCATsx", MACHINE_CHIPSET_SCAT_SX }, + { "C&T CS8221 NEAT", MACHINE_CHIPSET_NEAT }, + { "C&T CS8281 NEATsx", MACHINE_CHIPSET_NEAT_SX }, + { "C&T CS4031", MACHINE_CHIPSET_CT_CS4031 }, + { "Contaq 82C596", MACHINE_CHIPSET_CONTAQ_82C596 }, + { "Contaq 82C597", MACHINE_CHIPSET_CONTAQ_82C597 }, + { "IMS 8848", MACHINE_CHIPSET_IMS_8848 }, + { "Intel 82335", MACHINE_CHIPSET_INTEL_82335 }, + { "Intel 420TX", MACHINE_CHIPSET_INTEL_420TX }, + { "Intel 420ZX", MACHINE_CHIPSET_INTEL_420ZX }, + { "Intel 420EX", MACHINE_CHIPSET_INTEL_420EX }, + { "Intel 430LX", MACHINE_CHIPSET_INTEL_430LX }, + { "Intel 430NX", MACHINE_CHIPSET_INTEL_430NX }, + { "Intel 430FX", MACHINE_CHIPSET_INTEL_430FX }, + { "Intel 430HX", MACHINE_CHIPSET_INTEL_430HX }, + { "Intel 430VX", MACHINE_CHIPSET_INTEL_430VX }, + { "Intel 430TX", MACHINE_CHIPSET_INTEL_430TX }, + { "Intel 450KX", MACHINE_CHIPSET_INTEL_450KX }, + { "Intel 440FX", MACHINE_CHIPSET_INTEL_440FX }, + { "Intel 440LX", MACHINE_CHIPSET_INTEL_440LX }, + { "Intel 440EX", MACHINE_CHIPSET_INTEL_440EX }, + { "Intel 440BX", MACHINE_CHIPSET_INTEL_440BX }, + { "Intel 440ZX", MACHINE_CHIPSET_INTEL_440ZX }, + { "Intel 440GX", MACHINE_CHIPSET_INTEL_440GX }, + { "OPTi 283", MACHINE_CHIPSET_OPTI_283 }, + { "OPTi 291", MACHINE_CHIPSET_OPTI_291 }, + { "OPTi 381", MACHINE_CHIPSET_OPTI_381 }, + { "OPTi 391", MACHINE_CHIPSET_OPTI_391 }, + { "OPTi 481", MACHINE_CHIPSET_OPTI_481 }, + { "OPTi 493", MACHINE_CHIPSET_OPTI_493 }, + { "OPTi 495SLC", MACHINE_CHIPSET_OPTI_495SLC }, + { "OPTi 495SX", MACHINE_CHIPSET_OPTI_495SX }, + { "OPTi 498", MACHINE_CHIPSET_OPTI_498 }, + { "OPTi 499", MACHINE_CHIPSET_OPTI_499 }, + { "OPTi 895/802G", MACHINE_CHIPSET_OPTI_895_802G }, + { "OPTi 547/597", MACHINE_CHIPSET_OPTI_547_597 }, + { "SARC RC2016A", MACHINE_CHIPSET_SARC_RC2016A }, + { "SiS 310", MACHINE_CHIPSET_SIS_310 }, + { "SiS 401", MACHINE_CHIPSET_SIS_401 }, + { "SiS 460", MACHINE_CHIPSET_SIS_460 }, + { "SiS 461", MACHINE_CHIPSET_SIS_461 }, + { "SiS 471", MACHINE_CHIPSET_SIS_471 }, + { "SiS 496", MACHINE_CHIPSET_SIS_496 }, + { "SiS 501", MACHINE_CHIPSET_SIS_501 }, + { "SiS 5501", MACHINE_CHIPSET_SIS_5501 }, + { "SiS 5511", MACHINE_CHIPSET_SIS_5511 }, + { "SiS 5571", MACHINE_CHIPSET_SIS_5571 }, + { "SiS 5581", MACHINE_CHIPSET_SIS_5581 }, + { "SiS 5591", MACHINE_CHIPSET_SIS_5591 }, + { "SiS (5)600", MACHINE_CHIPSET_SIS_5600 }, + { "SMSC VictoryBX-66", MACHINE_CHIPSET_SMSC_VICTORYBX_66 }, + { "STPC Client", MACHINE_CHIPSET_STPC_CLIENT }, + { "STPC Consumer-II", MACHINE_CHIPSET_STPC_CONSUMER_II }, + { "STPC Elite", MACHINE_CHIPSET_STPC_ELITE }, + { "STPC Atlas", MACHINE_CHIPSET_STPC_ATLAS }, + { "Symphony SL82C460 Haydn II", MACHINE_CHIPSET_SYMPHONY_SL82C460 }, + { "UMC UM82C480", MACHINE_CHIPSET_UMC_UM82C480 }, + { "UMC UM82C491", MACHINE_CHIPSET_UMC_UM82C491 }, + { "UMC UM8881", MACHINE_CHIPSET_UMC_UM8881 }, + { "UMC UM8890BF", MACHINE_CHIPSET_UMC_UM8890BF }, + { "VIA VT82C495", MACHINE_CHIPSET_VIA_VT82C495 }, + { "VIA VT82C496G", MACHINE_CHIPSET_VIA_VT82C496G }, + { "VIA Apollo VPX", MACHINE_CHIPSET_VIA_APOLLO_VPX }, + { "VIA Apollo VP3", MACHINE_CHIPSET_VIA_APOLLO_VP3 }, + { "VIA Apollo MVP3", MACHINE_CHIPSET_VIA_APOLLO_MVP3 }, + { "VIA Apollo Pro", MACHINE_CHIPSET_VIA_APOLLO_PRO }, + { "VIA Apollo Pro 133", MACHINE_CHIPSET_VIA_APOLLO_PRO_133 }, + { "VIA Apollo Pro 133A", MACHINE_CHIPSET_VIA_APOLLO_PRO_133A }, + { "VLSI SCAMP", MACHINE_CHIPSET_VLSI_SCAMP }, + { "VLSI VL82C480", MACHINE_CHIPSET_VLSI_VL82C480 }, + { "VLSI VL82C481", MACHINE_CHIPSET_VLSI_VL82C481 }, + { "VLSI VL82C486", MACHINE_CHIPSET_VLSI_VL82C486 }, + { "WD76C10", MACHINE_CHIPSET_WD76C10 } +}; + +/* Machines to add before machine freeze: + - TMC Mycomp PCI54ST; + - Zeos Quadtel 486. + + NOTE: The AMI MegaKey tests were done on a real Intel Advanced/ATX + (thanks, MrKsoft for running my AMIKEY.COM on it), but the + technical specifications of the other Intel machines confirm + that the other boards also have the MegaKey. + + NOTE: The later (ie. not AMI Color) Intel AMI BIOS'es execute a + sequence of commands (B8, BA, BB) during one of the very first + phases of POST, in a way that is only valid on the AMIKey-3 + KBC firmware, that includes the Classic PCI/ED (Ninja) BIOS + which otherwise does not execute any AMI KBC commands, which + indicates that the sequence is a leftover of whatever AMI + BIOS (likely a laptop one since the AMIKey-3 is a laptop KBC + firmware!) Intel forked. + + NOTE: The VIA VT82C42N returns 0x46 ('F') in command 0xA1 (so it + emulates the AMI KF/AMIKey KBC firmware), and 0x42 ('B') in + command 0xAF. + The version on the VIA VT82C686B southbridge also returns + 'F' in command 0xA1, but 0x45 ('E') in command 0xAF. + The version on the VIA VT82C586B southbridge also returns + 'F' in command 0xA1, but 0x44 ('D') in command 0xAF. + The version on the VIA VT82C586A southbridge also returns + 'F' in command 0xA1, but 0x43 ('C') in command 0xAF. + + NOTE: The AMI MegaKey commands blanked in the technical reference + are CC and and C4, which are Set P14 High and Set P14 Low, + respectively. Also, AMI KBC command C1, mysteriously missing + from the technical references of AMI MegaKey and earlier, is + Write Input Port, same as on AMIKey-3. +*/ + +const machine_t machines[] = { + // clang-format off + /* 8088 Machines */ + { + .name = "[8088] IBM PC (1981)", + .internal_name = "ibmpc", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_pc_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_PC5150, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 16, + .max = 64, + .step = 16 + }, + .nvrmask = 0, + .kbc_device = &kbc_pc_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &ibmpc_device, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] IBM PC (1982)", + .internal_name = "ibmpc82", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_pc82_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_PC5150, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 64, + .max = 256, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_pc82_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &ibmpc82_device, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] IBM PCjr", + .internal_name = "ibmpcjr", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_pcjr_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 = 4772728, + .max_bus = 4772728, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCJR, + .flags = MACHINE_VIDEO_FIXED | MACHINE_KEYBOARD | MACHINE_CARTRIDGE, + .ram = { + .min = 64, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = NULL, /* TODO: No specific kbd_device yet */ + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &pcjr_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] IBM XT (1982)", + .internal_name = "ibmxt", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_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 = 256, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &ibmxt_device, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] IBM XT (1986)", + .internal_name = "ibmxt86", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt86_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 = 256, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_xt86_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &ibmxt86_device, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] American XT Computer", + .internal_name = "americxt", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_americxt_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 = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] AMI XT clone", + .internal_name = "amixt", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_amixt_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 = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Atari PC 3", + .internal_name = "ataripc3", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_ataripc3_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_FDC, /* Machine has internal video: NSI EVC315-S EGA */ + .ram = { + .min = 64, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Bondwell BW230", + .internal_name = "bw230", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_bw230_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 = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Columbia Data Products MPC-1600", + .internal_name = "mpc1600", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_mpc1600_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 = 128, + .max = 512, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_pc82_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Compaq Portable", + .internal_name = "portable", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_compaq_portable_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_KEYBOARD, + .ram = { + .min = 128, + .max = 640, + .step = 128 + }, + .nvrmask = 0, + .kbc_device = &kbc_xt_compaq_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] DTK PIM-TB10-Z", + .internal_name = "dtk", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_dtk_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 = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Eagle PC Spirit", + .internal_name = "pcspirit", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_pcspirit_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 = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_pc82_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Generic XT clone", + .internal_name = "genxt", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_genxt_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 = &kbc_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] GLaBIOS", + .internal_name = "glabios", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_glabios_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .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 = &kbc_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Hyosung Topstar 88T", + .internal_name = "top88", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_top88_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, /* Machine has internal video: Paradise PVC2 */ + .ram = { + .min = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Hyundai SUPER-16T", + .internal_name = "super16t", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_super16t_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 = 4772728, + .max_bus = 8000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Hyundai SUPER-16TE", + .internal_name = "super16te", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_super16te_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 = 10000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Juko ST", + .internal_name = "jukopc", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_jukopc_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 = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &jukopc_device, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Kaypro PC", + .internal_name = "kaypropc", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_kaypropc_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 = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Micoms XL-7 Turbo/Pravetz-16ES", + .internal_name = "mxl7t", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_micoms_xl7turbo_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .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 = &kbc_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Multitech PC-500", + .internal_name = "pc500", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_pc500_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .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 = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_pc_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Multitech PC-700", + .internal_name = "pc700", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_pc700_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .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 = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_pc_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] NCR PC4i", + .internal_name = "pc4i", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_pc4i_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 = 256, + .max = 640, + .step = 128 + }, + .nvrmask = 0, + .kbc_device = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Olivetti M19", + .internal_name = "m19", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_xt_m19_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 = 4772728, + .max_bus = 7159092, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_VIDEO_FIXED | MACHINE_KEYBOARD, + .ram = { + .min = 256, + .max = 640, + .step = 128 + }, + .nvrmask = 0, + .kbc_device = &kbc_xt_olivetti_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &m19_vid_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] OpenXT", + .internal_name = "openxt", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_openxt_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 = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Samsung SPC-3000V/Packard Bell PB500/PB8810", + .internal_name = "pb8810", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_pb8810_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 = 256, + .max = 640, + .step = 128 + }, + .nvrmask = 0, + .kbc_device = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Philips P3105/NMS9100", + .internal_name = "p3105", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_p3105_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_XTA, + .ram = { + .min = 256, + .max = 768, + .step = 256 + }, + .nvrmask = 0, + .kbc_device = &kbc_pc_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Phoenix XT clone", + .internal_name = "pxxt", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_pxxt_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 = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Pravetz 16 / IMKO-4", + .internal_name = "pravetz16", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_pravetz16_imko4_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 = &kbc_pravetz_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Pravetz 16S / CPU12 Plus", + .internal_name = "pravetz16s", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_pravetz16s_cpu12p_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 = 4772728, + .max_bus = 12000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 512, + .max = 1024, + .step = 128 + }, + .nvrmask = 0, + .kbc_device = &kbc_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Sanyo SX-16", + .internal_name = "sansx16", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_sansx16_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 = 256, + .max = 640, + .step = 128 + }, + .nvrmask = 0, + .kbc_device = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Schneider EuroPC", + .internal_name = "europc", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_europc_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088_EUROPC, + .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_XTA | MACHINE_KEYBOARD | MACHINE_MOUSE, /* Machine has internal video: Paradise PVC4 */ + .ram = { + .min = 512, + .max = 640, + .step = 128 + }, + .nvrmask = 15, + .kbc_device = &kbc_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Super PC/Turbo XT", + .internal_name = "pcxt", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_pcxt_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 = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Tandy 1000 SX", + .internal_name = "tandy1000sx", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_tandy1000sx_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_VIDEO_FIXED | MACHINE_KEYBOARD, + .ram = { + .min = 384, + .max = 640, + .step = 128 + }, + .nvrmask = 0, + .kbc_device = &kbc_tandy_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &tandy_1000_video_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Tandy 1000 HX", + .internal_name = "tandy1000hx", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_tandy1000hx_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_VIDEO_FIXED | MACHINE_KEYBOARD, + .ram = { + .min = 256, + .max = 640, + .step = 128 + }, + .nvrmask = 0, + .kbc_device = &kbc_tandy_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &tandy_1000hx_video_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Toshiba T1000", + .internal_name = "t1000", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_xt_t1000_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_VIDEO | MACHINE_KEYBOARD, + .ram = { + .min = 512, + .max = 1280, + .step = 768 + }, + .nvrmask = 63, + .kbc_device = &kbc_xt_t1x00_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &t1000_video_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Vendex HeadStart Turbo 888-XT", + .internal_name = "vendex", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_xt_vendex_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 = 256, + .max = 768, + .step = 256 + }, + .nvrmask = 0, + .kbc_device = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &vendex_device, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] VTech Laser Turbo XT", + .internal_name = "ltxt", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_laserxt_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088_VTECH, + .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 = 256, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &laserxt_device, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a standard PS/2 KBC (so, use IBM PS/2 Type 1). */ + { + .name = "[8088] Xi8088", + .internal_name = "xi8088", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_xi8088_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_PS2, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 64, + .max = 1024, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = &kbc_ps2_xi8088_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &xi8088_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Z-NIX PC-1600", + .internal_name = "znic", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_znic_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 = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Zenith Data Systems Z-151/152/161", + .internal_name = "zdsz151", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_z151_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 = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_xt_zenith_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Zenith Data Systems Z-159", + .internal_name = "zdsz159", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_z159_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 = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_xt_zenith_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8088] Zenith Data Systems SupersPort (Z-184)", + .internal_name = "zdsupers", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_z184_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_VIDEO_FIXED, + .ram = { + .min = 128, + .max = 640, + .step = 128 + }, + .nvrmask = 0, + .kbc_device = &kbc_xt_zenith_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &cga_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[GC100A] Philips P3120", + .internal_name = "p3120", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_GC100A, + .init = machine_xt_p3120_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_XTA, + .ram = { + .min = 256, + .max = 768, + .step = 256 + }, + .nvrmask = 0, + .kbc_device = &kbc_pc_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[V20] PC-XT", + .internal_name = "v20xt", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_v20xt_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK(CPU_8088), + .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 = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[V20] Tulip PC Compact 2", + .internal_name = "tuliptc8", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_tuliptc8_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK(CPU_8088), + .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 = 63, + .kbc_device = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 8086 Machines */ + { + .name = "[8086] Amstrad PC1512", + .internal_name = "pc1512", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_pc1512_init, + .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 = 8000000, + .max_bus = 8000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_VIDEO_FIXED | MACHINE_KEYBOARD | MACHINE_MOUSE, + .ram = { + .min = 512, + .max = 640, + .step = 128 + }, + .nvrmask = 63, + .kbc_device = NULL /* TODO: No specific kbd_device yet */, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &vid_1512_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] Amstrad PC1640", + .internal_name = "pc1640", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_pc1640_init, + .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 = 10000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_VIDEO | MACHINE_KEYBOARD | MACHINE_MOUSE, + .ram = { + .min = 640, + .max = 640, + .step = 640 + }, + .nvrmask = 63, + .kbc_device = NULL /* TODO: No specific kbd_device yet */, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &vid_1640_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] Amstrad PC2086", + .internal_name = "pc2086", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_pc2086_init, + .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 = 10000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_VIDEO_FIXED | MACHINE_KEYBOARD | MACHINE_MOUSE, + .ram = { + .min = 640, + .max = 640, + .step = 640 + }, + .nvrmask = 63, + .kbc_device = NULL /* TODO: No specific kbd_device yet */, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &vid_pc2086_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] Amstrad PC3086", + .internal_name = "pc3086", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_pc3086_init, + .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 = 10000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_VIDEO_FIXED | MACHINE_KEYBOARD | MACHINE_MOUSE, + .ram = { + .min = 640, + .max = 640, + .step = 640 + }, + .nvrmask = 63, + .kbc_device = NULL /* TODO: No specific kbd_device yet */, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &vid_pc3086_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] Amstrad PC20(0)", + .internal_name = "pc200", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_pc200_init, + .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 = 10000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_VIDEO | MACHINE_KEYBOARD | MACHINE_MOUSE, + .ram = { + .min = 512, + .max = 640, + .step = 128 + }, + .nvrmask = 63, + .kbc_device = NULL /* TODO: No specific kbd_device yet */, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &vid_200_device, + .snd_device = NULL, + .net_device = NULL + }, { - .name = "[8088] IBM PC (1981)", - .internal_name = "ibmpc", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_pc_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_PC5150, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 16, - .max = 64, - .step = 16 - }, - .nvrmask = 0, - .kbc_device = &keyboard_pc_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &ibmpc_device, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] IBM PC (1982)", - .internal_name = "ibmpc82", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_pc82_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_PC5150, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 64, - .max = 256, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_pc82_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &ibmpc82_device, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] IBM PCjr", - .internal_name = "ibmpcjr", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_pcjr_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 = 4772728, - .max_bus = 4772728, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCJR, - .flags = MACHINE_VIDEO_FIXED | MACHINE_CARTRIDGE, - .ram = { - .min = 64, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = NULL, /* TODO: No specific kbd_device yet */ - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &pcjr_device, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] IBM XT (1982)", - .internal_name = "ibmxt", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_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 = 256, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &ibmxt_device, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] IBM XT (1986)", - .internal_name = "ibmxt86", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt86_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 = 256, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt86_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &ibmxt86_device, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] American XT Computer", - .internal_name = "americxt", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_americxt_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_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] AMI XT clone", - .internal_name = "amixt", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_amixt_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_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Atari PC 3", - .internal_name = "ataripc3", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_ataripc3_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_FDC, - .ram = { - .min = 64, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, //&fdc_xt_device, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Bondwell BW230", - .internal_name = "bw230", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_bw230_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_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Columbia Data Products MPC-1600", - .internal_name = "mpc1600", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_mpc1600_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 = 128, - .max = 512, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_pc82_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Compaq Portable", - .internal_name = "portable", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_compaq_portable_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 = 128, - .max = 640, - .step = 128 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt_compaq_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] DTK PIM-TB10-Z", - .internal_name = "dtk", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_dtk_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_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Eagle PC Spirit", - .internal_name = "pcspirit", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_pcspirit_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 = 128, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_pc82_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Generic XT clone", - .internal_name = "genxt", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_genxt_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, - .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, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Hyosung Topstar 88T", - .internal_name = "top88", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_top88_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 = 128, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Hyundai SUPER-16T", - .internal_name = "super16t", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_super16t_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 = 4772728, - .max_bus = 8000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 128, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Hyundai SUPER-16TE", - .internal_name = "super16te", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_super16te_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 = 10000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 128, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Juko ST", - .internal_name = "jukopc", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_jukopc_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_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &jukopc_device, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Kaypro PC", - .internal_name = "kaypropc", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_kaypropc_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 = 128, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Micoms XL-7 Turbo", - .internal_name = "mxl7t", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_micoms_xl7turbo_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_8088, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 64, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Multitech PC-500", - .internal_name = "pc500", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_pc500_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_8088, - .block = CPU_BLOCK_NONE, - .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 = 128, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_pc_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Multitech PC-700", - .internal_name = "pc700", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_pc700_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_8088, - .block = CPU_BLOCK_NONE, - .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 = 128, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_pc_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] NCR PC4i", - .internal_name = "pc4i", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_pc4i_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 = 256, - .max = 640, - .step = 128 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Olivetti M19", - .internal_name = "m19", - .type = MACHINE_TYPE_8088, + .name = "[8086] Amstrad PC5086", + .internal_name = "pc5086", + .type = MACHINE_TYPE_8086, .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_xt_m19_init, + .init = machine_pc5086_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 = 4772728, - .max_bus = 7159092, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO_FIXED, - .ram = { - .min = 256, - .max = 640, - .step = 128 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt_olivetti_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &m19_vid_device, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] OpenXT", - .internal_name = "openxt", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_openxt_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_8088, + .package = CPU_PKG_8086, .block = CPU_BLOCK_NONE, .min_bus = 0, .max_bus = 0, @@ -1222,15641 +2340,16143 @@ const machine_t machines[] = { .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_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Packard Bell PB8810", - .internal_name = "pb8810", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_pb8810_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 = 256, - .max = 640, - .step = 128 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Philips P3105/NMS9100", - .internal_name = "p3105", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_p3105_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, + .bus_flags = MACHINE_PC | MACHINE_BUS_PS2, .flags = MACHINE_XTA, - .ram = { - .min = 256, - .max = 768, - .step = 256 - }, - .nvrmask = 0, - .kbc_device = &keyboard_pc_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Phoenix XT clone", - .internal_name = "pxxt", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_pxxt_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_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Pravetz 16 / IMKO-4", - .internal_name = "pravetz16", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_pravetz16_imko4_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_pravetz_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Pravetz 16S / CPU12 Plus", - .internal_name = "pravetz16s", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_pravetz16s_cpu12p_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 = 4772728, - .max_bus = 12000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 512, - .max = 1024, - .step = 128 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Sanyo SX-16", - .internal_name = "sansx16", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_sansx16_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 = 256, - .max = 640, - .step = 128 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Schneider EuroPC", - .internal_name = "europc", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_europc_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_8088_EUROPC, - .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_XTA | MACHINE_MOUSE, - .ram = { - .min = 512, - .max = 640, - .step = 128 - }, - .nvrmask = 15, - .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Super PC/Turbo XT", - .internal_name = "pcxt", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_pcxt_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_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Tandy 1000 SX", - .internal_name = "tandy", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_tandy1000sx_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_VIDEO_FIXED, - .ram = { - .min = 384, - .max = 640, - .step = 128 - }, - .nvrmask = 0, - .kbc_device = &keyboard_tandy_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &vid_device, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Tandy 1000 HX", - .internal_name = "tandy1000hx", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_tandy1000hx_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_VIDEO_FIXED, - .ram = { - .min = 256, - .max = 640, - .step = 128 - }, - .nvrmask = 0, - .kbc_device = &keyboard_tandy_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &vid_device_hx, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Toshiba T1000", - .internal_name = "t1000", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_xt_t1000_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_VIDEO, - .ram = { - .min = 512, - .max = 1280, - .step = 768 - }, - .nvrmask = 63, - .kbc_device = &keyboard_xt_t1x00_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &t1000_video_device, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Vendex HeadStart Turbo 888-XT", - .internal_name = "vendex", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_xt_vendex_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 = 256, - .max = 768, - .step = 256 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &vendex_device, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, -#ifdef USE_LASERXT - { - .name = "[8088] VTech Laser Turbo XT", - .internal_name = "ltxt", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_laserxt_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_8088_VTECH, - .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 = 256, - .max = 640, - .step = 256 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, -#endif /* USE_LASERXT */ - /* Has a standard PS/2 KBC (so, use IBM PS/2 Type 1). */ - { - .name = "[8088] Xi8088", - .internal_name = "xi8088", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_xi8088_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_PS2, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 64, - .max = 1024, - .step = 128 - }, - .nvrmask = 127, - .kbc_device = &keyboard_ps2_xi8088_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &xi8088_device, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Z-NIX PC-1600", - .internal_name = "znic", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_znic_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_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Zenith Data Systems Z-151/152/161", - .internal_name = "zdsz151", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_z151_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 = 128, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt_zenith_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Zenith Data Systems Z-159", - .internal_name = "zdsz159", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_z159_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 = 128, - .max = 640, - .step = 64 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt_zenith_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8088] Zenith Data Systems SupersPort (Z-184)", - .internal_name = "zdsupers", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_z184_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_VIDEO_FIXED, - .ram = { - .min = 128, - .max = 640, - .step = 128 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt_zenith_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &cga_device, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[GC100A] Philips P3120", - .internal_name = "p3120", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_GC100A, - .init = machine_xt_p3120_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_XTA, - .ram = { - .min = 256, - .max = 768, - .step = 256 - }, - .nvrmask = 0, - .kbc_device = &keyboard_pc_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[V20] PC-XT", - .internal_name = "v20xt", - .type = MACHINE_TYPE_8088, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_v20xt_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_8088, - .block = CPU_BLOCK(CPU_8088), - .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_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 8086 Machines */ - { - .name = "[8086] Amstrad PC1512", - .internal_name = "pc1512", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_pc1512_init, - .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 = 8000000, - .max_bus = 8000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO_FIXED | MACHINE_MOUSE, .ram = { .min = 512, .max = 640, .step = 128 }, .nvrmask = 63, - .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &vid_1512_device, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8086] Amstrad PC1640", - .internal_name = "pc1640", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_pc1640_init, - .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 = 10000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO | MACHINE_MOUSE, - .ram = { - .min = 640, - .max = 640, - .step = 640 - }, - .nvrmask = 63, - .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &vid_1640_device, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8086] Amstrad PC2086", - .internal_name = "pc2086", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_pc2086_init, - .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 = 10000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO_FIXED | MACHINE_MOUSE, - .ram = { - .min = 640, - .max = 640, - .step = 640 - }, - .nvrmask = 63, - .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &vid_pc2086_device, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8086] Amstrad PC3086", - .internal_name = "pc3086", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_pc3086_init, - .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 = 10000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO_FIXED | MACHINE_MOUSE, - .ram = { - .min = 640, - .max = 640, - .step = 640 - }, - .nvrmask = 63, - .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &vid_pc3086_device, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8086] Amstrad PC20(0)", - .internal_name = "pc200", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_pc200_init, - .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 = 10000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO | MACHINE_MOUSE, - .ram = { - .min = 512, - .max = 640, - .step = 128 - }, - .nvrmask = 63, - .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &vid_200_device, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8086] Amstrad PPC512/640", - .internal_name = "ppc512", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ppc512_init, - .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 = 10000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO | MACHINE_MOUSE, - .ram = { - .min = 512, - .max = 640, - .step = 128 - }, - .nvrmask = 63, - .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &vid_ppc512_device, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8086] Compaq Deskpro", - .internal_name = "deskpro", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_xt_compaq_deskpro_init, - .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, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 128, - .max = 640, - .step = 128 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt_compaq_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8086] Epson Equity LT", - .internal_name = "elt", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_elt_init, - .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, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO, - .ram = { - .min = 640, - .max = 640, - .step = 640 - }, - .nvrmask = 0x3f, - .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8086] Mazovia 1016", - .internal_name = "maz1016", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_maz1016_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_8086_MAZOVIA, - .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 = 256, - .max = 640, - .step = 384 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8086] Olivetti M21/24/24SP", - .internal_name = "m24", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_xt_m24_init, - .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, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO | MACHINE_MOUSE | MACHINE_MFM, - .ram = { - .min = 128, - .max = 640, - .step = 128 - }, - .nvrmask = 15, - .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &ogc_m24_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has Olivetti KBC firmware. */ - { - .name = "[8086] Olivetti M240", - .internal_name = "m240", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_xt_m240_init, - .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, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_MFM, - .ram = { - .min = 128, - .max = 640, - .step = 128 - }, - .nvrmask = 15, - .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8086] Schetmash Iskra-3104", - .internal_name = "iskra3104", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_iskra3104_init, - .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, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 128, - .max = 640, - .step = 128 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xtclone_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8086] Tandy 1000 SL/2", - .internal_name = "tandy1000sl2", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_tandy1000sl2_init, - .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, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO_FIXED, - .ram = { - .min = 512, - .max = 768, - .step = 128 - }, - .nvrmask = 0, - .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &vid_device_sl, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8086] Toshiba T1200", - .internal_name = "t1200", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_xt_t1200_init, - .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, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO | MACHINE_MFM, - .ram = { - .min = 1024, - .max = 2048, - .step = 1024 - }, - .nvrmask = 63, - .kbc_device = &keyboard_xt_t1x00_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &t1200_video_device, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[8086] Victor V86P", - .internal_name = "v86p", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_v86p_init, - .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, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO | MACHINE_MFM, - .ram = { - .min = 512, - .max = 1024, - .step = 128 - }, - .nvrmask = 127, - .kbc_device = &keyboard_xt_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - -#ifdef USE_LASERXT - { - .name = "[8086] VTech Laser XT3", - .internal_name = "lxt3", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_lxt3_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_8086_VTECH, - .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 = 256, - .max = 640, - .step = 256 - }, - .nvrmask = 0, - .kbc_device = &keyboard_xt_lxt3_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, -#endif /* USE_LASERXT */ - - /* 286 AT machines */ - /* Has IBM AT KBC firmware. */ - { - .name = "[ISA] IBM AT", - .internal_name = "ibmat", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_ibm_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 = 6000000, - .max_bus = 8000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 256, - .max = 512, - .step = 256 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &ibmat_device, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[ISA] IBM PS/1 model 2011", - .internal_name = "ibmps1es", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps1_m2011_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 = 10000000, - .max_bus = 10000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_XTA | MACHINE_VIDEO_FIXED, - .ram = { - .min = 512, - .max = 15360, - .step = 512 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &ps1_2011_device, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[ISA] IBM PS/2 model 30-286", - .internal_name = "ibmps2_m30_286", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps2_m30_286_init, - .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, - .min_bus = 10000000, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_XTA | MACHINE_VIDEO_FIXED, - .ram = { - .min = 512, - .max = 16384, - .step = 512 - }, - .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 IBM AT KBC firmware. */ - { - .name = "[ISA] IBM XT Model 286", - .internal_name = "ibmxt286", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_ibmxt286_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 = 6000000, - .max_bus = 6000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 256, - .max = 640, - .step = 128 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &ibmxt286_device, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* AMI BIOS for a chipset-less machine, most likely has AMI 'F' KBC firmware. */ - { - .name = "[ISA] AMI IBM AT", - .internal_name = "ibmatami", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_ibmatami_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 = 256, - .max = 512, - .step = 256 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Uses Commodore (CBM) KBC firmware, to be implemented as identical to the - IBM AT KBC firmware unless evidence emerges of any proprietary commands. */ - { - .name = "[ISA] Commodore PC 30 III", - .internal_name = "cmdpc30", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_at_cmdpc_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 = 6000000, - .max_bus = 12500000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 640, - .max = 14912, - .step = 64 - }, - .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 - }, - /* Uses Compaq KBC firmware. */ - { - .name = "[ISA] Compaq Portable II", - .internal_name = "portableii", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_at_portableii_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 = 6000000, - .max_bus = 16000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 640, - .max = 16384, - .step = 128 - }, - .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 - }, - /* Uses Compaq KBC firmware. */ - { - .name = "[ISA] Compaq Portable III", - .internal_name = "portableiii", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_at_portableiii_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 = 6000000, - .max_bus = 16000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE | MACHINE_VIDEO, - .ram = { - .min = 640, - .max = 16384, - .step = 128 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &compaq_plasma_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM AT KBC firmware. */ - { - .name = "[ISA] MR BIOS 286 clone", - .internal_name = "mr286", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_mr286_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_IDE, - .ram = { - .min = 512, - .max = 16384, - .step = 128 - }, - .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 IBM AT KBC firmware. */ - { - .name = "[ISA] NCR PC8/810/710/3390/3392", - .internal_name = "pc8", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_pc8_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 = 16384, - .step = 128 - }, - .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 Chips & Technologies KBC firmware. */ - { - .name = "[ISA] Wells American A*Star", - .internal_name = "wellamerastar", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_wellamerastar_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 = 6000000, - .max_bus = 14000000, - .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 = 512 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, -#ifdef USE_OLIVETTI - /* Has Olivetti KBC firmware. */ - { - .name = "[ISA] Olivetti M290", - .internal_name = "m290", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_at_m290_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 = 640, - .max = 16384, - .step = 128 - }, - .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 - }, -#endif /* USE_OLIVETTI */ -#ifdef USE_OPEN_AT - /* Has IBM AT KBC firmware. */ - { - .name = "[ISA] OpenAT", - .internal_name = "openat", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_openat_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 = 256, - .max = 15872, - .step = 128 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, -#endif /* USE_OPEN_AT */ - /* Has IBM AT KBC firmware. */ - { - .name = "[ISA] Phoenix IBM AT", - .internal_name = "ibmatpx", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_ibmatpx_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 = 256, - .max = 512, - .step = 256 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has Quadtel KBC firmware. */ - { - .name = "[ISA] Quadtel IBM AT", - .internal_name = "ibmatquadtel", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_ibmatquadtel_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 = 256, - .max = 512, - .step = 256 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM AT KBC firmware. */ - /* To configure the BIOS, use PB_2330a_diag.IMA from MS-DOS 3.30 Packard Bell OEM, GSETUP might work too*/ - { - .name = "[ISA] Packard Bell PB286", - .internal_name = "pb286", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_pb286_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 = 256, - .max = 1024, - .step = 128 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has a Siemens proprietary KBC which is completely undocumented. */ - { - .name = "[ISA] Siemens PCD-2L", - .internal_name = "siemens", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_siemens_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 = 6000000, - .max_bus = 12500000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 256, - .max = 15872, - .step = 128 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has Toshiba's proprietary KBC, which is already implemented. */ - { - .name = "[ISA] Toshiba T3100e", - .internal_name = "t3100e", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_at_t3100e_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_IDE | MACHINE_VIDEO_FIXED, - .ram = { - .min = 1024, - .max = 5120, - .step = 256 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[ISA] GRiD GRiDcase 1520", - .internal_name = "grid1520", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_at_grid1520_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 = 6000000, - .max_bus = 10000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE /*| MACHINE_VIDEO_FIXED*/, - .ram = { - .min = 1024, - .max = 8192, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has Quadtel KBC firmware. */ - { - .name = "[GC103] Quadtel 286 clone", - .internal_name = "quadt286", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_GC103, - .init = machine_at_quadt286_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_SOFTFLOAT_ONLY, - .ram = { - .min = 512, - .max = 16384, - .step = 128 - }, - .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 - }, - /* Most likely has AMI 'F' KBC firmware. */ - { - .name = "[GC103] TriGem 286M", - .internal_name = "tg286m", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_GC103, - .init = machine_at_tg286m_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_IDE, - .ram = { - .min = 512, - .max = 8192, - .step = 128 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[NEAT] Atari PC 4", - .internal_name = "ataripc4", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_NEAT, - .init = machine_at_ataripc4_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_FDC, - .ram = { - .min = 512, - .max = 8192, - .step = 128 - }, - .nvrmask = 127, - .kbc_device = &keyboard_at_ami_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, //&fdc_at_device, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has "AMI KEYBOARD BIOS", most likely 'F'. */ - { - .name = "[NEAT] DataExpert 286", - .internal_name = "ami286", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_NEAT, - .init = machine_at_neat_ami_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 = 8192, - .step = 128 - }, - .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 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, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM AT KBC firmware. */ - { - .name = "[NEAT] NCR 3302", - .internal_name = "3302", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_NEAT, - .init = machine_at_3302_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_IDE | MACHINE_VIDEO, - .ram = { - .min = 512, - .max = 5120, - .step = 128 - }, - .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 IBM AT KBC firmware. */ - { - .name = "[NEAT] Arche AMA-2010", - .internal_name = "px286", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_NEAT, - .init = machine_at_px286_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 = 8192, - .step = 128 - }, - .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 Chips & Technologies KBC firmware. */ - { - .name = "[SCAT] GW-286CT GEAR", - .internal_name = "gw286ct", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_SCAT, - .init = machine_at_gw286ct_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_IDE, - .ram = { - .min = 512, - .max = 16384, - .step = 128 - }, - .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 IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[SCAT] Goldstar GDC-212M", - .internal_name = "gdc212m", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_SCAT, - .init = machine_at_gdc212m_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_PS2, - .flags = MACHINE_IDE, - .ram = { - .min = 512, - .max = 4096, - .step = 512 - }, - .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 a VIA VT82C42N KBC. */ - { - .name = "[SCAT] Hyundai Solomon 286KP", - .internal_name = "award286", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_SCAT, - .init = machine_at_award286_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_IDE, - .ram = { - .min = 512, - .max = 8192, - .step = 128 - }, - .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 a VIA VT82C42N KBC. */ - { - .name = "[SCAT] Hyundai Super-286TR", - .internal_name = "super286tr", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_SCAT, - .init = machine_at_super286tr_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 = 8192, - .step = 128 - }, - .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 IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[SCAT] Samsung SPC-4200P", - .internal_name = "spc4200p", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_SCAT, - .init = machine_at_spc4200p_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_PS2, - .flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */ - .ram = { - .min = 512, - .max = 2048, - .step = 128 - }, - .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 IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[SCAT] Samsung SPC-4216P", - .internal_name = "spc4216p", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_SCAT, - .init = machine_at_spc4216p_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_PS2, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 1024, - .max = 5120, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[SCAT] Samsung SPC-4620P", - .internal_name = "spc4620p", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_SCAT, - .init = machine_at_spc4620p_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_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO, - .ram = { - .min = 1024, - .max = 5120, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM AT KBC firmware. */ - { - .name = "[SCAT] Samsung Deskmaster 286", - .internal_name = "deskmaster286", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_SCAT, - .init = machine_at_deskmaster286_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_PS2, - .flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */ - .ram = { - .min = 512, - .max = 8192, - .step = 128 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - { - .name = "[SCAT] Senor Science Co. SCAT-286-003", - .internal_name = "senorscat286", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_SCAT, - .init = machine_at_senor_scat286_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_IDE, - .ram = { - .min = 1024, - .max = 4096, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* 286 machines that utilize the MCA bus */ - /* Has IBM PS/2 Type 2 KBC firmware. */ - { - .name = "[MCA] IBM PS/2 model 50", - .internal_name = "ibmps2_m50", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps2_model_50_init, - .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, - .min_bus = 10000000, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_MCA, - .flags = MACHINE_VIDEO, - .ram = { - .min = 1024, - .max = 10240, - .step = 1024 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 2 KBC firmware. */ - { - .name = "[MCA] IBM PS/2 model 60", - .internal_name = "ibmps2_m60", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps2_model_60_init, - .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, - .min_bus = 10000000, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_MCA, - .flags = MACHINE_VIDEO, - .ram = { - .min = 1024, - .max = 10240, - .step = 1024 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 386SX machines */ - /* ISA slots available because an official IBM expansion for that existed. */ - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[ISA] IBM PS/1 model 2121", - .internal_name = "ibmps1_2121", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps1_m2121_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO, - .ram = { - .min = 2048, - .max = 6144, - .step = 1024 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM AT KBC firmware. */ - { - .name = "[ISA] NCR PC916SX", - .internal_name = "pc916sx", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_pc916sx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 1024, - .max = 16384, - .step = 128 - }, - .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 Quadtel KBC firmware. */ - { - .name = "[ISA] QTC-SXM KT X20T02/HI", - .internal_name = "quadt386sx", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_quadt386sx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 1024, - .max = 16384, - .step = 128 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[ALi M1217] Acrosser AR-B1374", - .internal_name = "arb1374", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_ALI_M1217, - .init = machine_at_arb1374_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has the AMIKey-2 KBC. */ - { - .name = "[ALi M1217] AAEON SBC-350A", - .internal_name = "sbc350a", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_ALI_M1217, - .init = machine_at_sbc350a_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE, - .ram = { - .min = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a VIA VT82C42N KBC. */ - { - .name = "[ALi M1217] Flytech A36", - .internal_name = "flytech386", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_ALI_M1217, - .init = machine_at_flytech386_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE | MACHINE_VIDEO, - .ram = { - .min = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &tvga8900d_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a JetKey KBC without version, shows up as a 'H'. */ - { - .name = "[ALi M1217] Chaintech 325AX", - .internal_name = "325ax", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_ALI_M1217, - .init = machine_at_325ax_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .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 = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a JetKey KBC without version, shows up as a 'H'. */ - { - .name = "[ALi M1217] Chaintech 325AX (MR BIOS)", - .internal_name = "mr1217", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_ALI_M1217, - .init = machine_at_mr1217_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .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 = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[ALI M1409] Acer 100T", - .internal_name = "acer100t", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_ALI_M1409, - .init = machine_at_acer100t_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 16000000, - .max_bus = 25000000, /* Limited to 25 due a inaccurate cpu speed */ - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0, - - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO , /* Machine has internal OTI 077 Video card*/ - .ram = { - .min = 2048, - .max = 16256, - .step = 128 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &oti077_acer100t_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[ALi M6117] Acrosser PJ-A511M", - .internal_name = "pja511m", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_ALI_M6117, - .init = machine_at_pja511m_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_M6117, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[ALi M6117] Protech ProX-1332", - .internal_name = "prox1332", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_ALI_M6117, - .init = machine_at_prox1332_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_M6117, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has an AMI KBC firmware, the only photo of this is too low resolution - for me to read what's on the KBC chip, so I'm going to assume AMI 'F' - based on the other known HT18 AMI BIOS strings. */ - { - .name = "[HT18] Arche AMA-932J", - .internal_name = "ama932j", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_HT18, - .init = machine_at_ama932j_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE | MACHINE_VIDEO, - .ram = { - .min = 512, - .max = 8192, - .step = 128 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &oti067_ama932j_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has an unknown KBC firmware with commands B8 and BB in the style of - Phoenix MultiKey and AMIKey-3(!), but also commands E1 and EA with - unknown functions. */ - { - .name = "[Intel 82335] ADI 386SX", - .internal_name = "adi386sx", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_INTEL_82335, - .init = machine_at_adi386sx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 512, - .max = 8192, - .step = 128 - }, - .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 an AMI Keyboard BIOS PLUS KBC firmware ('8'). */ - { .name = "[Intel 82335] Shuttle 386SX", - .internal_name = "shuttle386sx", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_INTEL_82335, - .init = machine_at_shuttle386sx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 512, - .max = 8192, - .step = 128 - }, - .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 - }, - /* Uses Commodore (CBM) KBC firmware, to be implemented as identical to - the IBM PS/2 Type 1 KBC firmware unless evidence emerges of any - proprietary commands. */ - { - .name = "[NEAT] Commodore SL386SX-16", - .internal_name = "cmdsl386sx16", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_NEAT, - .init = machine_at_cmdsl386sx16_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 1024, - .max = 8192, - .step = 512 - }, - .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 IBM AT KBC firmware. */ - { - .name = "[NEAT] DTK PM-1630C", - .internal_name = "dtk386", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_NEAT, - .init = machine_at_neat_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 512, - .max = 8192, - .step = 128 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { .name = "[NEATsx] OKI if386AX30L", - .internal_name = "if386sx", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_NEAT_SX, - .init = machine_at_if386sx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_VIDEO_FIXED, - .ram = { - .min = 1024, - .max = 4096, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM AT KBC firmware. */ - { - .name = "[OPTi 291] DTK PPM-3333P", - .internal_name = "awardsx", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_OPTI_291, - .init = machine_at_awardsx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 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 - }, - /* Uses Commodore (CBM) KBC firmware, to be implemented as identical to - the IBM PS/2 Type 1 KBC firmware unless evidence emerges of any - proprietary commands. */ - { - .name = "[SCAMP] Commodore SL386SX-25", - .internal_name = "cmdsl386sx25", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_VLSI_SCAMP, - .init = machine_at_cmdsl386sx25_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO, - .ram = { - .min = 1024, - .max = 8192, - .step = 512 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &gd5402_onboard_device, - .snd_device = NULL, - .net_device = NULL - }, - /* The closest BIOS string I find to this one's, differs only in one part, - and ends in -8, so I'm going to assume that this, too, has an AMI '8' - (AMI Keyboard BIOS Plus) KBC firmware. */ - { - .name = "[SCAMP] DataExpert 386SX", - .internal_name = "dataexpert386sx", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_VLSI_SCAMP, - .init = machine_at_dataexpert386sx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 10000000, - .max_bus = 25000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 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 IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[SCAMP] Samsung SPC-6033P", - .internal_name = "spc6033p", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_VLSI_SCAMP, - .init = machine_at_spc6033p_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO, - .ram = { - .min = 2048, - .max = 12288, - .step = 2048 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &ati28800k_spc6033p_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has an unknown AMI KBC firmware, I'm going to assume 'F' until a - photo or real hardware BIOS string is found. */ - { - .name = "[SCATsx] Kaimei KMX-C-02", - .internal_name = "kmxc02", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_SCAT_SX, - .init = machine_at_kmxc02_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 512, - .max = 16384, - .step = 512 - }, - .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 Quadtel KBC firmware. */ - { - .name = "[WD76C10] Amstrad MegaPC", - .internal_name = "megapc", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_WD76C10, - .init = machine_at_wd76c10_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 16000000, - .max_bus = 25000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 386SX machines which utilize the MCA bus */ - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[MCA] IBM PS/2 model 55SX", - .internal_name = "ibmps2_m55sx", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps2_model_55sx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_MCA, - .flags = MACHINE_VIDEO, - .ram = { - .min = 1024, - .max = 8192, - .step = 1024 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[MCA] IBM PS/2 model 65SX", - .internal_name = "ibmps2_m65sx", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps2_model_65sx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_MCA, - .flags = MACHINE_VIDEO, - .ram = { - .min = 1024, - .max = 8192, - .step = 1024 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 486SLC machines */ - /* 486SLC machines with just the ISA slot */ - /* Has AMIKey H KBC firmware. */ - { - .name = "[OPTi 283] RYC Leopard LX", - .internal_name = "rycleopardlx", - .type = MACHINE_TYPE_486SLC, - .chipset = MACHINE_CHIPSET_OPTI_283, - .init = machine_at_rycleopardlx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_486SLC_IBM, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 386DX machines */ - /* Has a Jetkey V3, which identifies as a 'B'. */ - { - .name = "[ACC 2168] Juko AT046DX3", - .internal_name = "acc386", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_ACC_2168, - .init = machine_at_acc386_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has an AMI Keyboard BIOS PLUS KBC firmware ('8'). */ - { - .name = "[C&T 386] ECS 386/32", - .internal_name = "ecs386", - .type = MACHINE_TYPE_386DX, + .kbc_device = &kbc_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &f82c710_pc5086_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] Amstrad PPC512/640", + .internal_name = "ppc512", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ppc512_init, + .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 = 10000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_VIDEO | MACHINE_KEYBOARD | MACHINE_MOUSE, + .ram = { + .min = 512, + .max = 640, + .step = 128 + }, + .nvrmask = 63, + .kbc_device = NULL /* TODO: No specific kbd_device yet */, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &vid_ppc512_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] Compaq Deskpro", + .internal_name = "deskpro", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_xt_compaq_deskpro_init, + .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, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 128, + .max = 640, + .step = 128 + }, + .nvrmask = 0, + .kbc_device = &kbc_xt_compaq_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] Epson Equity LT", + .internal_name = "elt", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_elt_init, + .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, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_VIDEO, + .ram = { + .min = 640, + .max = 640, + .step = 640 + }, + .nvrmask = 0x3f, + .kbc_device = &kbc_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] Mazovia 1016", + .internal_name = "maz1016", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_maz1016_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8086_MAZOVIA, + .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 = 256, + .max = 640, + .step = 384 + }, + .nvrmask = 0, + .kbc_device = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] Olivetti M21/24/24SP/AT&T PC 6300", + .internal_name = "m24", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_xt_m24_init, + .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, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_VIDEO | MACHINE_KEYBOARD | MACHINE_MOUSE | MACHINE_MFM, + .ram = { + .min = 128, + .max = 640, + .step = 128 + }, + .nvrmask = 15, + .kbc_device = NULL /* TODO: No specific kbd_device yet */, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &ogc_m24_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Olivetti KBC firmware. */ + { + .name = "[8086] Olivetti M240/AT&T PC 6300 WGS", + .internal_name = "m240", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_xt_m240_init, + .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, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_KEYBOARD | MACHINE_MFM, + .ram = { + .min = 128, + .max = 640, + .step = 128 + }, + .nvrmask = 15, + .kbc_device = NULL /* TODO: No specific kbd_device yet */, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] Schetmash Iskra-3104", + .internal_name = "iskra3104", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_iskra3104_init, + .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, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 128, + .max = 640, + .step = 128 + }, + .nvrmask = 0, + .kbc_device = &kbc_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] Tandy 1000 SL/2", + .internal_name = "tandy1000sl2", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_tandy1000sl2_init, + .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, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_VIDEO_FIXED | MACHINE_KEYBOARD, + .ram = { + .min = 512, + .max = 768, + .step = 128 + }, + .nvrmask = 0, + .kbc_device = NULL /* TODO: No specific kbd_device yet */, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &tandy_1000sl_video_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] Toshiba T1200", + .internal_name = "t1200", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_xt_t1200_init, + .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, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_VIDEO | MACHINE_KEYBOARD | MACHINE_MFM, + .ram = { + .min = 1024, + .max = 2048, + .step = 1024 + }, + .nvrmask = 63, + .kbc_device = &kbc_xt_t1x00_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &t1200_video_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] Victor V86P", + .internal_name = "v86p", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_v86p_init, + .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, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_VIDEO | MACHINE_KEYBOARD | MACHINE_MFM, + .ram = { + .min = 512, + .max = 1024, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = &kbc_xt_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[8086] VTech Laser XT3", + .internal_name = "lxt3", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_lxt3_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8086_VTECH, + .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 = 512, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &kbc_xt_lxt3_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &lxt3_device, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 286 AT machines */ + /* Has IBM AT KBC firmware. */ + { + .name = "[ISA] IBM AT", + .internal_name = "ibmat", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_ibm_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 = 6000000, + .max_bus = 8000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 256, + .max = 512, + .step = 256 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &ibmat_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[ISA] IBM PS/1 model 2011", + .internal_name = "ibmps1es", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps1_m2011_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 = 10000000, + .max_bus = 10000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_XTA | MACHINE_VIDEO_FIXED, + .ram = { + .min = 512, + .max = 15360, + .step = 512 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &ps1_2011_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[ISA] IBM PS/2 model 30-286", + .internal_name = "ibmps2_m30_286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps2_m30_286_init, + .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, + .min_bus = 10000000, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_XTA | MACHINE_VIDEO_FIXED, + .ram = { + .min = 512, + .max = 16384, + .step = 512 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[ISA] IBM XT Model 286", + .internal_name = "ibmxt286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_ibmxt286_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 = 6000000, + .max_bus = 6000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 256, + .max = 640, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &ibmxt286_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* AMI BIOS for a chipset-less machine, most likely has AMI 'F' KBC firmware. */ + { + .name = "[ISA] AMI IBM AT", + .internal_name = "ibmatami", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_ibmatami_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 = 256, + .max = 512, + .step = 256 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Uses Commodore (CBM) KBC firmware, to be implemented as identical to the + IBM AT KBC firmware unless evidence emerges of any proprietary commands. */ + { + .name = "[ISA] Commodore PC 30 III", + .internal_name = "cmdpc30", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_PROPRIETARY, /* Machine has chipset: Faraday FE3400B */ + .init = machine_at_cmdpc_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 = 6000000, + .max_bus = 12500000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 640, + .max = 14912, + .step = 64 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Uses Compaq KBC firmware. */ + { + .name = "[ISA] Compaq Portable II", + .internal_name = "portableii", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_at_portableii_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 = 6000000, + .max_bus = 16000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_KEYBOARD, + .ram = { + .min = 640, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Uses Compaq KBC firmware. */ + { + .name = "[ISA] Compaq Portable III", + .internal_name = "portableiii", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_at_portableiii_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 = 6000000, + .max_bus = 16000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_KEYBOARD, + .ram = { + .min = 640, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &compaq_plasma_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[ISA] MR BIOS 286 clone", + .internal_name = "mr286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_mr286_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_IDE, + .ram = { + .min = 512, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[ISA] NCR PC8/810/710/3390/3392", + .internal_name = "pc8", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_pc8_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 = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Olivetti KBC firmware. */ + { + .name = "[ISA] Olivetti M290/AT&T 6286 WGS", + .internal_name = "m290", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_PROPRIETARY, /* Yes, it's M290 with 98/86 gate array, not M290-30 with VLSI TOPCAT chipset. */ + .init = machine_at_m290_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 = 1024, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[ISA] Phoenix IBM AT", + .internal_name = "ibmatpx", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_ibmatpx_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 = 256, + .max = 512, + .step = 256 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Quadtel KBC firmware. */ + { + .name = "[ISA] Quadtel IBM AT", + .internal_name = "ibmatquadtel", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_ibmatquadtel_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 = 256, + .max = 512, + .step = 256 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + /* To configure the BIOS, use PB_2330a_diag.IMA from MS-DOS 3.30 Packard Bell OEM, GSETUP might work too*/ + { + .name = "[ISA] Packard Bell PB286", + .internal_name = "pb286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_pb286_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 = 256, + .max = 1024, + .step = 128 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has a Siemens proprietary KBC which is completely undocumented. */ + { + .name = "[ISA] Siemens PCD-2L", + .internal_name = "siemens", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_siemens_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 = 6000000, + .max_bus = 12500000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 256, + .max = 15872, + .step = 128 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has Toshiba's proprietary KBC, which is already implemented. */ + { + .name = "[ISA] Toshiba T3100e", + .internal_name = "t3100e", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_at_t3100e_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_IDE | MACHINE_VIDEO_FIXED | MACHINE_KEYBOARD, + .ram = { + .min = 1024, + .max = 5120, + .step = 256 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[ISA] GRiD GRiDcase 1520", + .internal_name = "grid1520", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_PROPRIETARY, /* Machine has chipset: Faraday FE3400B */ + .init = machine_at_grid1520_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 = 6000000, + .max_bus = 10000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_IDE /*| MACHINE_VIDEO_FIXED*/ | MACHINE_KEYBOARD, + .ram = { + .min = 1024, + .max = 8192, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC + firmware. */ + { + .name = "[C&T PC/AT] Dell System 200", + .internal_name = "dells200", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_CT_AT, + .init = machine_at_dells200_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 = 6000000, + .max_bus = 12000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 640, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* has an Award-branded KBC controller */ + { + .name = "[C&T PC/AT] Hyundai Super-286C", + .internal_name = "super286c", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_CT_AT, + .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, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC + firmware. */ + { + .name = "[C&T PC/AT] PC's Limited (Dell) 28608L/AT122", + .internal_name = "at122", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_CT_AT, + .init = machine_at_at122_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 = 6000000, + .max_bus = 12000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 640, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC + firmware. */ + { + .name = "[C&T PC/AT] Tulip AT Compact", + .internal_name = "tuliptc7", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_CT_AT, + .init = machine_at_tuliptc7_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 = 6000000, + .max_bus = 12000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 640, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Chips & Technologies KBC firmware. */ + { + .name = "[C&T PC/AT] Wells American A*Star", + .internal_name = "wellamerastar", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_CT_AT, + .init = machine_at_wellamerastar_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 = 6000000, + .max_bus = 14000000, + .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 = 512 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Quadtel KBC firmware. */ + { + .name = "[GC103] Quadtel 286 clone", + .internal_name = "quadt286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_GC103, + .init = machine_at_quadt286_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_SOFTFLOAT_ONLY, + .ram = { + .min = 512, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Most likely has AMI 'F' KBC firmware. */ + { + .name = "[GC103] TriGem 286M", + .internal_name = "tg286m", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_GC103, + .init = machine_at_tg286m_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_IDE, + .ram = { + .min = 512, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[NEAT] Atari PC 4", + .internal_name = "ataripc4", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_NEAT, + .init = machine_at_ataripc4_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_FDC, /* Machine has video: Paradise PVGA1A */ + .ram = { + .min = 512, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = &kbc_at_ami_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has "AMI KEYBOARD BIOS", most likely 'F'. */ + { + .name = "[NEAT] DataExpert 286", + .internal_name = "ami286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_NEAT, + .init = machine_at_neat_ami_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 = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[NEAT] NCR 3302", + .internal_name = "3302", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_NEAT, + .init = machine_at_3302_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_IDE | MACHINE_VIDEO, + .ram = { + .min = 512, + .max = 5120, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = ¶dise_pvga1a_ncr3302_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[NEAT] Arche AMA-2010", + .internal_name = "px286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_NEAT, + .init = machine_at_px286_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 = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Chips & Technologies KBC firmware. */ + { + .name = "[SCAT] GW-286CT GEAR", + .internal_name = "gw286ct", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_SCAT, + .init = machine_at_gw286ct_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_IDE, + .ram = { + .min = 512, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[SCAT] Goldstar GDC-212M", + .internal_name = "gdc212m", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_SCAT, + .init = machine_at_gdc212m_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_PS2, + .flags = MACHINE_IDE, + .ram = { + .min = 512, + .max = 4096, + .step = 512 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a VIA VT82C42N KBC. */ + { + .name = "[SCAT] Hyundai Solomon 286KP", + .internal_name = "award286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_SCAT, + .init = machine_at_award286_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_IDE, + .ram = { + .min = 640, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a VIA VT82C42N KBC. */ + { + .name = "[SCAT] Hyundai Super-286TR", + .internal_name = "super286tr", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_SCAT, + .init = machine_at_super286tr_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 = 640, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[SCAT] ICL DRS M35/286", + .internal_name = "drsm35286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_SCAT, + .init = machine_at_drsm35286_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_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO, /* Machine has Super I/O: C&T F82C711 */ + .ram = { + .min = 512, + .max = 5120, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5401_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[SCAT] Samsung SPC-4200P", + .internal_name = "spc4200p", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_SCAT, + .init = machine_at_spc4200p_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_PS2, + .flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */ + .ram = { + .min = 512, + .max = 2048, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[SCAT] Samsung SPC-4216P", + .internal_name = "spc4216p", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_SCAT, + .init = machine_at_spc4216p_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_PS2, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 5120, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[SCAT] Samsung SPC-4620P", + .internal_name = "spc4620p", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_SCAT, + .init = machine_at_spc4620p_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_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 5120, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[SCAT] Samsung Deskmaster 286", + .internal_name = "deskmaster286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_SCAT, + .init = machine_at_deskmaster286_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_PS2, + .flags = MACHINE_IDE, /* Has internal video: C&T VGA 411 */ + .ram = { + .min = 512, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[SCAT] Senor Science Co. SCAT-286-003", + .internal_name = "senorscat286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_SCAT, + .init = machine_at_senor_scat286_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_IDE, + .ram = { + .min = 1024, + .max = 4096, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* 286 machines that utilize the MCA bus */ + /* Has IBM PS/2 Type 2 KBC firmware. */ + { + .name = "[MCA] IBM PS/2 model 50", + .internal_name = "ibmps2_m50", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps2_model_50_init, + .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, + .min_bus = 10000000, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_MCA, + .flags = MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 10240, + .step = 1024 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 2 KBC firmware. */ + { + .name = "[MCA] IBM PS/2 model 60", + .internal_name = "ibmps2_m60", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps2_model_60_init, + .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, + .min_bus = 10000000, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_MCA, + .flags = MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 10240, + .step = 1024 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 386SX machines */ + /* ISA slots available because an official IBM expansion for that existed. */ + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[ISA] IBM PS/1 model 2121", + .internal_name = "ibmps1_2121", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps1_m2121_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO, + .ram = { + .min = 2048, + .max = 6144, + .step = 1024 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[ISA] NCR PC916SX", + .internal_name = "pc916sx", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_DISCRETE, /* Machine has chipset: TI TACT82000 */ + .init = machine_at_pc916sx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Quadtel KBC firmware. */ + { + .name = "[ISA] QTC-SXM KT X20T02/HI", + .internal_name = "quadt386sx", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_DISCRETE, /* Machine has chipset: VLSI TOPCAT */ + .init = machine_at_quadt386sx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Most likely has Phonenix KBC firmware. */ + { + .name = "[ACC 2036] Packard Bell Legend 300SX", + .internal_name = "pbl300sx", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ACC_2036, + .init = machine_at_pbl300sx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &pbl300sx_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &oti037_pbl300sx_device, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[ALi M1217] Acrosser AR-B1374", + .internal_name = "arb1374", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ALI_M1217, + .init = machine_at_arb1374_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_IDE, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the AMIKey-2 KBC. */ + { + .name = "[ALi M1217] AAEON SBC-350A", + .internal_name = "sbc350a", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ALI_M1217, + .init = machine_at_sbc350a_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_IDE, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a VIA VT82C42N KBC. */ + { + .name = "[ALi M1217] Flytech A36", + .internal_name = "flytech386", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ALI_M1217, + .init = machine_at_flytech386_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_IDE | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &tvga8900d_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a JetKey KBC without version, shows up as a 'H'. */ + { + .name = "[ALi M1217] Chaintech 325AX", + .internal_name = "325ax", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ALI_M1217, + .init = machine_at_325ax_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .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 = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a JetKey KBC without version, shows up as a 'H'. */ + { + .name = "[ALi M1217] Chaintech 325AX (MR BIOS)", + .internal_name = "mr1217", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ALI_M1217, + .init = machine_at_mr1217_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .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 = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[ALi M1409] Acer 100T", + .internal_name = "acer100t", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ALI_M1409, + .init = machine_at_acer100t_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 16000000, + .max_bus = 25000000, /* Limited to 25 due a inaccurate cpu speed */ + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0, + + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO , /* Machine has internal OTI 077 Video card*/ + .ram = { + .min = 2048, + .max = 16256, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &oti077_acer100t_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[ALi M6117] Acrosser PJ-A511M", + .internal_name = "pja511m", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ALI_M6117, + .init = machine_at_pja511m_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_M6117, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[ALi M6117] Protech ProX-1332", + .internal_name = "prox1332", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ALI_M6117, + .init = machine_at_prox1332_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_M6117, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has an AMI KBC firmware, the only photo of this is too low resolution + for me to read what's on the KBC chip, so I'm going to assume AMI 'F' + based on the other known HT18 AMI BIOS strings. */ + { + .name = "[HT18] Arche AMA-932J", + .internal_name = "ama932j", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_HT18, + .init = machine_at_ama932j_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_IDE | MACHINE_VIDEO, + .ram = { + .min = 512, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &oti067_ama932j_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has an unknown KBC firmware with commands B8 and BB in the style of + Phoenix MultiKey and AMIKey-3(!), but also commands E1 and EA with + unknown functions. */ + { + .name = "[Intel 82335] ADI 386SX", + .internal_name = "adi386sx", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_INTEL_82335, + .init = machine_at_adi386sx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 512, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has an AMI Keyboard BIOS PLUS KBC firmware ('8'). */ + { .name = "[Intel 82335] Shuttle 386SX", + .internal_name = "shuttle386sx", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_INTEL_82335, + .init = machine_at_shuttle386sx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 512, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Uses Commodore (CBM) KBC firmware, to be implemented as identical to + the IBM PS/2 Type 1 KBC firmware unless evidence emerges of any + proprietary commands. */ + { + .name = "[NEAT] Commodore SL386SX-16", + .internal_name = "cmdsl386sx16", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_NEAT, + .init = machine_at_cmdsl386sx16_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 8192, + .step = 512 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[NEAT] DTK PM-1630C", + .internal_name = "dtk386", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_NEAT, + .init = machine_at_neat_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 512, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { .name = "[NEATsx] OKI if386AX30L", + .internal_name = "if386sx", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_NEAT_SX, + .init = machine_at_if386sx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_VIDEO_FIXED | MACHINE_KEYBOARD | MACHINE_KEYBOARD_JIS | MACHINE_AX, + .ram = { + .min = 1024, + .max = 4096, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[OPTi 291] DTK PPM-3333P", + .internal_name = "awardsx", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_OPTI_291, + .init = machine_at_awardsx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Uses Commodore (CBM) KBC firmware, to be implemented as identical to + the IBM PS/2 Type 1 KBC firmware unless evidence emerges of any + proprietary commands. */ + { + .name = "[SCAMP] Commodore SL386SX-25", + .internal_name = "cmdsl386sx25", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_VLSI_SCAMP, + .init = machine_at_cmdsl386sx25_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 8192, + .step = 512 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5402_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, + /* The closest BIOS string I find to this one's, differs only in one part, + and ends in -8, so I'm going to assume that this, too, has an AMI '8' + (AMI Keyboard BIOS Plus) KBC firmware. */ + { + .name = "[SCAMP] DataExpert 386SX", + .internal_name = "dataexpert386sx", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_VLSI_SCAMP, + .init = machine_at_dataexpert386sx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 10000000, + .max_bus = 25000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC + firmware. */ + { + .name = "[SCAMP] Dell System 333s/L", + .internal_name = "dells333sl", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_VLSI_SCAMP, + .init = machine_at_dells333sl_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 10000000, + .max_bus = 33333333, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 16384, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &dells333sl_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5420_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[SCAMP] Samsung SPC-6033P", + .internal_name = "spc6033p", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_VLSI_SCAMP, + .init = machine_at_spc6033p_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO, + .ram = { + .min = 2048, + .max = 12288, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &ati28800k_spc6033p_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has an unknown AMI KBC firmware, I'm going to assume 'F' until a + photo or real hardware BIOS string is found. */ + { + .name = "[SCATsx] Kaimei KMX-C-02", + .internal_name = "kmxc02", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_SCAT_SX, + .init = machine_at_kmxc02_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 512, + .max = 16384, + .step = 512 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Quadtel KBC firmware. */ + { + .name = "[WD76C10] Amstrad MegaPC", + .internal_name = "megapc", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_WD76C10, + .init = machine_at_wd76c10_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 16000000, + .max_bus = 25000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 386SX machines which utilize the MCA bus */ + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[MCA] IBM PS/2 model 55SX", + .internal_name = "ibmps2_m55sx", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps2_model_55sx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_MCA, + .flags = MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 8192, + .step = 1024 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[MCA] IBM PS/2 model 65SX", + .internal_name = "ibmps2_m65sx", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps2_model_65sx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_MCA, + .flags = MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 8192, + .step = 1024 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 486SLC machines */ + /* 486SLC machines with just the ISA slot */ + /* Has AMIKey H KBC firmware. */ + { + .name = "[OPTi 283] RYC Leopard LX", + .internal_name = "rycleopardlx", + .type = MACHINE_TYPE_486SLC, + .chipset = MACHINE_CHIPSET_OPTI_283, + .init = machine_at_rycleopardlx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_486SLC_IBM, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 386DX machines */ + /* Has a Jetkey V3, which identifies as a 'B'. */ + { + .name = "[ACC 2168] Juko AT046DX3", + .internal_name = "acc386", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_ACC_2168, + .init = machine_at_acc386_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has an AMI Keyboard BIOS PLUS KBC firmware ('8'). */ + { + .name = "[C&T 386/AT] ECS 386/32", + .internal_name = "ecs386", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_CT_386, + .init = machine_at_ecs386_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[C&T 386/AT] Samsung SPC-6000A", + .internal_name = "spc6000a", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_CT_386, + .init = machine_at_spc6000a_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[C&T 386/AT] Tandy 4000", + .internal_name = "tandy4000", + .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_CT_386, - .init = machine_at_ecs386_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL + .init = machine_at_tandy4000_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL }, - /* Has IBM AT KBC firmware. */ - { - .name = "[C&T 386] Samsung SPC-6000A", - .internal_name = "spc6000a", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_CT_386, - .init = machine_at_spc6000a_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Uses Compaq KBC firmware. */ - { - .name = "[ISA] Compaq Deskpro 386 (September 1986)", - .internal_name = "deskpro386", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_deskpro386_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX_DESKPRO386, - .block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD), - .min_bus = 16000000, - .max_bus = 25000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[ISA] Compaq Deskpro 386 (May 1988)", - .internal_name = "deskpro386_05_1988", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_deskpro386_05_1988_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX_DESKPRO386, - .block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD), - .min_bus = 16000000, - .max_bus = 25000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[ISA] Compaq Portable III (386)", - .internal_name = "portableiii386", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_portableiii386_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX, - .block = CPU_BLOCK_NONE, - .min_bus = 20000000, - .max_bus = 20000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE | MACHINE_VIDEO, - .ram = { - .min = 1024, - .max = 14336, - .step = 1024 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &compaq_plasma_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM AT KBC firmware. */ - { - .name = "[ISA] Micronics 09-00021", - .internal_name = "micronics386", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_micronics386_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_APM, - .ram = { - .min = 512, - .max = 8192, - .step = 128 - }, - .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 IBM AT KBC firmware. */ - { - .name = "[ISA] Tandy 4000", - .internal_name = "tandy4000", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_tandy4000_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Lance LT38C41 with AMI Megakey P KBC firmware */ - { - .name = "[ALi M1429] ECS Panda 386V", - .internal_name = "ecs386v", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_ALI_M1429, - .init = machine_at_ecs386v_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0, - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024, - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey 'F' KBC firmware. */ - { - .name = "[OPTi 391] DataExpert 386WB", - .internal_name = "dataexpert386wb", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_OPTI_391, - .init = machine_at_dataexpert386wb_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX, /* Actual machine only supports 386DXes */ - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* The board has a "ASII KB-100" which I was not able to find any information about, - but the BIOS sends commands C9 without a parameter and D5, both of which are - Phoenix MultiKey commands. */ - { - .name = "[OPTi 495] U-Board OPTi 495SLC", - .internal_name = "award495", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_OPTI_495, - .init = machine_at_opti495_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX, /* Actual machine only supports 386DXes */ - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey F KBC firmware. */ - { - .name = "[SiS 310] ASUS ISA-386C", - .internal_name = "asus386", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_SIS_310, - .init = machine_at_asus386_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 386DX machines which utilize the MCA bus */ - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[MCA] IBM PS/2 model 80 (type 2)", - .internal_name = "ibmps2_m80", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps2_model_80_init, - .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, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_MCA, - .flags = MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/55 5551-Sxx, Txx stage 2 firmware. */ - { - .name = "[MCA] IBM PS/55 model 5550-T", - .internal_name = "ibmps55_m50t", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps55_model_50t_init, - .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, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_MCA, - .flags = MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 2048, - .max = 16384, - .step = 2048 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/55 5551-V0x, V1x firmware. */ - { - .name = "[MCA] IBM PS/55 model 5550-V", - .internal_name = "ibmps55_m50v", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps55_model_50v_init, - .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, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_MCA, - .flags = MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 4096, - .max = 16384, - .step = 4096 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 386DX/486 machines */ - /* Has AMIKey F KBC firmware. */ - { - .name = "[OPTi 495] DataExpert SX495", - .internal_name = "ami495", - .type = MACHINE_TYPE_386DX_486, - .chipset = MACHINE_CHIPSET_OPTI_495, - .init = machine_at_opti495_ami_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX | CPU_PKG_SOCKET1, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey F KBC firmware (it's just the MR BIOS for the above machine). */ - { - .name = "[OPTi 495] DataExpert SX495 (MR BIOS)", - .internal_name = "mr495", - .type = MACHINE_TYPE_386DX_486, - .chipset = MACHINE_CHIPSET_OPTI_495, - .init = machine_at_opti495_mr_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX | CPU_PKG_SOCKET1, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Winbond W83C42 with unknown firmware. */ - { - .name = "[ALi M1429G] DataExpert EXP4349", - .internal_name = "exp4349", - .type = MACHINE_TYPE_386DX_486, - .chipset = MACHINE_CHIPSET_ALI_M1429G, - .init = machine_at_exp4349_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX | CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 49152, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[MCA] IBM PS/2 model 70 (type 3)", - .internal_name = "ibmps2_m70_type3", - .type = MACHINE_TYPE_386DX_486, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps2_model_70_type3_init, - .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, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_MCA, - .flags = MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 2048, - .max = 65536, - .step = 2048 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[MCA] IBM PS/2 model 80 (type 3)", - .internal_name = "ibmps2_m80_type3", - .type = MACHINE_TYPE_386DX_486, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps2_model_80_axx_init, - .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, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_MCA, - .flags = MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 2048, - .max = 65536, - .step = 2048 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 486 machines - Socket 1 */ - /* Has AMI KF KBC firmware. */ - { - .name = "[ZyMOS Poach] Genoa Unknown 486", - .internal_name = "genoa486", - .type = MACHINE_TYPE_486, - .chipset = MACHINE_CHIPSET_ZYMOS_POACH, - .init = machine_at_genoa486_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET1, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMI KF KBC firmware. */ - { - .name = "[OPTi 381] Gigabyte GA-486L", - .internal_name = "ga486l", - .type = MACHINE_TYPE_486, - .chipset = MACHINE_CHIPSET_OPTI_381, - .init = machine_at_ga486l_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET1, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 16384, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has JetKey 5 KBC Firmware - but the BIOS string ends in a hardcoded -F, and - the BIOS also explicitly expects command A1 to return a 'F', so it looks like - the JetKey 5 is a clone of AMIKey type F. */ - { - .name = "[CS4031] AMI 486 CS4031", - .internal_name = "cs4031", - .type = MACHINE_TYPE_486, - .chipset = MACHINE_CHIPSET_CT_CS4031, - .init = machine_at_cs4031_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET1, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Uses some variant of Phoenix MultiKey/42 as the Intel 8242 chip has a Phoenix - copyright. */ - { - .name = "[OPTi 495] Mylex MVI486", - .internal_name = "mvi486", - .type = MACHINE_TYPE_486, - .chipset = MACHINE_CHIPSET_OPTI_495, - .init = machine_at_mvi486_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET1, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMI KF KBC firmware. */ - { - .name = "[SiS 401] ASUS ISA-486", - .internal_name = "isa486", - .type = MACHINE_TYPE_486, - .chipset = MACHINE_CHIPSET_SIS_401, - .init = machine_at_isa486_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET1, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey H KBC firmware, per the screenshot in "How computers & MS-DOS work". */ - { - .name = "[SiS 401] Chaintech 433SC", - .internal_name = "sis401", - .type = MACHINE_TYPE_486, - .chipset = MACHINE_CHIPSET_SIS_401, - .init = machine_at_sis401_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET1, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey F KBC firmware, per a photo of a monitor with the BIOS screen on - eBay. */ - { - .name = "[SiS 460] ABIT AV4", - .internal_name = "av4", - .type = MACHINE_TYPE_486, - .chipset = MACHINE_CHIPSET_SIS_460, - .init = machine_at_av4_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET1, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* The chip is a Lance LT38C41, a clone of the Intel 8041, and the BIOS sends - commands BC, BD, and C9 which exist on both AMIKey and Phoenix MultiKey/42, - but it does not write a byte after C9, which is consistent with AMIKey, so - this must have some form of AMIKey. */ - { - .name = "[VIA VT82C495] FIC 486-VC-HD", - .internal_name = "486vchd", - .type = MACHINE_TYPE_486, - .chipset = MACHINE_CHIPSET_VIA_VT82C495, - .init = machine_at_486vchd_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET1, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 64512, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a VLSI VL82C113A SCAMP Combination I/O which holds the KBC. */ - { - .name = "[VLSI 82C480] HP Vectra 486VL", - .internal_name = "vect486vl", - .type = MACHINE_TYPE_486, - .chipset = MACHINE_CHIPSET_VLSI_VL82C480, - .init = machine_at_vect486vl_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET1, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 2048, - .max = 32768, - .step = 2048 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, /*Has SIO (sorta): VLSI VL82C113A SCAMP Combination I/O*/ - .vid_device = &gd5428_onboard_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a standard IBM PS/2 KBC firmware or a clone thereof. */ - { - .name = "[VLSI 82C481] Siemens Nixdorf D824", - .internal_name = "d824", - .type = MACHINE_TYPE_486, - .chipset = MACHINE_CHIPSET_VLSI_VL82C481, - .init = machine_at_d824_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET1, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 2048, - .max = 32768, - .step = 2048 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &gd5428_onboard_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[MCA] IBM PS/2 model 70 (type 4)", - .internal_name = "ibmps2_m70_type4", - .type = MACHINE_TYPE_486, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps2_model_70_type4_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET1, - .block = CPU_BLOCK(CPU_i486SX, CPU_i486SX_SLENH, CPU_Am486SX, CPU_Cx486S), - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_MCA, - .flags = MACHINE_VIDEO | MACHINE_SOFTFLOAT_ONLY, - .ram = { - .min = 2048, - .max = 65536, - .step = 2048 - }, - .nvrmask = 63, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* 486 machines - Socket 2 */ - /* 486 machines with just the ISA slot */ - /* Uses some variant of Phoenix MultiKey/42 as the BIOS sends keyboard controller - command C7 (OR input byte with received data byte). */ - { - .name = "[ACC 2168] Packard Bell PB410A", - .internal_name = "pb410a", - .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_ACC_2168, - .init = machine_at_pb410a_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM | MACHINE_GAMEPORT, - .ram = { - .min = 4096, - .max = 36864, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Uses an ACER/NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware (V4.01H). */ - { - .name = "[ALi M1429G] Acer A1G", - .internal_name = "acera1g", - .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_ALI_M1429G, - .init = machine_at_acera1g_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 4096, - .max = 36864, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &gd5428_onboard_device, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[ALi M1429G] Kaimei SA-486 VL-BUS M.B.", - .internal_name = "win486", - .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_ALI_M1429G, - .init = machine_at_winbios1429_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. - It also has those Ex commands also seen on the VIA VT82C42N (the BIOS - supposedly sends command EF. - The board was also seen in 2003 with a -H string - perhaps someone swapped - the KBC? */ - { - .name = "[ALi M1429] Olystar LIL1429", - .internal_name = "ali1429", - .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_ALI_M1429, - .init = machine_at_ali1429_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has a standalone AMI Megakey 1993, which is type 'P'. */ - { - .name = "[IMS 8848] Tekram G486IP", - .internal_name = "g486ip", - .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_IMS_8848, - .init = machine_at_g486ip_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_APM, - .ram = { - .min = 2048, + /* Uses Compaq KBC firmware. */ + { + .name = "[ISA] Compaq Deskpro 386 (September 1986)", + .internal_name = "deskpro386", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_deskpro386_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX_DESKPRO386, + .block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD), + .min_bus = 16000000, + .max_bus = 25000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[ISA] Compaq Deskpro 386 (May 1988)", + .internal_name = "deskpro386_05_1988", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_deskpro386_05_1988_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX_DESKPRO386, + .block = CPU_BLOCK(CPU_486DLC, CPU_RAPIDCAD), + .min_bus = 16000000, + .max_bus = 25000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[ISA] Compaq Portable III (386)", + .internal_name = "portableiii386", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_portableiii386_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 20000000, + .max_bus = 20000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_KEYBOARD, + .ram = { + .min = 1024, + .max = 14336, + .step = 1024 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &compaq_plasma_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[ISA] Micronics 09-00021 (Tandon BIOS)", + .internal_name = "micronics386", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_micronics386_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 512, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ + { + .name = "[ISA] Micronics 09-00021 (Phoenix BIOS)", + .internal_name = "micronics386px", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_micronics386px_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 512, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Lance LT38C41 with AMI Megakey P KBC firmware */ + { + .name = "[ALi M1429] ECS Panda 386V", + .internal_name = "ecs386v", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_ALI_M1429, + .init = machine_at_ecs386v_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0, + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024, + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey 'F' KBC firmware. */ + { + .name = "[OPTi 391] DataExpert 386WB", + .internal_name = "dataexpert386wb", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_OPTI_391, + .init = machine_at_dataexpert386wb_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, /* Actual machine only supports 386DXes */ + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* The board has a "ASII KB-100" which I was not able to find any information about, + but the BIOS sends commands C9 without a parameter and D5, both of which are + Phoenix MultiKey commands. */ + { + .name = "[OPTi 495SLC] U-Board OPTi 495SLC", + .internal_name = "award495", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_OPTI_495SLC, + .init = machine_at_opti495_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, /* Actual machine only supports 386DXes */ + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Award KBC firmware. */ + { + .name = "[SiS 310] ASUS 386/33-64K", + .internal_name = "asus3863364k", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_SIS_310, + .init = machine_at_asus3863364k_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey F KBC firmware. */ + { + .name = "[SiS 310] ASUS ISA-386C", + .internal_name = "asus386", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_SIS_310, + .init = machine_at_asus386_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 386DX machines which utilize the MCA bus */ + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[MCA] IBM PS/2 model 80 (type 2)", + .internal_name = "ibmps2_m80", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps2_model_80_init, + .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, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_MCA, + .flags = MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/55 5551-Sxx, Txx stage 2 firmware. */ + { + .name = "[MCA] IBM PS/55 model 5550-T", + .internal_name = "ibmps55_m50t", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps55_model_50t_init, + .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, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_MCA, + .flags = MACHINE_VIDEO | MACHINE_KEYBOARD_JIS | MACHINE_APM, + .ram = { + .min = 2048, + .max = 16384, + .step = 2048 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/55 5551-V0x, V1x firmware. */ + { + .name = "[MCA] IBM PS/55 model 5550-V", + .internal_name = "ibmps55_m50v", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps55_model_50v_init, + .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, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_MCA, + .flags = MACHINE_VIDEO | MACHINE_KEYBOARD_JIS | MACHINE_APM, + .ram = { + .min = 4096, + .max = 16384, + .step = 4096 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 386DX/486 machines */ + /* Has AMIKey F KBC firmware. The EFAR chipst is a rebrand of OPTi 495SX. */ + { + .name = "[OPTi 495SX] CAF Technology C747", + .internal_name = "c747", + .type = MACHINE_TYPE_386DX_486, + .chipset = MACHINE_CHIPSET_OPTI_495SX, + .init = machine_at_c747_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX | CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM | MACHINE_IDE, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey F KBC firmware. */ + { + .name = "[OPTi 495SX] DataExpert SX495", + .internal_name = "ami495", + .type = MACHINE_TYPE_386DX_486, + .chipset = MACHINE_CHIPSET_OPTI_495SX, + .init = machine_at_opti495_ami_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX | CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey F KBC firmware (it's just the MR BIOS for the above machine). */ + { + .name = "[OPTi 495SX] DataExpert SX495 (MR BIOS)", + .internal_name = "mr495", + .type = MACHINE_TYPE_386DX_486, + .chipset = MACHINE_CHIPSET_OPTI_495SX, + .init = machine_at_opti495_mr_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX | CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Winbond W83C42 with unknown firmware. */ + { + .name = "[ALi M1429G] DataExpert EXP4349", + .internal_name = "exp4349", + .type = MACHINE_TYPE_386DX_486, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_exp4349_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX | CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[MCA] IBM PS/2 model 70 (type 3)", + .internal_name = "ibmps2_m70_type3", + .type = MACHINE_TYPE_386DX_486, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps2_model_70_type3_init, + .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, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_MCA, + .flags = MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 2048, + .max = 65536, + .step = 2048 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[MCA] IBM PS/2 model 80 (type 3)", + .internal_name = "ibmps2_m80_type3", + .type = MACHINE_TYPE_386DX_486, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps2_model_80_axx_init, + .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, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_MCA, + .flags = MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 2048, + .max = 65536, + .step = 2048 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 486 machines - Socket 1 */ + /* Has Award KBC firmware. */ + { + .name = "[ZyMOS Poach] ASUS ISA-486C", + .internal_name = "isa486c", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_ZYMOS_POACH, + .init = machine_at_isa486c_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMI KF KBC firmware. */ + { + .name = "[ZyMOS Poach] Genoa Unknown 486", + .internal_name = "genoa486", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_ZYMOS_POACH, + .init = machine_at_genoa486_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMI KF KBC firmware. */ + { + .name = "[OPTi 381] Gigabyte GA-486L", + .internal_name = "ga486l", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_OPTI_381, + .init = machine_at_ga486l_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 16384, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has JetKey 5 KBC Firmware - but the BIOS string ends in a hardcoded -F, and + the BIOS also explicitly expects command A1 to return a 'F', so it looks like + the JetKey 5 is a clone of AMIKey type F. */ + { + .name = "[CS4031] AMI 486 CS4031", + .internal_name = "cs4031", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_CT_CS4031, + .init = machine_at_cs4031_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Uses some variant of Phoenix MultiKey/42 as the Intel 8242 chip has a Phoenix + copyright. */ + { + .name = "[OPTi 498] Mylex MVI486", + .internal_name = "mvi486", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_OPTI_498, + .init = machine_at_mvi486_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMI KF KBC firmware. */ + { + .name = "[SiS 401] ASUS ISA-486", + .internal_name = "isa486", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_SIS_401, + .init = machine_at_isa486_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey H KBC firmware, per the screenshot in "How computers & MS-DOS work". */ + { + .name = "[SiS 401] Chaintech 433SC", + .internal_name = "sis401", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_SIS_401, + .init = machine_at_sis401_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey F KBC firmware, per a photo of a monitor with the BIOS screen on + eBay. */ + { + .name = "[SiS 460] ABIT AV4", + .internal_name = "av4", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_SIS_460, + .init = machine_at_av4_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Phoenix KBC firmware. */ + { + .name = "[SiS 471] AST Advantage! 40xxd", + .internal_name = "advantage40xxd", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_advantage40xxd_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 2 + }, + .bus_flags = MACHINE_PS2_VLB, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 4096, + .max = 36864, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5424_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey F KBC firmware. */ + { + .name = "[Symphony SL42C460] DTK PKM-0031Y", + .internal_name = "dtk461", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_SYMPHONY_SL82C460, + .init = machine_at_dtk461_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* The chip is a Lance LT38C41, a clone of the Intel 8041, and the BIOS sends + commands BC, BD, and C9 which exist on both AMIKey and Phoenix MultiKey/42, + but it does not write a byte after C9, which is consistent with AMIKey, so + this must have some form of AMIKey. */ + { + .name = "[VIA VT82C495] FIC 486-VC-HD", + .internal_name = "486vchd", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_VIA_VT82C495, + .init = machine_at_486vchd_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 64512, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a VLSI VL82C113A SCAMP Combination I/O which holds the KBC. */ + { + .name = "[VLSI 82C480] HP Vectra 486VL", + .internal_name = "vect486vl", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_VLSI_VL82C480, + .init = machine_at_vect486vl_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 2048, + .max = 32768, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, /*Has SIO (sorta): VLSI VL82C113A SCAMP Combination I/O*/ + .vid_device = &gd5428_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a VLSI VL82C114 Combination I/O which holds the KBC. */ + { + .name = "[VLSI 82C481] Siemens Nixdorf D824", + .internal_name = "d824", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_VLSI_VL82C481, + .init = machine_at_d824_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 2048, + .max = 32768, + .step = 2048 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5428_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a VLSI VL82C113A SCAMP Combination I/O which holds the KBC. */ + { + .name = "[VLSI 82C486] Tulip 486 DC/DT", + .internal_name = "tuliptc38", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_VLSI_VL82C486, + .init = machine_at_tuliptc38_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 2048, + .max = 32768, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, /*Has SIO (sorta): VLSI VL82C113A SCAMP Combination I/O*/ + .vid_device = &gd5426_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[MCA] IBM PS/2 model 70 (type 4)", + .internal_name = "ibmps2_m70_type4", + .type = MACHINE_TYPE_486, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps2_model_70_type4_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET1, + .block = CPU_BLOCK(CPU_i486SX, CPU_i486SX_SLENH, CPU_Am486SX, CPU_Cx486S), + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_MCA, + .flags = MACHINE_VIDEO | MACHINE_SOFTFLOAT_ONLY, + .ram = { + .min = 2048, + .max = 65536, + .step = 2048 + }, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* 486 machines - Socket 2 */ + /* 486 machines with just the ISA slot */ + /* Uses some variant of Phoenix MultiKey/42 as the BIOS sends keyboard controller + command C7 (OR input byte with received data byte). */ + { + .name = "[ACC 2168] Packard Bell PB410A", + .internal_name = "pb410a", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_ACC_2168, + .init = machine_at_pb410a_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM | MACHINE_GAMEPORT, + .ram = { + .min = 4096, + .max = 36864, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &ht216_32_pb410a_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Uses an ACER/NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware (V4.01H). */ + { + .name = "[ALi M1429G] Acer A1G", + .internal_name = "acera1g", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_acera1g_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 4096, + .max = 36864, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5428_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[ALi M1429G] Kaimei SA-486 VL-BUS M.B.", + .internal_name = "win486", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_winbios1429_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. + It also has those Ex commands also seen on the VIA VT82C42N (the BIOS + supposedly sends command EF. + The board was also seen in 2003 with a -H string - perhaps someone swapped + the KBC? */ + { + .name = "[ALi M1429] Olystar LIL1429", + .internal_name = "ali1429", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_ALI_M1429, + .init = machine_at_ali1429_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMI MegaKey KBC. */ + { + .name = "[i420TX] J-Bond PCI400C-A", + .internal_name = "pci400ca", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_INTEL_420TX, + .init = machine_at_pci400ca_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_SCSI, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = &kbc_at_ami_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has a standalone AMI Megakey 1993, which is type 'P'. */ + { + .name = "[IMS 8848] Tekram G486IP", + .internal_name = "g486ip", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_IMS_8848, + .init = machine_at_g486ip_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[OPTi 499] Alaris Cobalt LPX", + .internal_name = "cobalt", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_OPTI_499, + .init = machine_at_cobalt_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3 | CPU_PKG_486BL, + .block = CPU_BLOCK(CPU_P24T), + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_VLB, + .flags = MACHINE_APM | MACHINE_VIDEO | MACHINE_IDE_DUAL, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5428_vlb_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey-2 'H' KBC firmware. */ + { + .name = "[OPTi 499] Alaris COUGAR 486BL", + .internal_name = "cougar", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_OPTI_499, + .init = machine_at_cougar_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3 | CPU_PKG_486BL, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, /* Machine has IDE with controller: Appian ADI/2 */ + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Uses an Intel KBC with Phoenix MultiKey KBC firmware. */ + { + .name = "[SiS 461] DEC DECpc LPV", + .internal_name = "decpclpv", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_SIS_461, + .init = machine_at_decpclpv_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_86c805_onboard_vlb_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Uses a ???? KBC. */ + { + .name = "[SiS 461] Dell 466/NP", + .internal_name = "dell466np", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_SIS_461, + .init = machine_at_dell466np_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5428_onboard_vlb_device, + .snd_device = NULL, + .net_device = NULL + }, + /* The BIOS does not send any non-standard keyboard controller commands and wants + a PS/2 mouse, so it's an IBM PS/2 KBC (Type 1) firmware. */ + { + .name = "[SiS 461] IBM PS/ValuePoint 433DX/Si", + .internal_name = "valuepoint433", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_SIS_461, + .init = machine_at_valuepoint433_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a VLSI VL82C113A SCAMP Combination I/O which holds the KBC. */ + { + .name = "[VLSI 82C480] ZEOS Martin", + .internal_name = "martin", + .type = MACHINE_TYPE_486_S2, + .chipset = MACHINE_CHIPSET_VLSI_VL82C480, + .init = machine_at_martin_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 2048, + .max = 65536, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 486 machines - Socket 3 */ + /* 486 machines with just the ISA slot */ + /* Has a Fujitsu MBL8042H KBC. */ + { + .name = "[Contaq 82C596A] A-Trend 4GPV5", + .internal_name = "4gpv5", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_CONTAQ_82C596, + .init = machine_at_4gpv5_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMI MegaKey KBC firmware. */ + { + .name = "[Contaq 82C597] Visionex Green-B", + .internal_name = "greenb", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_CONTAQ_82C597, + .init = machine_at_greenb_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Version 1.0 has an AMIKEY-2, version 2.0 has a VIA VT82C42N KBC. */ + { + .name = "[OPTi 895] Jetway J-403TG", + .internal_name = "403tg", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_OPTI_895_802G, + .init = machine_at_403tg_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. */ + { + .name = "[OPTi 895] Jetway J-403TG Rev D", + .internal_name = "403tg_d", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_OPTI_895_802G, + .init = machine_at_403tg_d_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. */ + { + .name = "[OPTi 895] Jetway J-403TG Rev D (MR BIOS)", + .internal_name = "403tg_d_mr", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_OPTI_895_802G, + .init = machine_at_403tg_d_mr_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Uses an NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware. */ + { + .name = "[SiS 461] Acer V10", + .internal_name = "acerv10", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_SIS_461, + .init = machine_at_acerv10_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_VLB, + .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal SCSI: Adaptec AIC-6360 */ + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* The BIOS string ends in -U, unless command 0xA1 (AMIKey get version) returns an + 'F', in which case, it ends in -F, so it has an AMIKey F KBC firmware. + The photo of the board shows an AMIKey KBC which is indeed F. */ + { + .name = "[SiS 471] ABIT AB-AH4", + .internal_name = "win471", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_win471_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey-2 'H' keyboard BIOS. */ + { + .name = "[SiS 471] AOpen Vi15G", + .internal_name = "vi15g", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_vi15g_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[SiS 471] ASUS VL/I-486SV2GX4", + .internal_name = "vli486sv2g", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_vli486sv2g_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. */ + { + .name = "[SiS 471] DTK PKM-0038S E-2", + .internal_name = "dtk486", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_dtk486_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Lance LT38C41L with AMIKey F keyboard BIOS. */ + { + .name = "[SiS 471] Epox GXA486SG", + .internal_name = "ami471", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_ami471_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has MR (!) KBC firmware, which is a clone of the standard IBM PS/2 KBC firmware. */ + { + .name = "[SiS 471] SiS VL-BUS 471 REV. A1", + .internal_name = "px471", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_px471_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* TriGem AMIBIOS Pre-Color with TriGem AMI 'Z' keyboard controller */ + { + .name = "[SiS 471] TriGem 486G (Olympia-K)", + .internal_name = "tg486g", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_tg486g_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_VLB, + .flags = MACHINE_IDE | MACHINE_APM, /* Has internal video: Western Digital WD90C33-ZZ */ + .ram = { + .min = 4096, + .max = 40960, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Unknown revision phoenix 1993 multikey */ + { + .name = "[SiS 471] DEC Venturis 4xx", + .internal_name = "dvent4xx", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_SIS_471, + .init = machine_at_dvent4xx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE_DUAL | MACHINE_SUPER_IO | MACHINE_APM | MACHINE_VIDEO, + .ram = { + .min = 4096, + .max = 69632, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_phoenix_trio32_onboard_vlb_device, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[ALi M1429G] ECS AL486", + .internal_name = "ecsal486", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_ecsal486_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 98304, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This uses a VIA VT82C42N KBC, which is a clone of type 'F' with additional commands */ + { + .name = "[ALi M1429G] Lanner Electronics AP-4100AA", + .internal_name = "ap4100aa", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_ap4100aa_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* JETKey V5.0 */ + { + .name = "[ALi M1429G] A-Trend ATC-1762", + .internal_name = "atc1762", + .type = MACHINE_TYPE_486_S3, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_atc1762_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 1024, .max = 131072, - .step = 2048 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey-2 'H' KBC firmware. */ - { - .name = "[OPTi 499] Alaris COUGAR 486BL", - .internal_name = "cougar", - .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_OPTI_499, - .init = machine_at_cougar_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3 | CPU_PKG_486BL, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Uses an Intel KBC with Phoenix MultiKey KBC firmware. */ - { - .name = "[SiS 461] DEC DECpc LPV", - .internal_name = "decpclpv", - .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_SIS_461, - .init = machine_at_decpclpv_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &s3_86c805_onboard_vlb_device, - .snd_device = NULL, - .net_device = NULL - }, - /* The BIOS does not send any non-standard keyboard controller commands and wants - a PS/2 mouse, so it's an IBM PS/2 KBC (Type 1) firmware. */ - { - .name = "[SiS 461] IBM PS/ValuePoint 433DX/Si", - .internal_name = "valuepoint433", - .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_SIS_461, - .init = machine_at_valuepoint433_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMI MegaKey KBC. */ - { - .name = "[i420TX] J-Bond PCI400C-A", - .internal_name = "pci400ca", - .type = MACHINE_TYPE_486_S2, - .chipset = MACHINE_CHIPSET_INTEL_420TX, - .init = machine_at_pci400ca_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_SCSI, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = &keyboard_at_ami_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - - /* 486 machines - Socket 3 */ - /* 486 machines with just the ISA slot */ - /* Has a Fujitsu MBL8042H KBC. */ - { - .name = "[Contaq 82C596A] A-Trend 4GPV5", - .internal_name = "4gpv5", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_CONTAQ_82C596, - .init = machine_at_4gpv5_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMI MegaKey KBC firmware. */ - { - .name = "[Contaq 82C597] Visionex Green-B", - .internal_name = "greenb", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_CONTAQ_82C597, - .init = machine_at_greenb_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Version 1.0 has an AMIKEY-2, version 2.0 has a VIA VT82C42N KBC. */ - { - .name = "[OPTi 895] Jetway J-403TG", - .internal_name = "403tg", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_OPTI_895_802G, - .init = machine_at_403tg_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. */ - { - .name = "[OPTi 895] Jetway J-403TG Rev D", - .internal_name = "403tg_d", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_OPTI_895_802G, - .init = machine_at_403tg_d_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. */ - { - .name = "[OPTi 895] Jetway J-403TG Rev D (MR BIOS)", - .internal_name = "403tg_d_mr", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_OPTI_895_802G, - .init = machine_at_403tg_d_mr_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Uses an NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware. */ - { - .name = "[SiS 461] Acer V10", - .internal_name = "acerv10", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_SIS_461, - .init = machine_at_acerv10_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_VLB, - .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal SCSI: Adaptec AIC-6360 */ - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* The BIOS string ends in -U, unless command 0xA1 (AMIKey get version) returns an - 'F', in which case, it ends in -F, so it has an AMIKey F KBC firmware. - The photo of the board shows an AMIKey KBC which is indeed F. */ - { - .name = "[SiS 471] ABIT AB-AH4", - .internal_name = "win471", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_win471_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey-2 'H' keyboard BIOS. */ - { - .name = "[SiS 471] AOpen Vi15G", - .internal_name = "vi15g", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_vi15g_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[SiS 471] ASUS VL/I-486SV2GX4", - .internal_name = "vli486sv2g", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_vli486sv2g_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has JetKey 5 KBC Firmware which looks like it is a clone of AMIKey type F. */ - { - .name = "[SiS 471] DTK PKM-0038S E-2", - .internal_name = "dtk486", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_dtk486_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Lance LT38C41L with AMIKey F keyboard BIOS. */ - { - .name = "[SiS 471] Epox GXA486SG", - .internal_name = "ami471", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_ami471_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has MR (!) KBC firmware, which is a clone of the standard IBM PS/2 KBC firmware. */ - { - .name = "[SiS 471] SiS VL-BUS 471 REV. A1", - .internal_name = "px471", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_px471_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_IDE | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* TriGem AMIBIOS Pre-Color with TriGem AMI 'Z' keyboard controller */ - { - .name = "[SiS 471] TriGem 486G", - .internal_name = "tg486g", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_tg486g_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_VLB, - .flags = MACHINE_IDE | MACHINE_APM, /* Has internal video: Western Digital WD90C33-ZZ */ - .ram = { - .min = 4096, - .max = 40960, - .step = 4096 - }, - .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 - }, - /* Unknown revision phoenix 1993 multikey */ - { - .name = "[SiS 471] DEC Venturis 4xx", - .internal_name = "dvent4xx", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_SIS_471, - .init = machine_at_dvent4xx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE_DUAL | MACHINE_SUPER_IO | MACHINE_APM | MACHINE_VIDEO, - .ram = { - .min = 4096, - .max = 69632, - .step = 4096 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &s3_phoenix_trio32_onboard_vlb_device, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[ALi M1429G] ECS AL486", - .internal_name = "ecsal486", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_ALI_M1429G, - .init = machine_at_ecsal486_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 98304, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This uses a VIA VT82C42N KBC, which is a clone of type 'F' with additional commands */ - { - .name = "[ALi M1429G] Lanner Electronics AP-4100AA", - .internal_name = "ap4100aa", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_ALI_M1429G, - .init = machine_at_ap4100aa_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* JETKey V5.0 */ - { - .name = "[ALi M1429G] A-Trend ATC-1762", - .internal_name = "atc1762", - .type = MACHINE_TYPE_486_S3, - .chipset = MACHINE_CHIPSET_ALI_M1429G, - .init = machine_at_atc1762_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 40960, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 486 machines which utilize the PCI bus */ - /* Machine with ALi M1429G chipset and M1435 southbridge */ - /* Has an AMIKEY-2 KBC. */ - { - .name = "[ALi M1429G] MSI MS-4134", - .internal_name = "ms4134", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_ALI_M1429G, - .init = machine_at_ms4134_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCIV, - .flags = MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* TriGem machine with M1429G and PhoenixBIOS */ - { - .name = "[ALi M1429G] TriGem 486GP", - .internal_name = "tg486gp", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_ALI_M1429G, - .init = machine_at_tg486gp_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[ALi M1489] AAEON SBC-490", - .internal_name = "sbc490", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_sbc490_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &tgui9440_onboard_pci_device, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT - KBC. */ - { - .name = "[ALi M1489] ABIT AB-PB4", - .internal_name = "abpb4", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_abpb4_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, /* Machine has a PISA slot */ - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT - KBC. - The BIOS string always ends in -U, but the BIOS will send AMIKey commands 0xCA - and 0xCB if command 0xA1 returns a letter in the 0x5x or 0x7x ranges, so I'm - going to give it an AMI 'U' KBC. */ - { - .name = "[ALi M1489] AMI WinBIOS 486 PCI", - .internal_name = "win486pci", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_win486pci_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT - KBC. - The known BIOS string ends in -E, and the BIOS returns whatever command 0xA1 - returns (but only if command 0xA1 is instant response), so said ALi keyboard - controller likely returns 'E'. */ - { - .name = "[ALi M1489] MSI MS-4145", - .internal_name = "ms4145", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_ms4145_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has an ALi M5042 keyboard controller with Phoenix MultiKey/42 v1.40 firmware. */ - { - .name = "[ALi M1489] ESA TF-486", - .internal_name = "tf486", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_tf486_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has an ALi M5042 with phoenix firmware like the ESA TF-486. */ - { - .name = "[ALi M1489] Acrosser AR-B1476", - .internal_name = "arb1476", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_ALI_M1489, - .init = machine_at_arb1476_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, /* Has onboard video: C&T F65545 */ - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[OPTi 802G] IBM Aptiva 510/710/Vision", - .internal_name = "aptiva510", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_OPTI_895_802G, - .init = machine_at_aptiva510_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3_PC330, - .block = CPU_BLOCK_NONE, - .min_bus = 25000000, - .max_bus = 33333333, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 2.0, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &gd5430_onboard_vlb_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[OPTi 802G] IBM PC 330 (type 6573)", - .internal_name = "pc330_6573", - .type = MACHINE_TYPE_486_S3_PCI, - .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, - .cpu = { - .package = CPU_PKG_SOCKET3_PC330, - .block = CPU_BLOCK_NONE, - .min_bus = 25000000, - .max_bus = 33333333, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 2.0, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &gd5430_onboard_vlb_device, - .snd_device = NULL, - .net_device = NULL - }, - /* has a Phoenix PLCC Multikey copyrighted 1993, version unknown. */ - { - .name = "[OPTi 895] Packard Bell PB450", - .internal_name = "pb450", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_OPTI_895_802G, - .init = machine_at_pb450_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_VIDEO, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &pb450_device, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &gd5428_vlb_onboard_device, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[i420EX] ASUS PVI-486AP4", - .internal_name = "486ap4", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_INTEL_420EX, - .init = machine_at_486ap4_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has the Phoenix MultiKey KBC firmware. */ - { - .name = "[i420EX] Intel Classic/PCI ED", - .internal_name = "ninja", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_INTEL_420EX, - .init = machine_at_ninja_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has Phoenix Multikey/42 PS/2 KBC, but unknown version */ - { - .name = "[i420EX] Anigma BAT4IP3e", - .internal_name = "bat4ip3e", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_INTEL_420EX, - .init = machine_at_bat4ip3e_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[i420EX] Advanced Integration Research 486PI", - .internal_name = "486pi", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_INTEL_420EX, - .init = machine_at_486pi_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCIV, - .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* absolutely no KBC info */ - { - .name = "[i420EX] ICS SB486P", - .internal_name = "sb486p", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_INTEL_420EX, - .init = machine_at_sb486p_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* I'm going to assume this as an AMIKey-2 like the other two 486SP3's. */ - { - .name = "[i420TX] ASUS PCI/I-486SP3", - .internal_name = "486sp3", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_INTEL_420TX, - .init = machine_at_486sp3_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE | MACHINE_SCSI | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has the Phoenix MultiKey KBC firmware. */ - { - .name = "[i420TX] Intel Classic/PCI", - .internal_name = "alfredo", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_INTEL_420TX, - .init = machine_at_alfredo_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_APM, - .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, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* According to another string seen on the UH19 website, this has AMI 'H' KBC. */ - { - .name = "[i420TX] AMI Super Voyager PCI", - .internal_name = "amis76", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_INTEL_420TX, - .init = machine_at_amis76_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. Also has a - SST 29EE010 Flash chip. */ - { - .name = "[i420ZX] ASUS PCI/I-486SP3G", - .internal_name = "486sp3g", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_INTEL_420ZX, - .init = machine_at_486sp3g_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_SCSI | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This most likely has a standalone AMI Megakey 1993, which is type 'P', like the below Tekram board. */ - { - .name = "[IMS 8848] J-Bond PCI400C-B", - .internal_name = "pci400cb", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_IMS_8848, - .init = machine_at_pci400cb_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCIV, - .flags = MACHINE_APM, - .ram = { - .min = 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, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[SiS 496] Acer P3", - .internal_name = "acerp3", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_SIS_496, - .init = machine_at_acerp3_init, - .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), - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, - .ram = { - .min = 2048, - .max = 131072, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[SiS 496] ASUS PVI-486SP3C", - .internal_name = "486sp3c", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_SIS_496, - .init = machine_at_486sp3c_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 261120, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[SiS 496] Lucky Star LS-486E", - .internal_name = "ls486e", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_SIS_496, - .init = machine_at_ls486e_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_PS2_KBC | MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a VIA VT82C42N KBC. */ - { - .name = "[SiS 496] Micronics M4Li", - .internal_name = "m4li", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_SIS_496, - .init = machine_at_m4li_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Revision 1 has a Lance LT38C41L, revision 2 has a Holtek HT6542B. Another variant with a Bestkey KBC might exist as well. */ - { - .name = "[SiS 496] Rise Computer R418", - .internal_name = "r418", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_SIS_496, - .init = machine_at_r418_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_PS2_KBC | MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 261120, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has a Holtek HT6542B KBC and the BIOS does not send a single non-standard KBC command, so it - must be an ASIC that clones the standard IBM PS/2 KBC. */ - { - .name = "[SiS 496] Soyo 4SAW2", - .internal_name = "4saw2", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_SIS_496, - .init = machine_at_4saw2_init, - .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), - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 2048, - .max = 261120, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* According to MrKsoft, his real 4DPS has an AMIKey-2, which is an updated version - of type 'H'. There are other variants of the board with Holtek HT6542B KBCs. */ - { - .name = "[SiS 496] Zida Tomato 4DP", - .internal_name = "4dps", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_SIS_496, - .init = machine_at_4dps_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, - .ram = { - .min = 2048, - .max = 261120, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* AMIKEY-2 */ - { - .name = "[SiS 496] MSI MS-4144", - .internal_name = "ms4144", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_SIS_496, - .init = machine_at_ms4144_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 5120, /* Hack: machine seems to break with less than 5 MBs of RAM */ - .max = 131072, - .step = 1024 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has the UMC 88xx on-chip KBC. */ - { - .name = "[UMC 8881] A-Trend ATC-1415", - .internal_name = "atc1415", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_UMC_UM8881, - .init = machine_at_atc1415_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[UMC 8881] ECS Elite UM8810P-AIO", - .internal_name = "ecs486", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_UMC_UM8881, - .init = machine_at_ecs486_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_PS2_KBC | MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey Z(!) KBC firmware. */ - { - .name = "[UMC 8881] Epson ActionPC 2600", - .internal_name = "actionpc2600", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_UMC_UM8881, - .init = machine_at_actionpc2600_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, - .ram = { - .min = 1024, - .max = 262144, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has the UMC 88xx on-chip KBC. All the copies of the BIOS string I can find, end in - in -H, so the UMC on-chip KBC likely emulates the AMI 'H' KBC firmware. */ - { - .name = "[UMC 8881] Epson ActionTower 8400", - .internal_name = "actiontower8400", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_UMC_UM8881, - .init = machine_at_actiontower8400_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, - .ram = { - .min = 1024, - .max = 262144, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has the UMC 88xx on-chip KBC. All the copies of the BIOS string I can find, end in - in -H, so the UMC on-chip KBC likely emulates the AMI 'H' KBC firmware. */ - { - .name = "[UMC 8881] PC Chips M919", - .internal_name = "m919", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_UMC_UM8881, - .init = machine_at_m919_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. Uses a mysterious I/O port C05. */ - { - .name = "[UMC 8881] Samsung SPC7700P-LW", - .internal_name = "spc7700plw", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_UMC_UM8881, - .init = machine_at_spc7700plw_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has a Holtek KBC. */ - { - .name = "[UMC 8881] Shuttle HOT-433A", - .internal_name = "hot433a", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_UMC_UM8881, - .init = machine_at_hot433a_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 262144, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Compaq Presario 7100 / 7200 Series, using MiTAC/Trigon PL4600C (486). */ - /* Has a VIA VT82C42N KBC. */ - { - .name = "[UMC 8881] Compaq Presario 7100/7200 Series 486", - .internal_name = "pl4600c", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_UMC_UM8881, - .init = machine_at_pl4600c_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &gd5430_onboard_pci_device, - .snd_device = &ess_1688_device, - .net_device = NULL - }, - /* Has a VIA VT82C406 KBC+RTC that likely has identical commands to the VT82C42N. */ - { - .name = "[VIA VT82C496G] DFI G486VPA", - .internal_name = "g486vpa", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_VIA_VT82C496G, - .init = machine_at_g486vpa_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a VIA VT82C42N KBC. */ - { - .name = "[VIA VT82C496G] FIC VIP-IO2", - .internal_name = "486vipio2", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_VIA_VT82C496G, - .init = machine_at_486vipio2_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, - .ram = { - .min = 1024, - .max = 131072, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 486 machines - Miscellaneous */ - /* 486 machines which utilize the PCI bus */ - /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[STPC Client] ITOX STAR", - .internal_name = "itoxstar", - .type = MACHINE_TYPE_486_MISC, - .chipset = MACHINE_CHIPSET_STPC_CLIENT, - .init = machine_at_itoxstar_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_STPC, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 75000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 1.0, - .max_multi = 1.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[STPC Consumer-II] Acrosser AR-B1423C", - .internal_name = "arb1423c", - .type = MACHINE_TYPE_486_MISC, - .chipset = MACHINE_CHIPSET_STPC_CONSUMER_II, - .init = machine_at_arb1423c_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_STPC, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 66666667, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 2.0, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2_PCI, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 486 machines which utilize the PCI bus */ + /* Machine with ALi M1429G chipset and M1435 southbridge */ + /* Has an AMIKEY-2 KBC. */ + { + .name = "[ALi M1429G] MSI MS-4134", + .internal_name = "ms4134", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_ms4134_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCIV, + .flags = MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* TriGem machine with M1429G and PhoenixBIOS */ + { + .name = "[ALi M1429G] TriGem 486GP (Talent)", + .internal_name = "tg486gp", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_ALI_M1429G, + .init = machine_at_tg486gp_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCIV, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[ALi M1489] AAEON SBC-490", + .internal_name = "sbc490", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_sbc490_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &tgui9440_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT + KBC. */ + { + .name = "[ALi M1489] ABIT AB-PB4", + .internal_name = "abpb4", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_abpb4_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, /* Machine has a PISA slot */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT + KBC. + The BIOS string always ends in -U, but the BIOS will send AMIKey commands 0xCA + and 0xCB if command 0xA1 returns a letter in the 0x5x or 0x7x ranges, so I'm + going to give it an AMI 'U' KBC. */ + { + .name = "[ALi M1489] AMI WinBIOS 486 PCI", + .internal_name = "win486pci", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_win486pci_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the ALi M1487/9's on-chip keyboard controller which clones a standard AT + KBC. + The known BIOS string ends in -E, and the BIOS returns whatever command 0xA1 + returns (but only if command 0xA1 is instant response), so said ALi keyboard + controller likely returns 'E'. */ + { + .name = "[ALi M1489] MSI MS-4145", + .internal_name = "ms4145", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_ms4145_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has an ALi M5042 keyboard controller with Phoenix MultiKey/42 v1.40 firmware. */ + { + .name = "[ALi M1489] ESA TF-486", + .internal_name = "tf486", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_tf486_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has an ALi M5042 with phoenix firmware like the ESA TF-486. */ + { + .name = "[ALi M1489] Acrosser AR-B1476", + .internal_name = "arb1476", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_ALI_M1489, + .init = machine_at_arb1476_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, /* Has onboard video: C&T F65545 */ + .ram = { + .min = 8192, + .max = 73728, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[OPTi 802G] IBM Aptiva 510/710/Vision", + .internal_name = "aptiva510", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_OPTI_895_802G, + .init = machine_at_aptiva510_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3_PC330, + .block = CPU_BLOCK_NONE, + .min_bus = 25000000, + .max_bus = 33333333, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 2.0, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5430_onboard_vlb_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[OPTi 802G] IBM PC 330 (type 6573)", + .internal_name = "pc330_6573", + .type = MACHINE_TYPE_486_S3_PCI, + .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, + .cpu = { + .package = CPU_PKG_SOCKET3_PC330, + .block = CPU_BLOCK_NONE, + .min_bus = 25000000, + .max_bus = 33333333, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 2.0, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5430_onboard_vlb_device, + .snd_device = NULL, + .net_device = NULL + }, + /* has a Phoenix PLCC Multikey copyrighted 1993, version unknown. */ + { + .name = "[OPTi 895] Packard Bell PB450", + .internal_name = "pb450", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_OPTI_895_802G, + .init = machine_at_pb450_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &pb450_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5428_vlb_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[i420EX] ASUS PVI-486AP4", + .internal_name = "486ap4", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_INTEL_420EX, + .init = machine_at_486ap4_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCIV, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the Phoenix MultiKey KBC firmware. */ + { + .name = "[i420EX] Intel Classic/PCI ED (Ninja)", + .internal_name = "ninja", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_INTEL_420EX, + .init = machine_at_ninja_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Phoenix Multikey/42 PS/2 KBC, but unknown version */ + { + .name = "[i420EX] Anigma BAT4IP3e", + .internal_name = "bat4ip3e", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_INTEL_420EX, + .init = machine_at_bat4ip3e_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[i420EX] Advanced Integration Research 486PI", + .internal_name = "486pi", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_INTEL_420EX, + .init = machine_at_486pi_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCIV, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* absolutely no KBC info */ + { + .name = "[i420EX] ICS SB486P", + .internal_name = "sb486p", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_INTEL_420EX, + .init = machine_at_sb486p_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* + This has an AMIKey (and an on-board NCR 53C810 PCI SCSI controller), thanks, eBay! + The keyboard port is AT. + */ + { + .name = "[i420TX] ASUS PCI/I-486SP3", + .internal_name = "486sp3", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_INTEL_420TX, + .init = machine_at_486sp3_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE | MACHINE_SCSI | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the Phoenix MultiKey KBC firmware. */ + { + .name = "[i420TX] Intel Classic/PCI (Alfredo)", + .internal_name = "alfredo", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_INTEL_420TX, + .init = machine_at_alfredo_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* According to another string seen on the UH19 website, this has AMI 'H' KBC. */ + { + .name = "[i420TX] AMI Super Voyager PCI", + .internal_name = "amis76", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_INTEL_420TX, + .init = machine_at_amis76_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. Also has a + SST 29EE010 Flash chip. */ + { + .name = "[i420ZX] ASUS PCI/I-486SP3G", + .internal_name = "486sp3g", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_INTEL_420ZX, + .init = machine_at_486sp3g_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE | MACHINE_SCSI | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMI MEGAKey 'P' or 'R' keyboard controller. */ + { + .name = "[i420ZX] ICS SB486PV", + .internal_name = "sb486pv", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_INTEL_420ZX, + .init = machine_at_sb486pv_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + /* Has PCI but no user-facing slots. */ + .bus_flags = MACHINE_PCI, + .flags = MACHINE_PS2_KBC | MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM | MACHINE_PCI_INTERNAL, + .ram = { + .min = 2048, + .max = 65536, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &sb486pv_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5436_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* This most likely has a standalone AMI Megakey 1993, which is type 'P', like the below Tekram board. */ + { + .name = "[IMS 8848] J-Bond PCI400C-B", + .internal_name = "pci400cb", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_IMS_8848, + .init = machine_at_pci400cb_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCIV, + .flags = MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[SiS 496] Acer P3", + .internal_name = "acerp3", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_SIS_496, + .init = machine_at_acerp3_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, + .ram = { + .min = 2048, + .max = 131072, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5434_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[SiS 496] ASUS PVI-486SP3C", + .internal_name = "486sp3c", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_SIS_496, + .init = machine_at_486sp3c_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCIV, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 261120, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[SiS 496] Lucky Star LS-486E", + .internal_name = "ls486e", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_SIS_496, + .init = machine_at_ls486e_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_PS2_KBC | MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a VIA VT82C42N KBC. */ + { + .name = "[SiS 496] Micronics M4Li", + .internal_name = "m4li", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_SIS_496, + .init = machine_at_m4li_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Revision 1 has a Lance LT38C41L, revision 2 has a Holtek HT6542B. Another variant with a Bestkey KBC might exist as well. */ + { + .name = "[SiS 496] Rise Computer R418", + .internal_name = "r418", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_SIS_496, + .init = machine_at_r418_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_PS2_KBC | MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 261120, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has a Holtek HT6542B KBC and the BIOS does not send a single non-standard KBC command, so it + must be an ASIC that clones the standard IBM PS/2 KBC. */ + { + .name = "[SiS 496] Soyo 4SAW2", + .internal_name = "4saw2", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_SIS_496, + .init = machine_at_4saw2_init, + .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), + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCIV, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 2048, + .max = 261120, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* According to MrKsoft, his real 4DPS has an AMIKey-2, which is an updated version + of type 'H'. There are other variants of the board with Holtek HT6542B KBCs. */ + { + .name = "[SiS 496] Zida Tomato 4DP", + .internal_name = "4dps", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_SIS_496, + .init = machine_at_4dps_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, + .ram = { + .min = 2048, + .max = 261120, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* AMIKEY-2 */ + { + .name = "[SiS 496] MSI MS-4144", + .internal_name = "ms4144", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_SIS_496, + .init = machine_at_ms4144_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 5120, /* Hack: machine seems to break with less than 5 MBs of RAM */ + .max = 131072, + .step = 1024 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the UMC 88xx on-chip KBC. */ + { + .name = "[UMC 8881] A-Trend ATC-1415", + .internal_name = "atc1415", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_UMC_UM8881, + .init = machine_at_atc1415_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the UMC 88xx on-chip KBC. All the copies of the BIOS string I can find, end in + in -H, so the UMC on-chip KBC likely emulates the AMI 'H' KBC firmware. */ + { + .name = "[UMC 8881] Biostar MB-84xxUUD-A", + .internal_name = "84xxuuda", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_UMC_UM8881, + .init = machine_at_84xxuuda_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[UMC 8881] ECS Elite UM8810P-AIO", + .internal_name = "ecs486", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_UMC_UM8881, + .init = machine_at_ecs486_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_PS2_KBC | MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey Z(!) KBC firmware. */ + { + .name = "[UMC 8881] Epson ActionPC 2600", + .internal_name = "actionpc2600", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_UMC_UM8881, + .init = machine_at_actionpc2600_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 262144, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &tgui9440_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the UMC 88xx on-chip KBC. All the copies of the BIOS string I can find, end in + in -H, so the UMC on-chip KBC likely emulates the AMI 'H' KBC firmware. */ + { + .name = "[UMC 8881] Epson ActionTower 8400", + .internal_name = "actiontower8400", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_UMC_UM8881, + .init = machine_at_actiontower8400_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 262144, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5430_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the UMC 88xx on-chip KBC. All the copies of the BIOS string I can find, end in + in -H, so the UMC on-chip KBC likely emulates the AMI 'H' KBC firmware. */ + { + .name = "[UMC 8881] PC Chips M919", + .internal_name = "m919", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_UMC_UM8881, + .init = machine_at_m919_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PCIV, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. Uses a mysterious I/O port C05. */ + { + .name = "[UMC 8881] Samsung SPC7700P-LW", + .internal_name = "spc7700plw", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_UMC_UM8881, + .init = machine_at_spc7700plw_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has a Holtek KBC. */ + { + .name = "[UMC 8881] Shuttle HOT-433A", + .internal_name = "hot433a", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_UMC_UM8881, + .init = machine_at_hot433a_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 262144, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &hot433a_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Compaq Presario 7100 / 7200 Series, using MiTAC/Trigon PL4600C (486). */ + /* Has a VIA VT82C42N KBC. */ + { + .name = "[UMC 8881] Compaq Presario 7100/7200 Series 486", + .internal_name = "pl4600c", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_UMC_UM8881, + .init = machine_at_pl4600c_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5430_onboard_pci_device, + .snd_device = &ess_1688_device, + .net_device = NULL + }, + /* Has a VIA VT82C406 KBC+RTC that likely has identical commands to the VT82C42N. */ + { + .name = "[VIA VT82C496G] DFI G486VPA", + .internal_name = "g486vpa", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_VIA_VT82C496G, + .init = machine_at_g486vpa_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCIV, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a VIA VT82C42N KBC. */ + { + .name = "[VIA VT82C496G] FIC VIP-IO2", + .internal_name = "486vipio2", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_VIA_VT82C496G, + .init = machine_at_486vipio2_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCIV, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, + .ram = { + .min = 1024, + .max = 131072, + .step = 1024 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 486 machines - Miscellaneous */ + /* 486 machines which utilize the PCI bus */ + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[STPC Client] ITOX STAR", + .internal_name = "itoxstar", + .type = MACHINE_TYPE_486_MISC, + .chipset = MACHINE_CHIPSET_STPC_CLIENT, + .init = machine_at_itoxstar_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_STPC, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 75000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 1.0, + .max_multi = 1.0 + }, + .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal video: ST STPC Atlas */ - .ram = { - .min = 32768, - .max = 163840, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[STPC Consumer-II] Acrosser AR-B1479", - .internal_name = "arb1479", - .type = MACHINE_TYPE_486_MISC, - .chipset = MACHINE_CHIPSET_STPC_CONSUMER_II, - .init = machine_at_arb1479_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_STPC, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 66666667, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 2.0, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: ST STPC Atlas */ - .ram = { - .min = 32768, - .max = 163840, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[STPC Consumer-II] Lanner Electronics IAC-H488", - .internal_name = "iach488", - .type = MACHINE_TYPE_486_MISC, - .chipset = MACHINE_CHIPSET_STPC_CONSUMER_II, - .init = machine_at_iach488_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_STPC, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 66666667, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 2.0, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal video: ST STPC Atlas and NIC: Realtek RTL8139C+ */ - .ram = { - .min = 32768, - .max = 131072, - .step = 32768 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[STPC Elite] Advantech PCM-9340", - .internal_name = "pcm9340", - .type = MACHINE_TYPE_486_MISC, - .chipset = MACHINE_CHIPSET_STPC_ELITE, - .init = machine_at_pcm9340_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_STPC, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 66666667, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 2.0, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 32768, - .max = 98304, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[STPC Atlas] AAEON PCM-5330", - .internal_name = "pcm5330", - .type = MACHINE_TYPE_486_MISC, - .chipset = MACHINE_CHIPSET_STPC_ATLAS, - .init = machine_at_pcm5330_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_STPC, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 66666667, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 2.0, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 32768, - .max = 131072, - .step = 32768 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* Socket 4 machines */ - /* 430LX */ - /* Has AMIKey H KBC firmware (AMIKey-2), per POST screen with BIOS string - shown in the manual. Has PS/2 mouse support with serial-style (DB9) - connector. - The boot block for BIOS recovery requires an unknown bit on port 805h - to be clear. */ - { - .name = "[i430LX] AMI Excalibur PCI Pentium", - .internal_name = "excaliburpci", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_INTEL_430LX, - .init = machine_at_excaliburpci_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal SCSI */ - .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, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey F KBC firmware (AMIKey). */ - { - .name = "[i430LX] ASUS P/I-P5MP3", - .internal_name = "p5mp3", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_INTEL_430LX, - .init = machine_at_p5mp3_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_PS2_KBC | MACHINE_APM, - .ram = { - .min = 2048, - .max = 196608, - .step = 2048 - }, - .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 IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[i430LX] Dell Dimension XPS P60", - .internal_name = "dellxp60", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_INTEL_430LX, - .init = machine_at_dellxp60_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_APM, - .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, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[i430LX] Dell OptiPlex 560/L", - .internal_name = "opti560l", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_INTEL_430LX, - .init = machine_at_opti560l_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_APM, - .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, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has the Phoenix MultiKey KBC firmware. - This is basically an Intel Batman (*NOT* Batman's Revenge) with a fancier - POST screen */ - { - .name = "[i430LX] AMBRA DP60 PCI", - .internal_name = "ambradp60", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_INTEL_430LX, - .init = machine_at_ambradp60_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_APM, - .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, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[i430LX] IBM PS/ValuePoint P60", - .internal_name = "valuepointp60", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_INTEL_430LX, - .init = machine_at_valuepointp60_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_VIDEO_8514A | MACHINE_APM, - .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, - .vid_device = &mach32_onboard_pci_device, - .snd_device = NULL, - .net_device = NULL - }, - /* This has the Phoenix MultiKey KBC firmware. */ - { - .name = "[i430LX] Intel Premiere/PCI", - .internal_name = "revenge", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_INTEL_430LX, - .init = machine_at_revenge_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 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, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMI MegaKey 'H' KBC firmware. */ - { - .name = "[i430LX] Gigabyte GA-586IS", - .internal_name = "586is", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_INTEL_430LX, - .init = machine_at_586is_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_APM, - .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, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has the Phoenix MultiKey KBC firmware. */ - { - .name = "[i430LX] Packard Bell PB520R", - .internal_name = "pb520r", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_INTEL_430LX, - .init = machine_at_pb520r_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 8192, - .max = 139264, - .step = 2048 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &gd5434_onboard_pci_device, - .snd_device = NULL, - .net_device = NULL - }, - /* The M5Pi appears to have a Phoenix MultiKey KBC firmware according to photos. */ - { - .name = "[i430LX] Micronics M5Pi", - .internal_name = "m5pi", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_INTEL_430LX, - .init = machine_at_m5pi_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .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, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* OPTi 596/597 */ - /* This uses an AMI KBC firmware in PS/2 mode (it sends command A5 with the - PS/2 "Load Security" meaning), most likely MegaKey as it sends command AF - (Set Extended Controller RAM) just like the later Intel AMI BIOS'es. */ - { - .name = "[OPTi 597] AMI Excalibur VLB", - .internal_name = "excalibur", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_OPTI_547_597, - .init = machine_at_excalibur_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 60000000, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PS2_VLB, - .flags = MACHINE_IDE | MACHINE_APM, - .ram = { - .min = 2048, - .max = 65536, - .step = 2048 - }, - .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 - }, - - /* OPTi 596/597/822 */ - /* Has a VIA VT82C42N KBC with AMI 'F' firmware */ - { - .name = "[OPTi 597] AT&T Globalyst 330 (Pentium)", - .internal_name = "globalyst330_p5", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_OPTI_547_597, - .init = machine_at_globalyst330_p5_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PCIV, - .flags = MACHINE_APM, - .ram = { - .min = 8192, - .max = 65536, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has AMIKey 'F' KBC firmware. */ - { - .name = "[OPTi 597] Supermicro P5VL-PCI", - .internal_name = "p5vl", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_OPTI_547_597, - .init = machine_at_p5vl_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PCIV, - .flags = MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* SiS 50x */ - /* This has some form of AMI MegaKey as it uses keyboard controller command 0xCC. */ - { - .name = "[SiS 501] AMI Excalibur PCI-II Pentium ISA", - .internal_name = "excaliburpci2", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_SIS_501, - .init = machine_at_excaliburpci2_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[SiS 501] ASUS PCI/I-P5SP4", - .internal_name = "p5sp4", - .type = MACHINE_TYPE_SOCKET4, - .chipset = MACHINE_CHIPSET_SIS_501, - .init = machine_at_p5sp4_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET4, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Socket 5 machines */ - /* 430NX */ - /* This has the Phoenix MultiKey KBC firmware. */ - { - .name = "[i430NX] Intel Premiere/PCI II", - .internal_name = "plato", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_INTEL_430NX, - .init = machine_at_plato_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3520, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 1.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 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, - .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(CPU_K5, CPU_5K86, CPU_Cx6x86), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3520, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 1.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 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, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has the Phoenix MultiKey KBC firmware. - This is basically an Intel Premiere/PCI II with a fancier POST screen. */ - { - .name = "[i430NX] AMBRA DP90 PCI", - .internal_name = "ambradp90", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_INTEL_430NX, - .init = machine_at_ambradp90_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 1.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .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, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMI 'H' KBC firmware. */ - { - .name = "[i430NX] ASUS PCI/I-P54NP4", - .internal_name = "p54np4", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_INTEL_430NX, - .init = machine_at_p54np4_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .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 | MACHINE_SCSI | MACHINE_APM, - .ram = { - .min = 2048, - .max = 524288, - .step = 2048 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMI 'H' KBC firmware. */ - { - .name = "[i430NX] Gigabyte GA-586IP", - .internal_name = "586ip", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_INTEL_430NX, - .init = machine_at_586ip_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 3520, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 1.5 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_APM, - .ram = { - .min = 2048, - .max = 262144, - .step = 2048 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMI MegaKey KBC firmware. */ - { - .name = "[i430NX] Teknor TEK-932", - .internal_name = "tek932", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_INTEL_430NX, - .init = machine_at_tek932_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 3520, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 1.5 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE | MACHINE_APM, - .ram = { - .min = 2048, - .max = 262144, - .step = 2048 - }, - .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 - }, - - /* 430FX */ - /* Uses an ACER/NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware (V5.0). */ - { - .name = "[i430FX] Acer V30", - .internal_name = "acerv30", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_acerv30_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey F KBC firmware. */ - { - .name = "[i430FX] AMI Apollo", - .internal_name = "apollo", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_apollo_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .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 - }, - /* 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 = "[i430FX] Intel Advanced/ZP", - .internal_name = "zappa", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_zappa_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .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 - }, - /* The BIOS sends KBC command B3 which indicates an AMI (or VIA VT82C42N) KBC. */ - { - .name = "[i430FX] NEC PowerMate V", - .internal_name = "powermatev", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_powermatev_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey Z(!) KBC firmware. */ - { - .name = "[i430FX] TriGem Hawk", - .internal_name = "hawk", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_hawk_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* KBC On-Chip the VT82C406MV. */ - { - .name = "[i430FX] FIC PT-2000", - .internal_name = "pt2000", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_pt2000_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .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 - }, - - /* OPTi 596/597 */ - /* This uses an AMI KBC firmware in PS/2 mode (it sends command A5 with the - PS/2 "Load Security" meaning), most likely MegaKey as it sends command AF - (Set Extended Controller RAM) just like the later Intel AMI BIOS'es. */ - { - .name = "[OPTi 597] TMC PAT54PV", - .internal_name = "pat54pv", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_OPTI_547_597, - .init = machine_at_pat54pv_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3520, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 1.5 - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM, - .ram = { - .min = 2048, - .max = 65536, - .step = 2048 - }, - .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 - }, - - /* OPTi 596/597/822 */ - { - .name = "[OPTi 597] Shuttle HOT-543", - .internal_name = "hot543", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_OPTI_547_597, - .init = machine_at_hot543_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3520, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PCIV, - .flags = MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - { - .name = "[OPTi 597] Northgate Computer Systems Elegance Pentium 90", - .internal_name = "ncselp90", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_OPTI_547_597, - .init = machine_at_ncselp90_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3520, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2_PCIV, - .flags = MACHINE_APM | MACHINE_IDE_DUAL | MACHINE_SUPER_IO, - .ram = { - .min = 8192, - .max = 131072, - .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 - }, - - /* SiS 85C50x */ - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[SiS 501] ASUS PCI/I-P54SP4", - .internal_name = "p54sp4", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_SIS_501, - .init = machine_at_p54sp4_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86), - .min_bus = 40000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 1.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[SiS 501] BCM SQ-588", - .internal_name = "sq588", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_SIS_501, - .init = machine_at_sq588_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_PENTIUMMMX), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3520, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 1.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This machine has a Winbond W83C842 KBC */ - { - .name = "[SiS 501] Gemlight GMB-P54SPS", - .internal_name = "p54sps", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_SIS_501, - .init = machine_at_p54sps_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - CPU_BLOCK(CPU_PENTIUMMMX), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3520, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 1.5 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = &keyboard_at_ami_device, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[SiS 5501] MSI MS-5109", - .internal_name = "ms5109", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_SIS_5501, - .init = machine_at_ms5109_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - CPU_BLOCK(CPU_PENTIUMMMX), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3520, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 1.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey Z(!) KBC firmware. */ - { - .name = "[SiS 5501] TriGem Torino", - .internal_name = "torino", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_SIS_5501, - .init = machine_at_torino_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - CPU_BLOCK(CPU_PENTIUMMMX), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3520, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 1.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &tgui9660_onboard_pci_device, - .snd_device = NULL, - .net_device = NULL - }, - - /* UMC 889x */ - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[UMC 889x] Shuttle HOT-539", - .internal_name = "hot539", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_UMC_UM8890BF, - .init = machine_at_hot539_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86), - .min_bus = 40000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3600, - .min_multi = 1.5, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 262144, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* Socket 7 (Single Voltage) machines */ - /* 430FX */ - /* This has an AMIKey-2, which is an updated version of type 'H'. - This also seems to be revision 2.1 with the FDC37C665 SIO. */ - { - .name = "[i430FX] ASUS P/I-P55TP4XE", - .internal_name = "p54tp4xe", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_p54tp4xe_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 = 3600, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[i430FX] ASUS P/I-P55TP4XE (MR BIOS)", - .internal_name = "p54tp4xe_mr", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_p54tp4xe_mr_init, - .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 = 3600, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey H KBC firmware. The KBC itself seems to differ between an AMIKEY-2 and a Winbond W83C42. */ - { - .name = "[i430FX] DataExpert EXP8551", - .internal_name = "exp8551", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_exp8551_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* 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 = "[i430FX] Gateway 2000 Thor", - .internal_name = "gw2katx", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_gw2katx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), - .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_GAMEPORT, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a SM(S)C FDC37C932 Super I/O chip with on-chip KBC with AMI - MegaKey (revision '5') KBC firmware. */ - { - .name = "[i430FX] HP Vectra VL 5 Series 4", - .internal_name = "vectra54", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_vectra54_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 2.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 511, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &s3_phoenix_trio64_onboard_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 . */ - { - .name = "[i430FX] Intel Advanced/ATX", - .internal_name = "thor", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_thor_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), - .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_VIDEO | MACHINE_APM | MACHINE_GAMEPORT, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &s3_phoenix_trio64vplus_onboard_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 . */ - { - .name = "[i430FX] Intel Advanced/ATX (MR BIOS)", - .internal_name = "mrthor", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_mrthor_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_GAMEPORT, - .ram = { - .min = 8192, - .max = 131072, - .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 - }, - /* 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 = "[i430FX] Intel Advanced/EV", - .internal_name = "endeavor", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_endeavor_init, - .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(CPU_K5, CPU_5K86, CPU_Cx6x86), - .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_VIDEO | MACHINE_SOUND | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &s3_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'. */ - { - .name = "[i430FX] MSI MS-5119", - .internal_name = "ms5119", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_ms5119_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 = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This most likely uses AMI MegaKey KBC firmware as well due to having the same - Super I/O chip (that has the KBC firmware on it) as eg. the Advanced/EV. */ - { - .name = "[i430FX] Packard Bell PB640", - .internal_name = "pb640", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_pb640_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), - .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_VIDEO | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .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 = &gd5440_onboard_pci_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a VIA VT82C42N KBC. */ - { - .name = "[i430FX] PC Partner MB500N", - .internal_name = "mb500n", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_mb500n_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has an AMI MegaKey 'H' KBC firmware (1992). */ - { - .name = "[i430FX] QDI FMB", - .internal_name = "fmb", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_fmb_init, - .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), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 430HX */ - /* Has SST Flash. */ - /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix - MultiKey/42 (version 1.38) KBC firmware. */ - { - .name = "[i430HX] Acer V35N", - .internal_name = "acerv35n", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_acerv35n_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 = 3450, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 4096, - .max = 524288, - .step = 4096 - }, - .nvrmask = 511, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey-2 or VIA VT82C42N KBC (depending on the revision) with AMIKEY 'F' KBC firmware. */ - { - .name = "[i430HX] AOpen AP53", - .internal_name = "ap53", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_ap53_init, - .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 = 3450, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 2.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 4096, - .max = 524288, - .step = 4096 - }, - .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 - }, - /* [TEST] Has a VIA 82C42N KBC, with AMIKey F KBC firmware. */ - { - .name = "[i430HX] Biostar MB-8500TUC", - .internal_name = "8500tuc", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_8500tuc_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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 4096, - .max = 524288, - .step = 4096 - }, - .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 - }, - - /* 430VX */ - /* Has a SM(S)C FDC37C932FR Super I/O chip with on-chip KBC with AMI - MegaKey (revision '5') KBC firmware. */ - { - .name = "[i430VX] Gateway 2000 Mailman", - .internal_name = "gw2kma", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_gw2kma_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), - .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 | MACHINE_BUS_USB, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[STPC Consumer-II] Acrosser AR-B1423C", + .internal_name = "arb1423c", + .type = MACHINE_TYPE_486_MISC, + .chipset = MACHINE_CHIPSET_STPC_CONSUMER_II, + .init = machine_at_arb1423c_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_STPC, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 2.0, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_PCI_INTERNAL, /* Machine has internal video: ST STPC Atlas */ + .ram = { + .min = 32768, + .max = 163840, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[STPC Consumer-II] Acrosser AR-B1479", + .internal_name = "arb1479", + .type = MACHINE_TYPE_486_MISC, + .chipset = MACHINE_CHIPSET_STPC_CONSUMER_II, + .init = machine_at_arb1479_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_STPC, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 2.0, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_PCI_INTERNAL | MACHINE_USB, /* Machine has internal video: ST STPC Atlas */ + .ram = { + .min = 32768, + .max = 163840, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[STPC Consumer-II] Lanner Electronics IAC-H488", + .internal_name = "iach488", + .type = MACHINE_TYPE_486_MISC, + .chipset = MACHINE_CHIPSET_STPC_CONSUMER_II, + .init = machine_at_iach488_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_STPC, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 2.0, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE | MACHINE_APM | MACHINE_PCI_INTERNAL, /* Machine has internal video: ST STPC Atlas and NIC: Realtek RTL8139C+ */ + .ram = { + .min = 32768, + .max = 131072, + .step = 32768 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[STPC Elite] Advantech PCM-9340", + .internal_name = "pcm9340", + .type = MACHINE_TYPE_486_MISC, + .chipset = MACHINE_CHIPSET_STPC_ELITE, + .init = machine_at_pcm9340_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_STPC, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 2.0, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_PCI_INTERNAL, /* Machine has internal video: SMI LynxEM+ 712 */ + .ram = { + .min = 32768, + .max = 98304, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[STPC Atlas] AAEON PCM-5330", + .internal_name = "pcm5330", + .type = MACHINE_TYPE_486_MISC, + .chipset = MACHINE_CHIPSET_STPC_ATLAS, + .init = machine_at_pcm5330_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_STPC, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 2.0, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_PCI_INTERNAL, /* Machine has internal video: ST STPC Atlas */ + .ram = { + .min = 32768, + .max = 131072, + .step = 32768 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* Socket 4 machines */ + /* 430LX */ + { + .name = "[i430LX] Acer V12P", + .internal_name = "v12p", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_INTEL_430LX, + .init = machine_at_v12p_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 2048, + .max = 196608, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &v12p_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey H KBC firmware (AMIKey-2), per POST screen with BIOS string + shown in the manual. Has PS/2 mouse support with serial-style (DB9) + connector. + The boot block for BIOS recovery requires an unknown bit on port 805h + to be clear. */ + { + .name = "[i430LX] AMI Excalibur PCI Pentium", + .internal_name = "excaliburpci", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_INTEL_430LX, + .init = machine_at_excaliburpci_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal SCSI */ + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey F KBC firmware (AMIKey). */ + { + .name = "[i430LX] ASUS P/I-P5MP3", + .internal_name = "p5mp3", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_INTEL_430LX, + .init = machine_at_p5mp3_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_PS2_KBC | MACHINE_APM, + .ram = { + .min = 2048, + .max = 196608, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[i430LX] Dell Dimension XPS P60", + .internal_name = "dellxp60", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_INTEL_430LX, + .init = machine_at_dellxp60_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[i430LX] Dell OptiPlex 560/L", + .internal_name = "opti560l", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_INTEL_430LX, + .init = machine_at_opti560l_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the Phoenix MultiKey KBC firmware. + This is basically an Intel Batman (*NOT* Batman's Revenge) with a fancier + POST screen */ + { + .name = "[i430LX] AMBRA DP60 PCI", + .internal_name = "ambradp60", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_INTEL_430LX, + .init = machine_at_ambradp60_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[i430LX] IBM PS/ValuePoint P60", + .internal_name = "valuepointp60", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_INTEL_430LX, + .init = machine_at_valuepointp60_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_VIDEO_8514A | MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &mach32_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the Phoenix MultiKey KBC firmware. */ + { + .name = "[i430LX] Intel Premiere/PCI (Batman's Revenge)", + .internal_name = "revenge", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_INTEL_430LX, + .init = machine_at_revenge_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMI MegaKey 'H' KBC firmware. */ + { + .name = "[i430LX] Gigabyte GA-586IS", + .internal_name = "586is", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_INTEL_430LX, + .init = machine_at_586is_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the Phoenix MultiKey KBC firmware. */ + { + .name = "[i430LX] Packard Bell PB520R", + .internal_name = "pb520r", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_INTEL_430LX, + .init = machine_at_pb520r_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 8192, + .max = 139264, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5434_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* The M5Pi appears to have a Phoenix MultiKey KBC firmware according to photos. */ + { + .name = "[i430LX] Micronics M5Pi", + .internal_name = "m5pi", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_INTEL_430LX, + .init = machine_at_m5pi_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* OPTi 596/597 */ + /* This uses an AMI KBC firmware in PS/2 mode (it sends command A5 with the + PS/2 "Load Security" meaning), most likely MegaKey as it sends command AF + (Set Extended Controller RAM) just like the later Intel AMI BIOS'es. */ + { + .name = "[OPTi 597] AMI Excalibur VLB", + .internal_name = "excalibur", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_OPTI_547_597, + .init = machine_at_excalibur_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 60000000, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_VLB, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 2048, + .max = 65536, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* OPTi 596/597/822 */ + /* Has a VIA VT82C42N KBC with AMI 'F' firmware */ + { + .name = "[OPTi 597] AT&T Globalyst 330 (Pentium)", + .internal_name = "globalyst330_p5", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_OPTI_547_597, + .init = machine_at_globalyst330_p5_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PCIV, + .flags = MACHINE_APM, + .ram = { + .min = 8192, + .max = 65536, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has AMIKey 'F' KBC firmware. */ + { + .name = "[OPTi 597] Supermicro P5VL-PCI", + .internal_name = "p5vl", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_OPTI_547_597, + .init = machine_at_p5vl_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PCIV, + .flags = MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* SiS 50x */ + /* This has some form of AMI MegaKey as it uses keyboard controller command 0xCC. */ + { + .name = "[SiS 501] AMI Excalibur PCI-II Pentium ISA", + .internal_name = "excaliburpci2", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_SIS_501, + .init = machine_at_excaliburpci2_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[SiS 501] ASUS PCI/I-P5SP4", + .internal_name = "p5sp4", + .type = MACHINE_TYPE_SOCKET4, + .chipset = MACHINE_CHIPSET_SIS_501, + .init = machine_at_p5sp4_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET4, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 5000, + .max_voltage = 5000, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Socket 5 machines */ + /* 430NX */ + /* This has the Phoenix MultiKey KBC firmware. */ + { + .name = "[i430NX] Intel Premiere/PCI II (Plato)", + .internal_name = "plato", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430NX, + .init = machine_at_plato_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_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(CPU_K5, CPU_5K86, CPU_Cx6x86), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + { + .name = "[i430NX] Siemens-Nixdorf D842", + .internal_name = "d842", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430NX, + .init = machine_at_d842_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has onboard video: TLI ET4000/w32p */ + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &d842_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the Phoenix MultiKey KBC firmware. + This is basically an Intel Premiere/PCI II with a fancier POST screen. */ + { + .name = "[i430NX] AMBRA DP90 PCI", + .internal_name = "ambradp90", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430NX, + .init = machine_at_ambradp90_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 2048, + .max = 131072, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMI 'H' KBC firmware. */ + { + .name = "[i430NX] ASUS PCI/I-P54NP4", + .internal_name = "p54np4", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430NX, + .init = machine_at_p54np4_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .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 /*| MACHINE_SCSI */ | MACHINE_APM, + .ram = { + .min = 2048, + .max = 524288, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMI 'H' KBC firmware. */ + { + .name = "[i430NX] Gigabyte GA-586IP", + .internal_name = "586ip", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430NX, + .init = machine_at_586ip_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_APM, + .ram = { + .min = 2048, + .max = 262144, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMI MegaKey KBC firmware. */ + { + .name = "[i430NX] Teknor TEK-932", + .internal_name = "tek932", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430NX, + .init = machine_at_tek932_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE | MACHINE_APM, + .ram = { + .min = 2048, + .max = 262144, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 430FX */ + /* Uses an ACER/NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware (V5.0). */ + { + .name = "[i430FX] Acer V30", + .internal_name = "acerv30", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_acerv30_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey F KBC firmware. */ + { + .name = "[i430FX] AMI Apollo", + .internal_name = "apollo", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_apollo_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a National Semiconductor PC87332VLJ Super I/O with AMIKey 'F' KBC firmware. */ + { + .name = "[i430FX] Dell OptiPlex GXL/GXM", + .internal_name = "optiplexgxl", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_optiplexgxl_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_Cx6x86), + .min_bus = 60000000, + .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_VIDEO | MACHINE_SOUND | MACHINE_APM, /* Video: S3 Trio64V+ (86C765), Sound: Creative ViBRA 16S (CT2504), Network: 3Com ETHERLINK III (3C509B) */ + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_phoenix_trio64vplus_onboard_pci_device, + .snd_device = &sb_vibra16s_onboard_device, + .net_device = NULL /* not yet emulated */ + }, + /* 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 = "[i430FX] Intel Advanced/ZP (Zappa)", + .internal_name = "zappa", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_zappa_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* The BIOS sends KBC command B3 which indicates an AMI (or VIA VT82C42N) KBC. */ + { + .name = "[i430FX] NEC PowerMate V", + .internal_name = "powermatev", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_powermatev_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey Z(!) KBC firmware. */ + { + .name = "[i430FX] TriGem Hawk", + .internal_name = "hawk", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_hawk_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* KBC On-Chip the VT82C406MV. */ + { + .name = "[i430FX] FIC PT-2000", + .internal_name = "pt2000", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_pt2000_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* OPTi 596/597 */ + /* This uses an AMI KBC firmware in PS/2 mode (it sends command A5 with the + PS/2 "Load Security" meaning), most likely MegaKey as it sends command AF + (Set Extended Controller RAM) just like the later Intel AMI BIOS'es. */ + { + .name = "[OPTi 597] TMC PAT54PV", + .internal_name = "pat54pv", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_OPTI_547_597, + .init = machine_at_pat54pv_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_APM, + .ram = { + .min = 2048, + .max = 65536, + .step = 2048 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* OPTi 596/597/822 */ + { + .name = "[OPTi 597] Shuttle HOT-543", + .internal_name = "hot543", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_OPTI_547_597, + .init = machine_at_hot543_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PCIV, + .flags = MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[OPTi 597] Northgate Computer Systems Elegance Pentium 90", + .internal_name = "ncselp90", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_OPTI_547_597, + .init = machine_at_ncselp90_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCIV, + .flags = MACHINE_APM | MACHINE_IDE_DUAL | MACHINE_SUPER_IO, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* SiS 85C50x */ + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[SiS 501] ASUS PCI/I-P54SP4", + .internal_name = "p54sp4", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_SIS_501, + .init = machine_at_p54sp4_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86), + .min_bus = 40000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[SiS 501] BCM SQ-588", + .internal_name = "sq588", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_SIS_501, + .init = machine_at_sq588_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_PENTIUMMMX), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This machine has a Winbond W83C842 KBC */ + { + .name = "[SiS 501] Gemlight GMB-P54SPS", + .internal_name = "p54sps", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_SIS_501, + .init = machine_at_p54sps_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + CPU_BLOCK(CPU_PENTIUMMMX), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = &kbc_at_ami_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[SiS 5501] MSI MS-5109", + .internal_name = "ms5109", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_SIS_5501, + .init = machine_at_ms5109_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + CPU_BLOCK(CPU_PENTIUMMMX), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey Z(!) KBC firmware. */ + { + .name = "[SiS 5501] TriGem Torino", + .internal_name = "torino", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_SIS_5501, + .init = machine_at_torino_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + CPU_BLOCK(CPU_PENTIUMMMX), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3520, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 1.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &tgui9660_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + + /* UMC 889x */ + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[UMC 889x] Shuttle HOT-539", + .internal_name = "hot539", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_UMC_UM8890BF, + .init = machine_at_hot539_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86), + .min_bus = 40000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3600, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* Socket 7 (Single Voltage) machines */ + /* 430FX */ + /* This has an AMIKey-2, which is an updated version of type 'H'. + This also seems to be revision 2.1 with the FDC37C665 SIO. */ + { + .name = "[i430FX] ASUS P/I-P55TP4XE", + .internal_name = "p54tp4xe", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_p54tp4xe_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 = 3600, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[i430FX] ASUS P/I-P55TP4XE (MR BIOS)", + .internal_name = "p54tp4xe_mr", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_p54tp4xe_mr_init, + .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 = 3600, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey H KBC firmware. The KBC itself seems to differ between an AMIKEY-2 and a Winbond W83C42. */ + { + .name = "[i430FX] DataExpert EXP8551", + .internal_name = "exp8551", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_exp8551_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .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 . */ + { + .name = "[i430FX] Gateway 2000 Thor", + .internal_name = "gw2katx", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_gw2katx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), + .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_GAMEPORT, /* Machine has optional onboard sound: Crystal CS4232-KQ */ + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C932 Super I/O chip with on-chip KBC with AMI + MegaKey (revision '5') KBC firmware. */ + { + .name = "[i430FX] HP Vectra VL 5 Series 4", + .internal_name = "vectra54", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_vectra54_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_phoenix_trio64_onboard_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 . */ + { + .name = "[i430FX] Intel Advanced/ATX (Thor)", + .internal_name = "thor", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_thor_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), + .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_VIDEO | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has optional onboard sound: Crystal CS4232-KQ */ + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_phoenix_trio64vplus_onboard_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 . */ + { + .name = "[i430FX] Intel Advanced/ATX (Thor) (MR BIOS)", + .internal_name = "mrthor", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_mrthor_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_GAMEPORT, /* Machine has optional onboard video: S3 Trio64V+ and optional onboard sound: Crystal CS4232-KQ */ + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .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 . */ + { + .name = "[i430FX] Intel Advanced/EV (Endeavor)", + .internal_name = "endeavor", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_endeavor_init, + .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(CPU_K5, CPU_5K86, CPU_Cx6x86), + .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_VIDEO | MACHINE_SOUND | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_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'. */ + { + .name = "[i430FX] MSI MS-5119", + .internal_name = "ms5119", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_ms5119_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 = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This most likely uses AMI MegaKey KBC firmware as well due to having the same + Super I/O chip (that has the KBC firmware on it) as eg. the Advanced/EV. */ + { + .name = "[i430FX] Packard Bell PB640", + .internal_name = "pb640", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_pb640_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), + .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_VIDEO | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5440_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a VIA VT82C42N KBC. */ + { + .name = "[i430FX] PC Partner MB500N", + .internal_name = "mb500n", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_mb500n_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has an AMI MegaKey 'H' KBC firmware (1992). */ + { + .name = "[i430FX] QDI FMB", + .internal_name = "fmb", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_fmb_init, + .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), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 430HX */ + /* Has SST Flash. */ + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ + { + .name = "[i430HX] Acer V35N", + .internal_name = "acerv35n", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_acerv35n_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 = 3450, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 4096, + .max = 524288, + .step = 4096 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey-2 or VIA VT82C42N KBC (depending on the revision) with AMIKEY 'F' KBC firmware. */ + { + .name = "[i430HX] AOpen AP53", + .internal_name = "ap53", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_ap53_init, + .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 = 3450, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 4096, + .max = 524288, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* [TEST] Has a VIA 82C42N KBC, with AMIKey F KBC firmware. */ + { + .name = "[i430HX] Biostar MB-8500TUC", + .internal_name = "8500tuc", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_8500tuc_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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 4096, + .max = 524288, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + { + .name = "[i430HX] Siemens-Nixdorf D943", + .internal_name = "d943", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_d943_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_AV | MACHINE_GAMEPORT | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 4096 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &d943_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5436_onboard_pci_device, + .snd_device = &sb_vibra16c_onboard_device, + .net_device = NULL + }, + + /* 430VX */ + /* Has a SM(S)C FDC37C932FR Super I/O chip with on-chip KBC with AMI + MegaKey (revision '5') KBC firmware. */ + { + .name = "[i430VX] Gateway 2000 Mailman", + .internal_name = "gw2kma", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_gw2kma_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), + .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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal video: ATI Mach64GT-B 3D Rage II */ + .ram = { + .min = 8192, + .max = 131072, + .step = 4096 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &sb_vibra16c_onboard_device, + .net_device = NULL + }, + + /* SiS 5501 */ + /* Has the Lance LT38C41 KBC. */ + { + .name = "[SiS 5501] Chaintech 5SBM/5SBM2 (M103)", + .internal_name = "5sbm2", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_SIS_5501, + .init = machine_at_5sbm2_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &c5sbm2_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* SiS 5511 */ + /* Has AMIKey H KBC firmware (AMIKey-2). */ + { + .name = "[SiS 5511] AOpen AP5S", + .internal_name = "ap5s", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_SIS_5511, + .init = machine_at_ap5s_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &ap5s_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has an SMC FDC37C669QF Super I/O. */ + { + .name = "[SiS 5511] IBM PC 140 (type 6260)", + .internal_name = "pc140_6260", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_SIS_5511, + .init = machine_at_pc140_6260_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, CPU_Cx6x86, CPU_Cx6x86L, CPU_Cx6x86MX, CPU_PENTIUMMMX), + .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_VIDEO | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5436_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey H KBC firmware (AMIKey-2). */ + { + .name = "[SiS 5511] MSI MS-5124", + .internal_name = "ms5124", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_SIS_5511, + .init = machine_at_ms5124_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has Megakey 'R' KBC */ + { + .name = "[SiS 5511] AMI Atlas PCI-II", + .internal_name = "amis727", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_SIS_5511, + .init = machine_at_amis727_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* Socket 7 (Dual Voltage) machines */ + /* 430HX */ + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ + { + .name = "[i430HX] Acer AcerPower Ultima", + .internal_name = "acerm3a", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_acerm3a_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_Cx6x86MX), + .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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal SCSI */ + .ram = { + .min = 4096, + .max = 524288, + .step = 4096 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_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 = "[i430HX] ASUS P/I-P55T2P4", + .internal_name = "p55t2p4", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_p55t2p4_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 = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 4.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 4096, + .max = 524288, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* The base board has a Holtek HT6542B with the AMIKey-2 (updated 'H') KBC firmware. */ + { + .name = "[i430HX] ASUS P/I-P65UP5 (C-P55T2D)", + .internal_name = "p65up5_cp55t2d", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_p65up5_cp55t2d_init, + .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 = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Machine has AMB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 4096, + .max = 524288, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ + { + .name = "[i430HX] Micronics M7S-Hi", + .internal_name = "m7shi", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_m7shi_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 4096, + .max = 524288, + .step = 4096 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .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 . */ + { + .name = "[i430HX] Intel TC430HX (Tucson)", + .internal_name = "tc430hx", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_tc430hx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, + CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal sound: Yamaha YMF701-S */ + .ram = { + .min = 8192, + .max = 524288, + .step = 4096 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_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. */ + { + .name = "[i430HX] Toshiba Infinia 7201", + .internal_name = "infinia7200", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_infinia7200_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, + CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal sound: Yamaha YMF701-S */ + .ram = { + .min = 8192, + .max = 524288, + .step = 4096 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_virge_375_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* OEM-only Intel CU430HX, has AMI MegaKey KBC firmware on the PC87306 Super I/O chip. */ + { + .name = "[i430HX] Intel CU430HX (Cumberland)", + .internal_name = "cu430hx", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_cu430hx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, + CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_USB, /* Machine has internal video: ATI Mach64GT 3D Rage and internal NIC: Intel 82557 */ + .ram = { + .min = 8192, + .max = 524288, + .step = 4096 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &sb_vibra16c_onboard_device, + .net_device = NULL + }, + /* OEM-only Intel CU430HX, has AMI MegaKey KBC firmware on the PC87306 Super I/O chip. */ + { + .name = "[i430HX] Toshiba Equium 5200D", + .internal_name = "equium5200", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_equium5200_init, + .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, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, + CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_USB, /* Machine has internal video: ATI Mach64GT 3D Rage and internal NIC: Intel 82557 */ + .ram = { + .min = 8192, + .max = 524288, + .step = 4096 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &sb_vibra16c_onboard_device, + .net_device = NULL + }, + /* Unknown PS/2 KBC. */ + { + .name = "[i430HX] Radisys EPC-2102", + .internal_name = "epc2102", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_epc2102_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 4096, + .max = 524288, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .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 . + Yes, this is an Intel AMI BIOS with a fancy splash screen. */ + { + .name = "[i430HX] Sony Vaio PCV-90", + .internal_name = "pcv90", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_pcv90_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, + CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), + .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_APM, /* Machine has internal video: ATI Mach64GT-B 3D Rage II */ + .ram = { + .min = 8192, + .max = 524288, + .step = 4096 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* [TEST] The board doesn't seem to have a KBC at all, which probably means it's an on-chip one on the PC87306 SIO. + A list on a Danish site shows the BIOS as having a -0 string, indicating non-AMI KBC firmware. */ + { + .name = "[i430HX] Supermicro P55T2S", + .internal_name = "p55t2s", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_p55t2s_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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 4096, + .max = 524288, + .step = 4096 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 430VX */ + /* This has the VIA VT82C42N or Holtek HT6542B KBC. */ + { + .name = "[i430VX] AOpen AP5VM", + .internal_name = "ap5vm", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_ap5vm_init, + .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 = 2600, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 4096, + .max = 131072, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has AMIKey H KBC firmware (AMIKey-2) on a BestKey KBC. */ + { + .name = "[i430VX] ASUS P/I-P55TVP4", + .internal_name = "p55tvp4", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_p55tvp4_init, + .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 = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Machine has AMB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 4096, + .max = 131072, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* The BIOS does not send a single non-standard KBC command, so it must have a standard IBM + PS/2 KBC firmware or a clone thereof. */ + { + .name = "[i430VX] Azza PT-5IV", + .internal_name = "5ivg", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_5ivg_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 = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 4096, + .max = 131072, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* [TEST] Has AMIKey 'F' KBC firmware on a VIA VT82C42N KBC. */ + { + .name = "[i430VX] Biostar MB-8500TVX-A", + .internal_name = "8500tvxa", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_8500tvxa_init, + .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 = 2600, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 4096, + .max = 131072, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C932QF Super I/O chip with on-chip KBC with AMI + MegaKey (revision '5') KBC firmware. */ + { + .name = "[i430VX] Compaq Presario 224x", + .internal_name = "presario2240", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_presario2240_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 16384, + .max = 49152, + .step = 4096 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_trio64v2_dx_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C931APM Super I/O chip with on-chip KBC with Compaq + KBC firmware. */ + { + .name = "[i430VX] Compaq Presario 45xx", + .internal_name = "presario4500", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_presario4500_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 16384, + .max = 49152, + .step = 4096 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_trio64v2_dx_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C932FR Super I/O chip with on-chip KBC with AMI + MegaKey (revision '5') KBC firmware. */ + { + .name = "[i430VX] Dell Dimension XPS Pxxxa/Mxxxa", + .internal_name = "dellhannibalp", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_dellhannibalp_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, + CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal video: S3 Trio64V+ */ + .ram = { + .min = 8192, + .max = 131072, + .step = 4096 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_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, + .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 = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 4096, + .max = 131072, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C932FR Super I/O chip with on-chip KBC with AMI + MegaKey (revision '5') KBC firmware. */ + { + .name = "[i430VX] Epox P55-VA", + .internal_name = "p55va", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_p55va_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 75000000, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 4096, + .max = 131072, + .step = 4096 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C932FR Super I/O chip with on-chip KBC with AMI + MegaKey (revision '5') KBC firmware. */ + { + .name = "[i430VX] Gateway 2000 Hitman", + .internal_name = "gw2kte", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_gw2kte_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, + CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 2200, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal video: S3 Trio64V+ */ + .ram = { + .min = 8192, + .max = 131072, + .step = 4096 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &sb_vibra16c_onboard_device, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ + { + .name = "[i430VX] HP Brio 80xx", + .internal_name = "brio80xx", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_brio80xx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 2200, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal video: S3 Trio64V2/DX */ + .ram = { + .min = 8192, + .max = 131072, + .step = 4096 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .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 . */ + { + .name = "[i430VX] Packard Bell Multimedia C110 (PB680/PB682/PB685)", + .internal_name = "pb680", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_pb680_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, + CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), + .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 | MACHINE_BUS_USB, + .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 131072, + .step = 4096 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_phoenix_trio64vplus_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ + { + .name = "[i430VX] Packard Bell Multimedia M415 (PB810)", + .internal_name = "pb810", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_pb810_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 = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 4.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM, /* Machine has internal video: S3 Trio64V2/DX */ + .ram = { + .min = 4096, + .max = 131072, + .step = 4096 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the AMIKey 'H' firmware, possibly AMIKey-2. Photos show it with a BestKey, so it + likely clones the behavior of AMIKey 'H'. */ + { + .name = "[i430VX] PC Partner MB520N", + .internal_name = "mb520n", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_mb520n_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 = 2600, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 4096, + .max = 131072, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has a Holtek KBC and the BIOS does not send a single non-standard KBC command, so it + must be an ASIC that clones the standard IBM PS/2 KBC. */ + { + .name = "[i430VX] Shuttle HOT-557", + .internal_name = "430vx", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_i430vx_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 = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_GAMEPORT | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 4096, + .max = 131072, + .step = 4096 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 430TX */ + /* The BIOS sends KBC command B8, CA, and CB, so it has an AMI KBC firmware. */ + { + .name = "[i430TX] ADLink NuPRO-591/592", + .internal_name = "nupro592", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_nupro592_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 1900, + .max_voltage = 2800, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &chips_69000_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the AMIKey KBC firmware, which is an updated 'F' type (YM430TX is based on the TX97). */ + { + .name = "[i430TX] ASUS TX97", + .internal_name = "tx97", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_tx97_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 = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* + According to Dell specifications, it can have either National Semiconductor + PC87307 or PC87309 Super I/O. All known instances have the former, although + other similar Dells of the era have pinouts for accompanying either so this + likely also does. + + The KBC is either an AMI '5' MegaKey, Phoenix MultiKey/42 1.37, or Phoenix + MultiKey/42i 4.16. + */ + { + .name = "[i430TX] Dell OptiPlex GN+", + .internal_name = "optiplexgn", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_optiplexgn_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 = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI, + /* Video: S3 86C785 (Trio64V2/GX), ethernet: 3C905. */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO | MACHINE_SOUND, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + /* Stop-gap measure until the Trio64V2/GX is emulated, as both use the same VBIOS. */ + .vid_device = &s3_trio64v2_dx_onboard_pci_device, + .snd_device = &sb_vibra16xv_onboard_device, + .net_device = NULL + }, + /* [TEST] Has AMI Megakey '5' KBC firmware on the SM(S)C FDC37C67x Super I/O chip. */ + { + .name = "[i430TX] Gateway E-1000", + .internal_name = "tomahawk", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_tomahawk_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_NIC | MACHINE_USB, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_trio64v2_dx_onboard_pci_device, + .snd_device = &cs4236b_device, + .net_device = &pcnet_am79c973_onboard_device + }, + /* This has the AMIKey KBC firmware, which is an updated 'F' type. */ + { + .name = "[i430TX] Intel YM430TX (Yamamoto)", + .internal_name = "ym430tx", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_ym430tx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, + CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 4096, + .max = 262144, + .step = 4096 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_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, has onboard Yamaha YMF701 which + is not emulated yet. + + Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. + */ + { + .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 = 60000000, + .max_bus = 66666667, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + /* Machine has internal sound: Yamaha YMF701-S */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C67x Super I/O chip with on-chip KBC with Phoenix or + AMIKey-2 KBC firmware. */ + { + .name = "[i430TX] NEC Mate NX MA23C", + .internal_name = "ma23c", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_ma23c_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2700, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal video: Cirrus Logic CL-GD5465 and internal sound: Yamaha YMF715 */ + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has the Phoenix MultiKey KBC firmware. */ + { + .name = "[i430TX] Packard Bell PB790", + .internal_name = "an430tx", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_an430tx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, + CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, /* Machine has internal video: ATI Mach64GT-B 3D Rage II */ + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* The BIOS sends KBC command BB and expects it to output a byte, which is AMI KBC behavior. + A picture shows a VIA VT82C42N KBC though, so it could be a case of that KBC with AMI firmware. */ + { + .name = "[i430TX] PC Partner MB540N", + .internal_name = "mb540n", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_mb540n_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2700, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 4096, + .max = 262144, + .step = 4096 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Award BIOS, PS2, EDO, SDRAM, 4 PCI, 4 ISA, VIA VT82C42N KBC */ + { + .name = "[i430TX] Soltek SL-56A5", + .internal_name = "56a5", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_56a5_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 4096, + .max = 262144, + .step = 4096 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* [TEST] Has AMIKey 'H' KBC firmware. */ + { + .name = "[i430TX] Supermicro P5MMS98", + .internal_name = "p5mms98", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_p5mms98_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 = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 4096, + .max = 262144, + .step = 4096 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* [TEST] Has AMIKey 'H' KBC firmware. */ + { + .name = "[i430TX] TriGem RD535 (Richmond)", + .internal_name = "richmond", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_richmond_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* Apollo VPX */ + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA VPX] FIC VA-502", + .internal_name = "ficva502", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_VPX, + .init = machine_at_ficva502_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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* Apollo VP3 */ + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA VP3] FIC PA-2012", + .internal_name = "ficpa2012", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_VP3, + .init = machine_at_ficpa2012_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 = 75000000, + .min_voltage = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA VP3] PC Partner VIA809DS", + .internal_name = "via809ds", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_VP3, + .init = machine_at_via809ds_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 = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* SiS 5571 */ + /* Has the SiS 5571 chipset with on-chip KBC. */ + { + .name = "[SiS 5571] Daewoo CD520", + .internal_name = "cb52xsi", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5571, + .init = machine_at_cb52xsi_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 75000000, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 393216, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* SiS 5581 */ + /* Has the SiS 5581 chipset with on-chip KBC. */ + { + .name = "[SiS 5581] ASUS SP97-XV", + .internal_name = "sp97xv", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5581, + .init = machine_at_sp97xv_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 75000000, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the SiS 5581 chipset with on-chip KBC. */ + { + .name = "[SiS 5581] BCM SQ-578", + .internal_name = "sq578", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5581, + .init = machine_at_sq578_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 75000000, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* SiS 5591 */ + /* Has the SiS 5591 chipset with on-chip KBC. */ + { + .name = "[SiS 5591] MSI MS-5172", + .internal_name = "ms5172", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_SIS_5591, + .init = machine_at_ms5172_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 75000000, + .min_voltage = 2500, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* ALi ALADDiN IV+ */ + /* Has the ALi M1543 southbridge with on-chip KBC. */ + { + .name = "[ALi ALADDiN IV+] Biostar M5ATA", + .internal_name = "m5ata", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, + .init = machine_at_m5ata_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 4.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_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, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 83333333, + .min_voltage = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_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 = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* Super Socket 7 machines */ + /* ALi ALADDiN V */ + /* Has the ALi M1543C southbridge with on-chip KBC. */ + { + .name = "[ALi ALADDiN V] ASUS P5A", + .internal_name = "p5a", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, + .init = machine_at_p5a_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 120000000, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: ESS Solo-1 */ + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Is the exact same as the Matsonic MS6260S. Has the ALi M1543C southbridge + with on-chip KBC. */ + { + .name = "[ALi ALADDiN V] PC Chips M579", + .internal_name = "m579", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, + .init = machine_at_m579_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: C-Media CMI8330 */ + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* M1534c kbc */ + { + .name = "[ALi ALADDiN V] Gateway Lucas", + .internal_name = "gwlucas", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, + .init = machine_at_gwlucas_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_PCIONLY | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal video: ATI 3D Rage Pro Turbo AGP and sound: Ensoniq ES1373 */ + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &es1373_onboard_device, + .net_device = NULL + }, + /* Has the ALi M1543C southbridge with on-chip KBC. */ + { + .name = "[ALi ALADDiN V] Gigabyte GA-5AA", + .internal_name = "5aa", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, + .init = machine_at_5aa_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 140000000, + .min_voltage = 1300, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the ALi M1543C southbridge with on-chip KBC. */ + { + .name = "[ALi ALADDiN V] Gigabyte GA-5AX", + .internal_name = "5ax", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, + .init = machine_at_5ax_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 140000000, + .min_voltage = 1300, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* Apollo MVP3 */ + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA MVP3] AOpen AX59 Pro", + .internal_name = "ax59pro", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, + .init = machine_at_ax59pro_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 124242424, + .min_voltage = 1300, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA MVP3] FIC VA-503+", + .internal_name = "ficva503p", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, + .init = machine_at_mvp3_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 124242424, + .min_voltage = 2000, + .max_voltage = 3200, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the VIA VT82C686A southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA MVP3] FIC VA-503A", + .internal_name = "ficva503a", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, + .init = machine_at_ficva503a_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 124242424, + .min_voltage = 1800, + .max_voltage = 3100, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_A97 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the VIA VT82C686A southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA MVP3] Soyo 5EMA PRO", + .internal_name = "5emapro", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, + .init = machine_at_5emapro_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 124242424, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the VIA VT82C596A southbridge with on-chip KBC identical to the VIA + VT82C42N. Sadly likely abuses cache on Cyrix 6x86MX and MII CPUs (Cyrix MII being what most socket 7 eMachines PCs used) , so they are blocked and it's thus named after the only known eMachines with an AMD K6-2 CPU here */ + { + .name = "[VIA MVP3] eMachines eTower 300k", + .internal_name = "delhi3", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, + .init = machine_at_delhi3_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_Cx6x86MX), + .min_bus = 66666667, + .max_bus = 124242424, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Has internal video: ATI 3D Rage IIc AGP (Rage 2) */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_SOUND | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &cs4235_onboard_device, + .net_device = NULL + }, + + /* SiS 5591 */ + /* Has the SiS 5591 chipset with on-chip KBC. */ + { + .name = "[SiS 5591] Gigabyte GA-5SG100", + .internal_name = "5sg100", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_SIS_5591, + .init = machine_at_5sg100_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 100000000, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* Socket 8 machines */ + /* 450KX */ + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[i450KX] AOpen AP61", + .internal_name = "ap61", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_450KX, + .init = machine_at_ap61_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET8, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { + .name = "[i450KX] ASUS P/I-P6RP4", + .internal_name = "p6rp4", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_450KX, + .init = machine_at_p6rp4_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET8, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 440FX */ + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ + { + .name = "[i440FX] Acer V60N", + .internal_name = "acerv60n", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_acerv60n_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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 393216, + .step = 8192 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* The base board has a Holtek HT6542B with AMIKey-2 (updated 'H') KBC firmware. */ + { + .name = "[i440FX] ASUS P/I-P65UP5 (C-P6ND)", + .internal_name = "p65up5_cp6nd", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_p65up5_cp6nd_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET8, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Machine has AMB */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a VIA VT82C42N with likely AMIKey 'F' KBC firmware. */ + { + .name = "[i440FX] Biostar MB-8600TTC", + .internal_name = "8600ttc", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_8600ttc_init, + .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 = 50000000, + .max_bus = 66666667, + .min_voltage = 2900, + .max_voltage = 3300, + .min_multi = 2.0, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* It's an Intel VS440FX with a Dell OEM BIOS */ + { + .name = "[i440FX] Dell Dimension XPS Pro___n", + .internal_name = "dellvenus", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_dellvenus_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 | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, - .ram = { - .min = 8192, - .max = 131072, - .step = 4096 - }, - .nvrmask = 511, - .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 - }, - - /* SiS 5501 */ - /* Has the Lance LT38C41 KBC. */ - { - .name = "[SiS 5501] Chaintech 5SBM2 (M103)", - .internal_name = "5sbm2", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_SIS_5501, - .init = machine_at_5sbm2_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 262144, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* SiS 5511 */ - /* Has AMIKey H KBC firmware (AMIKey-2). */ - { - .name = "[SiS 5511] AOpen AP5S", - .internal_name = "ap5s", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_SIS_5511, - .init = machine_at_ap5s_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 524288, - .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 an SMC FDC37C669QF Super I/O. */ - { - .name = "[SiS 5511] IBM PC 140 (type 6260)", - .internal_name = "pc140_6260", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_SIS_5511, - .init = machine_at_pc140_6260_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, CPU_Cx6x86, CPU_Cx6x86L, CPU_Cx6x86MX, CPU_PENTIUMMMX), - .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_VIDEO | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &gd5436_onboard_pci_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey H KBC firmware (AMIKey-2). */ - { - .name = "[SiS 5511] MSI MS-5124", - .internal_name = "ms5124", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_SIS_5511, - .init = machine_at_ms5124_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has Megakey 'R' KBC */ - { - .name = "[SiS 5511] AMI Atlas PCI-II", - .internal_name = "amis727", - .type = MACHINE_TYPE_SOCKET7_3V, - .chipset = MACHINE_CHIPSET_SIS_5511, - .init = machine_at_amis727_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 3380, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* Socket 7 (Dual Voltage) machines */ - /* 430HX */ - /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix - MultiKey/42 (version 1.38) KBC firmware. */ - { - .name = "[i430HX] Acer AcerPower Ultima", - .internal_name = "acerm3a", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_acerm3a_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_Cx6x86MX), - .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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal SCSI */ - .ram = { - .min = 4096, - .max = 524288, - .step = 4096 - }, - .nvrmask = 511, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey H KBC firmware (AMIKey-2). */ - { - .name = "[i430HX] ASUS P/I-P55T2P4", - .internal_name = "p55t2p4", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_p55t2p4_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 75000000, - .min_voltage = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 4.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 4096, - .max = 524288, - .step = 4096 - }, - .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 - }, - /* The base board has a Holtek HT6542B with the AMIKey-2 (updated 'H') KBC firmware. */ - { - .name = "[i430HX] ASUS P/I-P65UP5 (C-P55T2D)", - .internal_name = "p65up5_cp55t2d", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_p65up5_cp55t2d_init, - .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 = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Machine has AMB */ - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 4096, - .max = 524288, - .step = 4096 - }, - .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 a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix - MultiKey/42 (version 1.38) KBC firmware. */ - { - .name = "[i430HX] Micronics M7S-Hi", - .internal_name = "m7shi", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_m7shi_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2800, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, - .ram = { - .min = 4096, - .max = 524288, - .step = 4096 - }, - .nvrmask = 511, - .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 - }, - /* 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 = "[i430HX] Intel TC430HX (Tucson)", - .internal_name = "tc430hx", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_tc430hx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, - CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 2800, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal sound: Yamaha YMF701-S */ - .ram = { - .min = 8192, - .max = 524288, - .step = 4096 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_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. */ - { - .name = "[i430HX] Toshiba Infinia 7201", - .internal_name = "infinia7200", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_infinia7200_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, - CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 2800, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal sound: Yamaha YMF701-S */ - .ram = { - .min = 8192, - .max = 524288, - .step = 4096 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &s3_virge_375_pci_device, - .snd_device = NULL, - .net_device = NULL - }, - /* OEM-only Intel CU430HX, has AMI MegaKey KBC firmware on the PC87306 Super I/O chip. */ - { - .name = "[i430HX] Intel CU430HX (Cumberland)", - .internal_name = "cu430hx", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_cu430hx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, - CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 2800, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 4096 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = &sb_vibra16c_onboard_device, - .net_device = NULL - }, - /* OEM-only Intel CU430HX, has AMI MegaKey KBC firmware on the PC87306 Super I/O chip. */ - { - .name = "[i430HX] Toshiba Equium 5200D", - .internal_name = "equium5200", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_equium5200_init, - .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, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, - CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 2800, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 4096 - }, - .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 - }, - /* Unknown PS/2 KBC. */ - { - .name = "[i430HX] Radisys EPC-2102", - .internal_name = "epc2102", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_epc2102_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 4096, - .max = 524288, - .step = 4096 - }, - .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 - }, - /* 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 . - Yes, this is an Intel AMI BIOS with a fancy splash screen. */ - { - .name = "[i430HX] Sony Vaio PCV-90", - .internal_name = "pcv90", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_pcv90_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, - CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), - .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_APM, - .ram = { - .min = 8192, - .max = 524288, - .step = 4096 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* [TEST] The board doesn't seem to have a KBC at all, which probably means it's an on-chip one on the PC87306 SIO. - A list on a Danish site shows the BIOS as having a -0 string, indicating non-AMI KBC firmware. */ - { - .name = "[i430HX] Supermicro P55T2S", - .internal_name = "p55t2s", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_p55t2s_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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 4096, - .max = 524288, - .step = 4096 - }, - .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 - }, - - /* 430VX */ - /* This has the VIA VT82C42N or Holtek HT6542B KBC. */ - { - .name = "[i430VX] AOpen AP5VM", - .internal_name = "ap5vm", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_ap5vm_init, - .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 = 2600, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 4096, - .max = 131072, - .step = 4096 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey H KBC firmware (AMIKey-2) on a BestKey KBC. */ - { - .name = "[i430VX] ASUS P/I-P55TVP4", - .internal_name = "p55tvp4", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_p55tvp4_init, - .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 = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Machine has AMB */ - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 4096, - .max = 131072, - .step = 4096 - }, - .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 - }, - /* The BIOS does not send a single non-standard KBC command, so it must have a standard IBM - PS/2 KBC firmware or a clone thereof. */ - { - .name = "[i430VX] Azza PT-5IV", - .internal_name = "5ivg", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_5ivg_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 = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 4096, - .max = 131072, - .step = 4096 - }, - .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 - }, - /* [TEST] Has AMIKey 'F' KBC firmware on a VIA VT82C42N KBC. */ - { - .name = "[i430VX] Biostar MB-8500TVX-A", - .internal_name = "8500tvxa", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_8500tvxa_init, - .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 = 2600, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 4096, - .max = 131072, - .step = 4096 - }, - .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 a SM(S)C FDC37C932QF Super I/O chip with on-chip KBC with AMI - MegaKey (revision '5') KBC firmware. */ - { - .name = "[i430VX] Compaq Presario 224x", - .internal_name = "presario2240", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_presario2240_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 66666667, - .min_voltage = 2800, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, - .ram = { - .min = 16384, - .max = 49152, - .step = 4096 - }, - .nvrmask = 511, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &s3_trio64v2_dx_onboard_pci_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a SM(S)C FDC37C931APM Super I/O chip with on-chip KBC with Compaq - KBC firmware. */ - { - .name = "[i430VX] Compaq Presario 45xx", - .internal_name = "presario4500", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_presario4500_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 66666667, - .min_voltage = 2800, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, - .ram = { - .min = 16384, - .max = 49152, - .step = 4096 - }, - .nvrmask = 511, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &s3_trio64v2_dx_onboard_pci_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a SM(S)C FDC37C932FR Super I/O chip with on-chip KBC with AMI - MegaKey (revision '5') KBC firmware. */ - { - .name = "[i430VX] Dell Dimension XPS Pxxxa/Mxxxa", - .internal_name = "dellhannibalp", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_dellhannibalp_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, - CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 131072, - .step = 4096 - }, - .nvrmask = 511, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has AMIKey H KBC firmware (AMIKey-2). */ - { - .name = "[i430VX] ECS P5VX-B", - .internal_name = "p5vxb", - .type = MACHINE_TYPE_SOCKET7, - .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 = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 4096, - .max = 131072, - .step = 4096 - }, - .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 a SM(S)C FDC37C932FR Super I/O chip with on-chip KBC with AMI - MegaKey (revision '5') KBC firmware. */ - { - .name = "[i430VX] Epox P55-VA", - .internal_name = "p55va", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_p55va_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 75000000, - .min_voltage = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 4096, - .max = 131072, - .step = 4096 - }, - .nvrmask = 511, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a SM(S)C FDC37C932FR Super I/O chip with on-chip KBC with AMI - MegaKey (revision '5') KBC firmware. */ - { - .name = "[i430VX] Gateway 2000 Hitman", - .internal_name = "gw2kte", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_gw2kte_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, - CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), - .min_bus = 50000000, - .max_bus = 66666667, - .min_voltage = 2200, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, - .ram = { - .min = 8192, - .max = 131072, - .step = 4096 - }, - .nvrmask = 511, - .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 - }, - /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix - MultiKey/42 (version 1.38) KBC firmware. */ - { - .name = "[i430VX] HP Brio 80xx", - .internal_name = "brio80xx", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_brio80xx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 66666667, - .min_voltage = 2200, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, - .step = 4096 - }, - .nvrmask = 511, - .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 - }, - /* 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] Packard Bell Multimedia C110", - .internal_name = "pb680", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_pb680_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, - CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), - .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 | MACHINE_BUS_USB, - .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 131072, - .step = 4096 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &s3_phoenix_trio64vplus_onboard_pci_device, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix - MultiKey/42 (version 1.38) KBC firmware. */ - { - .name = "[i430VX] Packard Bell Multimedia M415", - .internal_name = "pb810", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_pb810_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 = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 4.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM, - .ram = { - .min = 4096, - .max = 131072, - .step = 4096 - }, - .nvrmask = 511, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has the AMIKey 'H' firmware, possibly AMIKey-2. Photos show it with a BestKey, so it - likely clones the behavior of AMIKey 'H'. */ - { - .name = "[i430VX] PC Partner MB520N", - .internal_name = "mb520n", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_mb520n_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 = 2600, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 4096, - .max = 131072, - .step = 4096 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has a Holtek KBC and the BIOS does not send a single non-standard KBC command, so it - must be an ASIC that clones the standard IBM PS/2 KBC. */ - { - .name = "[i430VX] Shuttle HOT-557", - .internal_name = "430vx", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_i430vx_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 = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_GAMEPORT | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 4096, - .max = 131072, - .step = 4096 - }, - .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 - }, - - /* 430TX */ - /* The BIOS sends KBC command B8, CA, and CB, so it has an AMI KBC firmware. */ - { - .name = "[i430TX] ADLink NuPRO-591/592", - .internal_name = "nupro592", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_nupro592_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 66666667, - .min_voltage = 1900, - .max_voltage = 2800, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO, - .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 = &chips_69000_onboard_device, - .snd_device = NULL, - .net_device = NULL - }, - /* This has the AMIKey KBC firmware, which is an updated 'F' type (YM430TX is based on the TX97). */ - { - .name = "[i430TX] ASUS TX97", - .internal_name = "tx97", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_tx97_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 75000000, - .min_voltage = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 262144, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* [TEST] Has AMI Megakey '5' KBC firmware on the SM(S)C FDC37C67x Super I/O chip. */ - { - .name = "[i430TX] Gateway E-1000", - .internal_name = "tomahawk", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_tomahawk_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2100, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_NIC | MACHINE_USB, - .ram = { - .min = 8192, - .max = 262144, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &s3_trio64v2_dx_onboard_pci_device, - .snd_device = &cs4236b_device, - .net_device = &pcnet_am79c973_onboard_device - }, -#ifdef USE_AN430TX - /* This has the Phoenix MultiKey KBC firmware. */ - { - .name = "[i430TX] Intel AN430TX (Anchorage)", - .internal_name = "an430tx", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_an430tx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, - CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2800, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .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 - }, -#endif /* USE_AN430TX */ - /* This has the AMIKey KBC firmware, which is an updated 'F' type. */ - { - .name = "[i430TX] Intel YM430TX (Yamamoto)", - .internal_name = "ym430tx", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_ym430tx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, - CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2800, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 4096, - .max = 262144, - .step = 4096 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* PhoenixBIOS 4.0 Rel 6.0 for 430TX, has onboard Yamaha YMF701 which is not emulated yet. */ - /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix - MultiKey/42 (version 1.38) KBC firmware. */ - { - .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 = 60000000, - .max_bus = 66666667, - .min_voltage = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Yamaha YMF701-S */ - .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 a SM(S)C FDC37C67x Super I/O chip with on-chip KBC with Phoenix or - AMIKey-2 KBC firmware. */ - { - .name = "[i430TX] NEC Mate NX MA23C", - .internal_name = "ma23c", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_ma23c_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2700, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 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 - }, - /* The BIOS sends KBC command BB and expects it to output a byte, which is AMI KBC behavior. - A picture shows a VIA VT82C42N KBC though, so it could be a case of that KBC with AMI firmware. */ - { - .name = "[i430TX] PC Partner MB540N", - .internal_name = "mb540n", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_mb540n_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2700, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 4096, - .max = 262144, - .step = 4096 - }, - .nvrmask = 255, - .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 - }, - /* Award BIOS, PS2, EDO, SDRAM, 4 PCI, 4 ISA, VIA VT82C42N KBC */ - { - .name = "[i430TX] Soltek SL-56A5", - .internal_name = "56a5", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_56a5_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2800, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 4096, - .max = 262144, - .step = 4096 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* [TEST] Has AMIKey 'H' KBC firmware. */ - { - .name = "[i430TX] Supermicro P5MMS98", - .internal_name = "p5mms98", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_p5mms98_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 = 2100, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 4096, - .max = 262144, - .step = 4096 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* [TEST] Has AMIKey 'H' KBC firmware. */ - { - .name = "[i430TX] TriGem RD535 (Richmond)", - .internal_name = "richmond", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_richmond_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2100, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 262144, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* Apollo VPX */ - /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA VPX] FIC VA-502", - .internal_name = "ficva502", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_VPX, - .init = machine_at_ficva502_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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* Apollo VP3 */ - /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA VP3] FIC PA-2012", - .internal_name = "ficpa2012", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_VP3, - .init = machine_at_ficpa2012_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 = 75000000, - .min_voltage = 2100, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .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 VIA VT82C586B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA VP3] PC Partner VIA809DS", - .internal_name = "via809ds", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_VP3, - .init = machine_at_via809ds_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 = 2100, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .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 - }, - - /* SiS 5571 */ - /* Has the SiS 5571 chipset with on-chip KBC. */ - { - .name = "[SiS 5571] Daewoo CD520", - .internal_name = "cb52xsi", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_SIS_5571, - .init = machine_at_cb52xsi_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 75000000, - .min_voltage = 2800, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 262144, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* 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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, - .ram = { - .min = 8192, - .max = 262144, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* 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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 393216, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* SiS 5581 */ - /* Has the SiS 5581 chipset with on-chip KBC. */ - { - .name = "[SiS 5581] ASUS SP97-XV", - .internal_name = "sp97xv", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_SIS_5581, - .init = machine_at_sp97xv_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 75000000, - .min_voltage = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1572864, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has the SiS 5581 chipset with on-chip KBC. */ - { - .name = "[SiS 5581] BCM SQ-578", - .internal_name = "sq578", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_SIS_5581, - .init = machine_at_sq578_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 75000000, - .min_voltage = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1572864, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* SiS 5591 */ - /* Has the SiS 5591 chipset with on-chip KBC. */ - { - .name = "[SiS 5591] MSI MS-5172", - .internal_name = "ms5172", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_SIS_5591, - .init = machine_at_ms5172_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 75000000, - .min_voltage = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* ALi ALADDiN IV+ */ - /* 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, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 83333333, - .min_voltage = 2100, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has 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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* Super Socket 7 machines */ - /* ALi ALADDiN V */ - /* Has the ALi M1543C southbridge with on-chip KBC. */ - { - .name = "[ALi ALADDiN V] ASUS P5A", - .internal_name = "p5a", - .type = MACHINE_TYPE_SOCKETS7, - .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, - .init = machine_at_p5a_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 120000000, - .min_voltage = 2000, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1572864, - .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 - }, - /* Is the exact same as the Matsonic MS6260S. Has the ALi M1543C southbridge - with on-chip KBC. */ - { - .name = "[ALi ALADDiN V] PC Chips M579", - .internal_name = "m579", - .type = MACHINE_TYPE_SOCKETS7, - .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, - .init = machine_at_m579_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 2000, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 1024, - .max = 1572864, - .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 - }, - /* M1534c kbc */ - { - .name = "[ALi ALADDiN V] Gateway Lucas", - .internal_name = "gwlucas", - .type = MACHINE_TYPE_SOCKETS7, - .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, - .init = machine_at_gwlucas_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 2000, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_PCIONLY | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal video: ATI 3D Rage Pro Turbo AGP and sound: Ensoniq ES1373 */ - .ram = { - .min = 8192, - .max = 262144, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = &es1373_onboard_device, - .net_device = NULL - }, - /* Has the ALi M1543C southbridge with on-chip KBC. */ - { - .name = "[ALi ALADDiN V] Gigabyte GA-5AA", - .internal_name = "5aa", - .type = MACHINE_TYPE_SOCKETS7, - .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, - .init = machine_at_5aa_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 140000000, - .min_voltage = 1300, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 1024, - .max = 1572864, - .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 ALi M1543C southbridge with on-chip KBC. */ - { - .name = "[ALi ALADDiN V] Gigabyte GA-5AX", - .internal_name = "5ax", - .type = MACHINE_TYPE_SOCKETS7, - .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, - .init = machine_at_5ax_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 140000000, - .min_voltage = 1300, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 1024, - .max = 1572864, - .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 - }, - - /* Apollo MVP3 */ - /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA MVP3] AOpen AX59 Pro", - .internal_name = "ax59pro", - .type = MACHINE_TYPE_SOCKETS7, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, - .init = machine_at_ax59pro_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 124242424, - .min_voltage = 1300, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA MVP3] FIC VA-503+", - .internal_name = "ficva503p", - .type = MACHINE_TYPE_SOCKETS7, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, - .init = machine_at_mvp3_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 124242424, - .min_voltage = 2000, - .max_voltage = 3200, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has the VIA VT82C686A southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA MVP3] FIC VA-503A", - .internal_name = "ficva503a", - .type = MACHINE_TYPE_SOCKETS7, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, - .init = machine_at_ficva503a_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 124242424, - .min_voltage = 1800, - .max_voltage = 3100, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_A97 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has the VIA VT82C686A southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA MVP3] Soyo 5EMA PRO", - .internal_name = "5emapro", - .type = MACHINE_TYPE_SOCKETS7, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, - .init = machine_at_5emapro_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 124242424, - .min_voltage = 2000, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* SiS 5591 */ - /* Has the SiS 5591 chipset with on-chip KBC. */ - { - .name = "[SiS 5591] Gigabyte GA-5SG100", - .internal_name = "5sg100", - .type = MACHINE_TYPE_SOCKETS7, - .chipset = MACHINE_CHIPSET_SIS_5591, - .init = machine_at_5sg100_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 2000, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* Socket 8 machines */ - /* 450KX */ - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[i450KX] AOpen AP61", - .internal_name = "ap61", - .type = MACHINE_TYPE_SOCKET8, - .chipset = MACHINE_CHIPSET_INTEL_450KX, - .init = machine_at_ap61_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET8, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2100, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has an AMIKey-2, which is an updated version of type 'H'. */ - { - .name = "[i450KX] ASUS P/I-P6RP4", - .internal_name = "p6rp4", - .type = MACHINE_TYPE_SOCKET8, - .chipset = MACHINE_CHIPSET_INTEL_450KX, - .init = machine_at_p6rp4_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET8, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2100, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI, /* Machine has AMB */ - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 440FX */ - /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix - MultiKey/42 (version 1.38) KBC firmware. */ - { - .name = "[i440FX] Acer V60N", - .internal_name = "acerv60n", - .type = MACHINE_TYPE_SOCKET8, - .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_acerv60n_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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 511, - .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 - }, - /* The base board has a Holtek HT6542B with AMIKey-2 (updated 'H') KBC firmware. */ - { - .name = "[i440FX] ASUS P/I-P65UP5 (C-P6ND)", - .internal_name = "p65up5_cp6nd", - .type = MACHINE_TYPE_SOCKET8, - .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_p65up5_cp6nd_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET8, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2100, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Machine has AMB */ - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .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 a VIA VT82C42N with likely AMIKey 'F' KBC firmware. */ - { - .name = "[i440FX] Biostar MB-8600TTC", - .internal_name = "8600ttc", - .type = MACHINE_TYPE_SOCKET8, - .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_8600ttc_init, - .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 = 50000000, - .max_bus = 66666667, - .min_voltage = 2900, - .max_voltage = 3300, - .min_multi = 2.0, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* It's a Intel VS440FX with a Gateway 2000 OEM BIOS */ - { - .name = "[i440FX] Gateway 2000 Venus", - .internal_name = "gw2kvenus", - .type = MACHINE_TYPE_SOCKET8, - .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_gw2kvenus_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET8, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2100, - .max_voltage = 3500, - .min_multi = 2.0, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = &cs4236_onboard_device, - .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, - .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 = 5.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .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 . */ - { - .name = "[i440FX] Intel AP440FX", - .internal_name = "ap440fx", - .type = MACHINE_TYPE_SOCKET8, - .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_ap440fx_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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_SOUND | MACHINE_VIDEO | MACHINE_USB, /* Machine has internal video: S3 ViRGE/DX and sound: Crystal CS4236B */ - .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 = &s3_virge_325_onboard_pci_device, - .snd_device = &cs4236b_onboard_device, - .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 . */ - { - .name = "[i440FX] Intel VS440FX", - .internal_name = "vs440fx", - .type = MACHINE_TYPE_SOCKET8, - .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_vs440fx_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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = &cs4236_onboard_device, - .net_device = NULL - }, - /* Has the AMIKey-2 (updated 'H') KBC firmware. */ - { - .name = "[i440FX] LG IBM Multinet x61 (MSI MS-6106)", - .internal_name = "lgibmx61", - .type = MACHINE_TYPE_SOCKET8, - .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_lgibmx61_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET8, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2500, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal SCSI: Adaptec AIC-78xx */ - .ram = { - .min = 40960, - .max = 524288, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix - MultiKey/42 (version 1.38) KBC firmware. */ - { - .name = "[i440FX] Micronics M6Mi", - .internal_name = "m6mi", - .type = MACHINE_TYPE_SOCKET8, - .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_m6mi_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 = 2900, - .max_voltage = 3300, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 511, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a VIA VT82C42N KBC with likely AMI MegaKey firmware. */ - { - .name = "[i440FX] PC Partner MB600N", - .internal_name = "mb600n", - .type = MACHINE_TYPE_SOCKET8, - .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_mb600n_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET8, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2100, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* Slot 1 machines */ - /* ALi ALADDiN V */ - /* Has the ALi M1543C southbridge with on-chip KBC. */ - { - .name = "[ALi ALADDiN-PRO II] PC Chips M729", - .internal_name = "m729", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_ALI_ALADDIN_PRO_II, - .init = machine_at_m729_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: C-Media CMI8330 */ - .ram = { - .min = 1024, - .max = 1572864, - .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 - }, - - /* 440FX */ - /* The base board has a Holtek HT6542B KBC with AMIKey-2 (updated 'H') KBC firmware. */ - { - .name = "[i440FX] ASUS P/I-P65UP5 (C-PKND)", - .internal_name = "p65up5_cpknd", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_p65up5_cpknd_init, - .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 = 66666667, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 127, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* This has a Holtek KBC and the BIOS does not send a single non-standard KBC command, so it - must be an ASIC that clones the standard IBM PS/2 KBC. */ - { - .name = "[i440FX] ASUS KN97", - .internal_name = "kn97", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_kn97_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 = 60000000, - .max_bus = 83333333, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .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 - }, - - /* 440LX */ - /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440LX] ABIT LX6", - .internal_name = "lx6", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440LX, - .init = machine_at_lx6_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 = 60000000, - .max_bus = 83333333, - .min_voltage = 1500, - .max_voltage = 3500, - .min_multi = 2.0, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix - MultiKey/42 (version 1.38) KBC firmware. */ - { - .name = "[i440LX] Micronics Spitfire", - .internal_name = "spitfire", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440LX, - .init = machine_at_spitfire_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 66666667, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a SM(S)C FDC37C67x Super I/O chip with on-chip KBC with Phoenix or - AMIKey-2 KBC firmware. */ - { - .name = "[i440LX] NEC Mate NX MA30D/23D", - .internal_name = "ma30d", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440LX, - .init = machine_at_ma30d_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 66666667, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 440EX */ - /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440EX] QDI EXCELLENT II", - .internal_name = "p6i440e2", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440EX, - .init = machine_at_p6i440e2_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 = 83333333, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 3.0, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 440BX */ - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440BX] ASUS P2B-LS", - .internal_name = "p2bls", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_p2bls_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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal SCSI: Adaptec AIC-7890AB */ - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440BX] ASUS P3B-F", - .internal_name = "p3bf", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_p3bf_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 = 150000000, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - -{ - .name = "[i440BX] ABIT BX6", - .internal_name = "bx6", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_bx6_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 = 133333333, - .min_voltage = 1500, - .max_voltage = 3500, - .min_multi = 2.0, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - { - .name = "[i440BX] ABIT BF6", - .internal_name = "bf6", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_bf6_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 = 133333333, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440BX] AOpen AX6BC", - .internal_name = "ax6bc", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_ax6bc_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 = 112121212, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440BX] Gigabyte GA-686BX", - .internal_name = "686bx", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_686bx_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a SM(S)C FDC37M60x Super I/O chip with on-chip KBC with most likely - AMIKey-2 KBC firmware. */ - { - .name = "[i440BX] HP Vectra VEi 8", - .internal_name = "vei8", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_vei8_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal video: Matrox MGA-G200 and sound: Crystal CS4820 */ - .ram = { - .min = 8192, - .max = 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 = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 (updated 'H') KBC firmware. */ - { - .name = "[i440BX] LG IBM Multinet i x7G (MSI MS-6119)", - .internal_name = "lgibmx7g", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_lgibmx7g_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a National Semiconductors PC87309 Super I/O chip with on-chip KBC - with most likely AMIKey-2 KBC firmware. */ - { - .name = "[i440BX] Tyan Tsunami ATX", - .internal_name = "s1846", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_s1846_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 = 112121212, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1371 */ - .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, - .vid_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 - firmware. */ - { - .name = "[i440BX] Supermicro P6SBA", - .internal_name = "p6sba", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_p6sba_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 440ZX */ - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440ZX] MSI MS-6168", - .internal_name = "ms6168", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440ZX, - .init = machine_at_ms6168_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* AGP is reserved for the internal video */ - .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &voodoo_3_2000_agp_onboard_8m_device, - .snd_device = &es1373_onboard_device, - .net_device = NULL - }, - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440ZX] Packard Bell Bora Pro", - .internal_name = "borapro", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440ZX, - .init = machine_at_borapro_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* AGP is reserved for the internal video */ - .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &voodoo_3_2000_agp_onboard_8m_device, - .snd_device = &es1373_onboard_device, - .net_device = NULL - }, - - /* SMSC VictoryBX-66 */ - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[SMSC VictoryBX-66] A-Trend ATC6310BXII", - .internal_name = "atc6310bxii", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66, - .init = machine_at_atc6310bxii_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 = 133333333, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* VIA Apollo Pro */ - /* Has the VIA VT82C596B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA Apollo Pro] FIC KA-6130", - .internal_name = "ficka6130", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO, - .init = machine_at_ficka6130_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: ESS ES1938S */ - .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 = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[VIA Apollo Pro 133] ASUS P3V133", - .internal_name = "p3v133", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, - .init = machine_at_p3v133_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 = 150000000, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1572864, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[VIA Apollo Pro 133A] ASUS P3V4X", - .internal_name = "p3v4x", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, - .init = machine_at_p3v4x_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK(CPU_PENTIUMPRO), - .min_bus = 66666667, - .max_bus = 150000000, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 2097152, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[VIA Apollo Pro 133A] BCM GT694VA", - .internal_name = "gt694va", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, - .init = machine_at_gt694va_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 = 133333333, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ - .ram = { - .min = 8192, - .max = 3145728, - .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 = &es1373_onboard_device, - .net_device = NULL - }, - - /* SiS (5)600 */ - /* Has the SiS (5)600 chipset with on-chip KBC. */ - { - .name = "[SiS 5600] Freetech/Flexus P6F99", - .internal_name = "p6f99", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_SIS_5600, - .init = machine_at_p6f99_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ - .ram = { - .min = 8192, - .max = 1572864, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = &es1373_onboard_device, - .net_device = NULL - }, - /* Has the SiS (5)600 chipset with on-chip KBC. */ - { - .name = "[SiS 5600] PC Chips M747", - .internal_name = "m747", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_SIS_5600, - .init = machine_at_m747_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1572864, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* Slot 1/2 machines */ - /* 440GX */ - /* Has a National Semiconductors PC87309 Super I/O chip with on-chip KBC - with most likely AMIKey-2 KBC firmware. */ - { - .name = "[i440GX] Freeway FW-6400GX", - .internal_name = "fw6400gx", - .type = MACHINE_TYPE_SLOT1_2, - .chipset = MACHINE_CHIPSET_INTEL_440GX, - .init = machine_at_fw6400gx_init, - .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, - .min_bus = 100000000, - .max_bus = 150000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 3.0, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_NOISA | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 16384, - .max = 2097152, - .step = 16384 - }, - .nvrmask = 511, - .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 - }, - - /* Slot 1/Socket 370 machines */ - /* 440BX */ - /* OEM version of ECS P6BXT-A+ REV 1.3x/2.2x. Has a Winbond W83977EF Super - I/O chip with on-chip KBC with AMIKey-2 KBC firmware.*/ - { - .name = "[i440BX] Compaq ProSignia S316/318 (Intel)", - .internal_name = "prosignias31x_bx", - .type = MACHINE_TYPE_SLOT1_370, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, - .init = machine_at_prosignias31x_bx_init, - .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(CPU_PENTIUMPRO, CPU_CYRIX3S), /* Instability issues with PPro, and garbled text in POST with Cyrix */ - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = &cmi8738_onboard_device, - .net_device = NULL - }, - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440BX] Tyan Trinity 371", - .internal_name = "s1857", - .type = MACHINE_TYPE_SLOT1_370, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_s1857_init, - .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, - .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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = &es1373_onboard_device, - .net_device = NULL - }, - /* VIA Apollo Pro */ - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[VIA Apollo Pro 133] ECS P6BAT-A+", - .internal_name = "p6bat", - .type = MACHINE_TYPE_SLOT1_370, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, - .init = machine_at_p6bat_init, - .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, - .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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1572864, - .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 - }, - - /* Slot 2 machines */ - /* 440GX */ - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440GX] Gigabyte GA-6GXU", - .internal_name = "6gxu", - .type = MACHINE_TYPE_SLOT2, - .chipset = MACHINE_CHIPSET_INTEL_440GX, - .init = machine_at_6gxu_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT2, - .block = CPU_BLOCK_NONE, - .min_bus = 100000000, - .max_bus = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal SCSI */ - .ram = { - .min = 16384, - .max = 2097152, - .step = 16384 - }, - .nvrmask = 511, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440GX] Supermicro S2DGE", - .internal_name = "s2dge", - .type = MACHINE_TYPE_SLOT2, - .chipset = MACHINE_CHIPSET_INTEL_440GX, - .init = machine_at_s2dge_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT2, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 16384, - .max = 2097152, - .step = 16384 - }, - .nvrmask = 511, - .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 - }, - - /* PGA370 machines */ - /* 440LX */ - /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440LX] Supermicro 370SLM", - .internal_name = "s370slm", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_INTEL_440LX, - .init = machine_at_s370slm_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 = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED, - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 440BX */ - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440BX] AEWIN AW-O671R", - .internal_name = "awo671r", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_awo671r_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 /* limits assumed */ - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Machine has EISA, possibly for a riser? */ - /* Yes, that's a rise slot, not EISA. */ - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB | MACHINE_VIDEO, /* Machine has internal video: C&T B69000, sound: ESS ES1938S and NIC: Realtek RTL8139C */ - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440BX] ASUS CUBX", - .internal_name = "cubx", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_cubx_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 = 150000000, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has quad channel IDE with internal controller: CMD PCI-0648 */ - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440BX] AmazePC AM-BX133", - .internal_name = "ambx133", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_ambx133_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 /* limits assumed */ - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* 440ZX */ - /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440ZX] Soltek SL-63A1", - .internal_name = "63a1", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_INTEL_440ZX, - .init = machine_at_63a1_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 = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* SMSC VictoryBX-66 */ - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[SMSC VictoryBX-66] A-Trend ATC7020BXII", - .internal_name = "atc7020bxii", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66, - .init = machine_at_atc7020bxii_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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has 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 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = &cmi8738_onboard_device, - .net_device = NULL - }, - - /* VIA Apollo Pro */ - /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA Apollo Pro] PC Partner APAS3", - .internal_name = "apas3", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO, - .init = machine_at_apas3_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 = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[VIA Apollo Pro 133] ECS P6BAP-A+", - .internal_name = "p6bap", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, - .init = machine_at_p6bap_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 = 150000000, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB | MACHINE_SOUND, - .ram = { - .min = 8192, - .max = 1572864, - .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 - }, - /* Has the VIA VT82C686B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA Apollo Pro 133A] Acorp 6VIA90AP", - .internal_name = "6via90ap", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, - .init = machine_at_6via90ap_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 = 150000000, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = MACHINE_MULTIPLIER_FIXED, - .max_multi = MACHINE_MULTIPLIER_FIXED - }, - .bus_flags = MACHINE_PS2_A97 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_AG | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, - .ram = { - .min = 16384, - .max = 3145728, - .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 VIA VT82C686B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA Apollo Pro 133A] ASUS CUV4X-LS", - .internal_name = "cuv4xls", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, - .init = machine_at_cuv4xls_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 = 150000000, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_NOI97 | MACHINE_BUS_USB, /* Has Asus-proprietary LAN/SCSI slot */ - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, - .ram = { - .min = 16384, - .max = 4194304, - .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 - }, - /* SiS (5)600 */ - /* Has the SiS 600 chipset, which is a re-brand of the 5600, with - on-chip KBC. */ - { - .name = "[SiS 600] Soyo SY-7SBB", - .internal_name = "7sbb", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_SIS_5600, - .init = machine_at_7sbb_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET370, - .block = CPU_BLOCK(CPU_CYRIX3S), - .min_bus = 60000000, - .max_bus = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1572864, - .step = 1024 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* Miscellaneous/Fake/Hypervisor machines */ - /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC - firmware. */ - { - .name = "[i440BX] Microsoft Virtual PC 2007", - .internal_name = "vpc2007", - .type = MACHINE_TYPE_MISC, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_vpc2007_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK(CPU_PENTIUMPRO, CPU_PENTIUM2, CPU_CYRIX3S), - .min_bus = 0, - .max_bus = 66666667, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - { - .name = NULL, - .internal_name = NULL, - .type = MACHINE_TYPE_NONE, - .chipset = MACHINE_CHIPSET_NONE, - .init = NULL, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = 0, - .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_BUS_NONE, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 0, - .max = 0, - .step = 0 - }, - .nvrmask = 0, - .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 - } - // clang-format on -}; - -/* 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 uint32_t machine_p1_default; -static uint32_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) -{ - return machine_p1; -} - -void -machine_set_p1_default(uint8_t val) -{ - machine_p1 = machine_p1_default = val; -} - -void -machine_set_p1(uint8_t val) -{ - machine_p1 = val; -} - -void -machine_and_p1(uint8_t val) -{ - machine_p1 = machine_p1_default & val; -} - -uint8_t -machine_handle_p1(uint8_t write, uint8_t val) -{ - uint8_t ret = 0xff; - - if (machines[machine].p1_handler) - ret = machines[machine].p1_handler(write, val); - else { - if (write) - machine_p1 = machine_p1_default & val; - else - ret = machine_p1; - } - - return ret; -} - -void -machine_init_p1(void) -{ - machine_p1 = machine_p1_default = machines[machine].kbc_p1; -} - -uint32_t -machine_get_gpio_default(void) -{ - return machine_gpio_default; -} - -uint32_t -machine_get_gpio(void) -{ - return machine_gpio; -} - -void -machine_set_gpio_default(uint32_t val) -{ - machine_gpio = machine_gpio_default = val; -} - -void -machine_set_gpio(uint32_t val) -{ - machine_gpio = val; -} - -void -machine_and_gpio(uint32_t val) -{ - machine_gpio = machine_gpio_default & val; -} - -uint32_t -machine_handle_gpio(uint8_t write, uint32_t val) -{ - uint32_t ret = 0xffffffff; - - if (machines[machine].gpio_handler) - ret = machines[machine].gpio_handler(write, val); - else { - if (write) - machine_gpio = machine_gpio_default & val; - else - ret = machine_gpio; - } - - return ret; -} - -void -machine_init_gpio(void) -{ - machine_gpio = machine_gpio_default = machines[machine].gpio; -} - -uint32_t -machine_get_gpio_acpi_default(void) -{ - return machine_gpio_acpi_default; -} - -uint32_t -machine_get_gpio_acpi(void) -{ - return machine_gpio_acpi; -} - -void -machine_set_gpio_acpi_default(uint32_t val) -{ - machine_gpio_acpi = machine_gpio_acpi_default = val; -} - -void -machine_set_gpio_acpi(uint32_t val) -{ - machine_gpio_acpi = val; -} - -void -machine_and_gpio_acpi(uint32_t val) -{ - machine_gpio_acpi = machine_gpio_acpi_default & val; -} - -uint32_t -machine_handle_gpio_acpi(uint8_t write, uint32_t val) -{ - 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 -machine_count(void) -{ - return ((sizeof(machines) / sizeof(machine_t)) - 1); -} - -const char * -machine_getname(void) -{ - return (machines[machine].name); -} - -const char * -machine_getname_ex(int m) -{ - return (machines[m].name); -} - -const device_t * -machine_get_kbc_device(int m) -{ - if (machines[m].kbc_device) - return (machines[m].kbc_device); - - return (NULL); -} - -const device_t * -machine_get_device(int m) -{ - if (machines[m].device) - return (machines[m].device); - - return (NULL); -} - -const device_t * -machine_get_fdc_device(int m) -{ - if (machines[m].fdc_device) - return (machines[m].fdc_device); - - return (NULL); -} - -const device_t * -machine_get_sio_device(int m) -{ - if (machines[m].sio_device) - return (machines[m].sio_device); - - return (NULL); -} - -const device_t * -machine_get_vid_device(int m) -{ - if (machines[m].vid_device) - return (machines[m].vid_device); - - return (NULL); -} - -const device_t * -machine_get_snd_device(int m) -{ - if (machines[m].snd_device) - return (machines[m].snd_device); - - return (NULL); -} - -const device_t * -machine_get_net_device(int m) -{ - if (machines[m].net_device) - return (machines[m].net_device); - - return (NULL); -} - -const char * -machine_get_internal_name(void) -{ - return (machines[machine].internal_name); -} - -const char * -machine_get_internal_name_ex(int m) -{ - return (machines[m].internal_name); -} - -int -machine_get_nvrmask(int m) -{ - return (machines[m].nvrmask); -} - -int -machine_has_flags(int m, int flags) -{ - int ret = machines[m].flags & flags; - - /* Can't have PS/2 ports with an AT KBC. */ - if ((flags & MACHINE_PS2_KBC) && - (machines[m].bus_flags & MACHINE_BUS_PS2_PORTS)) - ret |= MACHINE_PS2_KBC; - - return ret; -} - -int -machine_has_bus(int m, int bus_flags) -{ - int ret = machines[m].bus_flags & bus_flags; - - /* TODO: Move the KBD flags to the machine table! */ - if ((bus_flags & MACHINE_BUS_XT_KBD) && - !(machines[m].bus_flags & MACHINE_BUS_ISA16) && - !(machines[m].bus_flags & MACHINE_BUS_PS2_PORTS)) + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &cs4236_onboard_device, + .net_device = NULL + }, + /* It's an 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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &cs4236_onboard_device, + .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, + .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 = 5.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .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 . */ + { + .name = "[i440FX] Intel AP440FX (Apollo)", + .internal_name = "ap440fx", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_ap440fx_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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_SOUND | MACHINE_VIDEO | MACHINE_USB, /* Machine has internal video: S3 ViRGE/DX and sound: Crystal CS4236B */ + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_virge_325_onboard_pci_device, + .snd_device = &cs4236b_onboard_device, + .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 . */ + { + .name = "[i440FX] Intel VS440FX (Venus)", + .internal_name = "vs440fx", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_vs440fx_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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &cs4236_onboard_device, + .net_device = NULL + }, + /* Has the AMIKey-2 (updated 'H') KBC firmware. */ + { + .name = "[i440FX] LG IBM Multinet x61 (MSI MS-6106)", + .internal_name = "lgibmx61", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_lgibmx61_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET8, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2500, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal SCSI: Adaptec AIC-7880U */ + .ram = { + .min = 40960, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ + { + .name = "[i440FX] Micronics M6Mi", + .internal_name = "m6mi", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_m6mi_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 = 2900, + .max_voltage = 3300, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Creative Vibra 16C */ + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a VIA VT82C42N KBC with likely AMI MegaKey firmware. */ + { + .name = "[i440FX] PC Partner MB600N", + .internal_name = "mb600n", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_mb600n_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET8, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* Slot 1 machines */ + /* ALi ALADDiN V */ + /* Has the ALi M1543C southbridge with on-chip KBC. */ + { + .name = "[ALi ALADDiN-PRO II] PC Chips M729", + .internal_name = "m729", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_PRO_II, + .init = machine_at_m729_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: C-Media CMI8330 */ + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 440FX */ + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ + { + .name = "[i440FX] Acer V62X", + .internal_name = "acerv62x", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_acerv62x_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 = 60000000, + .max_bus = 83333333, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 393216, + .step = 8192 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* The base board has a Holtek HT6542B KBC with AMIKey-2 (updated 'H') KBC firmware. */ + { + .name = "[i440FX] ASUS P/I-P65UP5 (C-PKND)", + .internal_name = "p65up5_cpknd", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_p65up5_cpknd_init, + .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 = 66666667, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* This has a Holtek KBC and the BIOS does not send a single non-standard KBC command, so it + must be an ASIC that clones the standard IBM PS/2 KBC. */ + { + .name = "[i440FX] ASUS KN97", + .internal_name = "kn97", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_kn97_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 = 60000000, + .max_bus = 83333333, + .min_voltage = 2800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 440LX */ + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440LX] ABIT LX6", + .internal_name = "lx6", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440LX, + .init = machine_at_lx6_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 = 60000000, + .max_bus = 83333333, + .min_voltage = 1500, + .max_voltage = 3500, + .min_multi = 2.0, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a National Semiconductor PC87307 Super I/O with on-chip KBC, which has one of these + firmwares: AMI '5' MegaKey, Phoenix MultiKey/42 1.37, or Phoenix MultiKey/42i 4.16. */ + { + .name = "[i440LX] Dell OptiPlex GXa", + .internal_name = "optiplexgxa", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440LX, + .init = machine_at_optiplexgxa_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK(CPU_PENTIUMPRO, CPU_CYRIX3S), + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 5.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Video: ATi 3D Rage Pro, Network: 3Com 3C905, Sound: Crystal CS4236B */ + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, /* not yet emulated */ + .snd_device = &cs4236b_device, + .net_device = NULL /* not yet emulated */ + }, + /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix + MultiKey/42 (version 1.38) KBC firmware. */ + { + .name = "[i440LX] Micronics Spitfire", + .internal_name = "spitfire", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440LX, + .init = machine_at_spitfire_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: Yamaha YMF701 */ + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a SM(S)C FDC37C67x Super I/O chip with on-chip KBC with Phoenix or + AMIKey-2 KBC firmware. */ + { + .name = "[i440LX] NEC Mate NX MA30D/23D", + .internal_name = "ma30d", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440LX, + .init = machine_at_ma30d_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Has internal video: SGS Thompson Riva 128 AGP, network: NEC PK-UG-X006 (Intel 82558B chip) and sound: OAK Audia 3D (OTI-610) */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 440EX */ + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440EX] QDI EXCELLENT II", + .internal_name = "p6i440e2", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440EX, + .init = machine_at_p6i440e2_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 = 83333333, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 3.0, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 440BX */ + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440BX] ASUS P2B-LS", + .internal_name = "p2bls", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_p2bls_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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal SCSI: Adaptec AIC-7890AB */ + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440BX] ASUS P3B-F", + .internal_name = "p3bf", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_p3bf_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 = 150000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + +{ + .name = "[i440BX] ABIT BX6", + .internal_name = "bx6", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_bx6_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 = 133333333, + .min_voltage = 1500, + .max_voltage = 3500, + .min_multi = 2.0, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + { + .name = "[i440BX] ABIT BF6", + .internal_name = "bf6", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_bf6_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 = 133333333, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440BX] AOpen AX6BC", + .internal_name = "ax6bc", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_ax6bc_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 = 112121212, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440BX] Gigabyte GA-686BX", + .internal_name = "686bx", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_686bx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 (updated 'H') KBC firmware. */ + { + .name = "[i440BX] LG IBM Multinet i x7G (MSI MS-6119)", + .internal_name = "lgibmx7g", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_lgibmx7g_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440BX] Supermicro P6SBA", + .internal_name = "p6sba", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_p6sba_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a National Semiconductors PC87309 Super I/O chip with on-chip KBC + with most likely AMIKey-2 KBC firmware. */ + { + .name = "[i440BX] Tyan Tsunami ATX", + .internal_name = "s1846", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_s1846_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 = 112121212, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1371 */ + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &es1371_onboard_device, + .net_device = NULL + }, + + /* 440ZX */ + /* Has a SM(S)C FDC37M60x Super I/O chip with on-chip KBC with most likely + AMIKey-2 KBC firmware. */ + { + .name = "[i440ZX] HP Vectra VEi 8", + .internal_name = "vei8", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440ZX, + .init = machine_at_vei8_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal video: Matrox MGA-G200 and sound: Crystal CS4820 */ + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440ZX] MSI MS-6168", + .internal_name = "ms6168", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440ZX, + .init = machine_at_ms6168_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* AGP is reserved for the internal video */ + .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &voodoo_3_2000_agp_onboard_8m_device, + .snd_device = &es1373_onboard_device, + .net_device = NULL + }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440ZX] Packard Bell Bora Pro (MSI MS-6168)", + .internal_name = "borapro", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440ZX, + .init = machine_at_borapro_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* AGP is reserved for the internal video */ + .flags = MACHINE_IDE_DUAL | MACHINE_AV | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &voodoo_3_2000_agp_onboard_8m_device, + .snd_device = &es1373_onboard_device, + .net_device = NULL + }, + + /* SMSC VictoryBX-66 */ + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[SMSC VictoryBX-66] A-Trend ATC6310BXII", + .internal_name = "atc6310bxii", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66, + .init = machine_at_atc6310bxii_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 = 133333333, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* VIA Apollo Pro */ + /* Has the VIA VT82C596B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA Apollo Pro] FIC KA-6130", + .internal_name = "ficka6130", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO, + .init = machine_at_ficka6130_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: ESS ES1938S */ + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[VIA Apollo Pro 133] ASUS P3V133", + .internal_name = "p3v133", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, + .init = machine_at_p3v133_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 = 150000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[VIA Apollo Pro 133A] ASUS P3V4X", + .internal_name = "p3v4x", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, + .init = machine_at_p3v4x_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK(CPU_PENTIUMPRO), + .min_bus = 66666667, + .max_bus = 150000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 2097152, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[VIA Apollo Pro 133A] BCM GT694VA", + .internal_name = "gt694va", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, + .init = machine_at_gt694va_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 = 133333333, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ + .ram = { + .min = 8192, + .max = 3145728, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &es1373_onboard_device, + .net_device = NULL + }, + + /* SiS (5)600 */ + /* Has the SiS (5)600 chipset with on-chip KBC. */ + { + .name = "[SiS 5600] Freetech/Flexus P6F99", + .internal_name = "p6f99", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_SIS_5600, + .init = machine_at_p6f99_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &es1373_onboard_device, + .net_device = NULL + }, + /* Has the SiS (5)600 chipset with on-chip KBC. */ + { + .name = "[SiS 5600] PC Chips M747", + .internal_name = "m747", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_SIS_5600, + .init = machine_at_m747_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal video: SiS 6326 and internal sound: C-Media CMI8330 */ + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* Slot 1/2 machines */ + /* 440GX */ + /* Has a National Semiconductors PC87309 Super I/O chip with on-chip KBC + with most likely AMIKey-2 KBC firmware. */ + { + .name = "[i440GX] Freeway FW-6400GX", + .internal_name = "fw6400gx", + .type = MACHINE_TYPE_SLOT1_2, + .chipset = MACHINE_CHIPSET_INTEL_440GX, + .init = machine_at_fw6400gx_init, + .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, + .min_bus = 100000000, + .max_bus = 150000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 3.0, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_NOISA | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 16384, + .max = 2097152, + .step = 16384 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* Slot 1/Socket 370 machines */ + /* 440BX */ + /* OEM version of ECS P6BXT-A+ REV 1.3x/2.2x. Has a Winbond W83977EF Super + I/O chip with on-chip KBC with AMIKey-2 KBC firmware.*/ + { + .name = "[i440BX] Compaq ProSignia S316/318 (Intel)", + .internal_name = "prosignias31x_bx", + .type = MACHINE_TYPE_SLOT1_370, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, + .init = machine_at_prosignias31x_bx_init, + .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(CPU_PENTIUMPRO, CPU_CYRIX3S), /* Instability issues with PPro, and garbled text in POST with Cyrix */ + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &cmi8738_onboard_device, + .net_device = NULL + }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440BX] Tyan Trinity 371", + .internal_name = "s1857", + .type = MACHINE_TYPE_SLOT1_370, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_s1857_init, + .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, + .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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &es1373_onboard_device, + .net_device = NULL + }, + /* VIA Apollo Pro */ + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[VIA Apollo Pro 133] ECS P6BAT-A+", + .internal_name = "p6bat", + .type = MACHINE_TYPE_SLOT1_370, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, + .init = machine_at_p6bat_init, + .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, + .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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &cmi8738_onboard_device, + .net_device = NULL + }, + + /* Slot 2 machines */ + /* 440GX */ + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440GX] Gigabyte GA-6GXU", + .internal_name = "6gxu", + .type = MACHINE_TYPE_SLOT2, + .chipset = MACHINE_CHIPSET_INTEL_440GX, + .init = machine_at_6gxu_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT2, + .block = CPU_BLOCK_NONE, + .min_bus = 100000000, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal SCSI */ + .ram = { + .min = 16384, + .max = 2097152, + .step = 16384 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440GX] Supermicro S2DGE", + .internal_name = "s2dge", + .type = MACHINE_TYPE_SLOT2, + .chipset = MACHINE_CHIPSET_INTEL_440GX, + .init = machine_at_s2dge_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT2, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 16384, + .max = 2097152, + .step = 16384 + }, + .nvrmask = 511, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* PGA370 machines */ + /* 440LX */ + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440LX] Supermicro 370SLM", + .internal_name = "s370slm", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_INTEL_440LX, + .init = machine_at_s370slm_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 = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED, + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 440BX */ + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440BX] AEWIN AW-O671R", + .internal_name = "awo671r", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_awo671r_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 /* limits assumed */ + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Machine has EISA, possibly for a riser? */ + /* Yes, that's a rise slot, not EISA. */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB | MACHINE_VIDEO, /* Machine has internal video: C&T B69000, sound: ESS ES1938S and NIC: Realtek RTL8139C */ + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &chips_69000_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440BX] ASUS CUBX", + .internal_name = "cubx", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_cubx_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 = 150000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_QUAD | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has quad channel IDE with internal controller: CMD PCI-0648 */ + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440BX] AmazePC AM-BX133", + .internal_name = "ambx133", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_ambx133_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 /* limits assumed */ + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* 440ZX */ + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440ZX] Soltek SL-63A1", + .internal_name = "63a1", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_INTEL_440ZX, + .init = machine_at_63a1_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 = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* SMSC VictoryBX-66 */ + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[SMSC VictoryBX-66] A-Trend ATC7020BXII", + .internal_name = "atc7020bxii", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66, + .init = machine_at_atc7020bxii_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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .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 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_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 + VT82C42N. */ + { + .name = "[VIA Apollo Pro] PC Partner APAS3", + .internal_name = "apas3", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO, + .init = machine_at_apas3_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 = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal video: Creative Vibra 16XV */ + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[VIA Apollo Pro 133] ECS P6BAP-A+", + .internal_name = "p6bap", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, + .init = machine_at_p6bap_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 = 150000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB | MACHINE_SOUND, + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &cmi8738_onboard_device, + .net_device = NULL + }, + /* Has the VIA VT82C686B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA Apollo Pro 133A] Acorp 6VIA90AP", + .internal_name = "6via90ap", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, + .init = machine_at_6via90ap_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 = 150000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_A97 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_AG | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 16384, + .max = 3145728, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the VIA VT82C686B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA Apollo Pro 133A] ASUS CUV4X-LS", + .internal_name = "cuv4xls", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, + .init = machine_at_cuv4xls_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 = 150000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_NOI97 | MACHINE_BUS_USB, /* Has Asus-proprietary LAN/SCSI slot */ + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 16384, + .max = 4194304, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &cmi8738_onboard_device, + .net_device = NULL + }, + /* SiS (5)600 */ + /* Has the SiS 600 chipset, which is a re-brand of the 5600, with + on-chip KBC. */ + { + .name = "[SiS 600] Soyo SY-7SBB", + .internal_name = "7sbb", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_SIS_5600, + .init = machine_at_7sbb_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET370, + .block = CPU_BLOCK(CPU_CYRIX3S), + .min_bus = 60000000, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + /* Miscellaneous/Fake/Hypervisor machines */ + /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i440BX] Microsoft Virtual PC 2007", + .internal_name = "vpc2007", + .type = MACHINE_TYPE_MISC, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_vpc2007_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK(CPU_PENTIUMPRO, CPU_PENTIUM2, CPU_CYRIX3S), + .min_bus = 0, + .max_bus = 66666667, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + + { + .name = NULL, + .internal_name = NULL, + .type = MACHINE_TYPE_NONE, + .chipset = MACHINE_CHIPSET_NONE, + .init = NULL, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = 0, + .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_BUS_NONE, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 0, + .max = 0, + .step = 0 + }, + .nvrmask = 0, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + } + // clang-format on +}; + +/* 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 uint32_t machine_p1_default; +static uint32_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) +{ + return machine_p1; +} + +void +machine_set_p1_default(uint8_t val) +{ + machine_p1 = machine_p1_default = val; +} + +void +machine_set_p1(uint8_t val) +{ + machine_p1 = val; +} + +void +machine_and_p1(uint8_t val) +{ + machine_p1 = machine_p1_default & val; +} + +uint8_t +machine_handle_p1(uint8_t write, uint8_t val) +{ + uint8_t ret = 0xff; + + if (machines[machine].p1_handler) + ret = machines[machine].p1_handler(write, val); + else { + if (write) + machine_p1 = machine_p1_default & val; + else + ret = machine_p1; + } + + return ret; +} + +void +machine_init_p1(void) +{ + machine_p1 = machine_p1_default = machines[machine].kbc_p1; +} + +uint32_t +machine_get_gpio_default(void) +{ + return machine_gpio_default; +} + +uint32_t +machine_get_gpio(void) +{ + return machine_gpio; +} + +void +machine_set_gpio_default(uint32_t val) +{ + machine_gpio = machine_gpio_default = val; +} + +void +machine_set_gpio(uint32_t val) +{ + machine_gpio = val; +} + +void +machine_and_gpio(uint32_t val) +{ + machine_gpio = machine_gpio_default & val; +} + +uint32_t +machine_handle_gpio(uint8_t write, uint32_t val) +{ + uint32_t ret = 0xffffffff; + + if (machines[machine].gpio_handler) + ret = machines[machine].gpio_handler(write, val); + else { + if (write) + machine_gpio = machine_gpio_default & val; + else + ret = machine_gpio; + } + + return ret; +} + +void +machine_init_gpio(void) +{ + machine_gpio = machine_gpio_default = machines[machine].gpio; +} + +uint32_t +machine_get_gpio_acpi_default(void) +{ + return machine_gpio_acpi_default; +} + +uint32_t +machine_get_gpio_acpi(void) +{ + return machine_gpio_acpi; +} + +void +machine_set_gpio_acpi_default(uint32_t val) +{ + machine_gpio_acpi = machine_gpio_acpi_default = val; +} + +void +machine_set_gpio_acpi(uint32_t val) +{ + machine_gpio_acpi = val; +} + +void +machine_and_gpio_acpi(uint32_t val) +{ + machine_gpio_acpi = machine_gpio_acpi_default & val; +} + +uint32_t +machine_handle_gpio_acpi(uint8_t write, uint32_t val) +{ + 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 +machine_count(void) +{ + return ((sizeof(machines) / sizeof(machine_t)) - 1); +} + +const char * +machine_getname(void) +{ + return (machines[machine].name); +} + +const char * +machine_getname_ex(int m) +{ + return (machines[m].name); +} + +const device_t * +machine_get_kbc_device(int m) +{ + if (machines[m].kbc_device) + return (machines[m].kbc_device); + + return (NULL); +} + +const device_t * +machine_get_device(int m) +{ + if (machines[m].device) + return (machines[m].device); + + return (NULL); +} + +const device_t * +machine_get_fdc_device(int m) +{ + if (machines[m].fdc_device) + return (machines[m].fdc_device); + + return (NULL); +} + +const device_t * +machine_get_sio_device(int m) +{ + if (machines[m].sio_device) + return (machines[m].sio_device); + + return (NULL); +} + +const device_t * +machine_get_vid_device(int m) +{ + if (machines[m].vid_device) + return (machines[m].vid_device); + + return (NULL); +} + +const device_t * +machine_get_snd_device(int m) +{ + if (machines[m].snd_device) + return (machines[m].snd_device); + + return (NULL); +} + +const device_t * +machine_get_net_device(int m) +{ + if (machines[m].net_device) + return (machines[m].net_device); + + return (NULL); +} + +const char * +machine_get_internal_name(void) +{ + return (machines[machine].internal_name); +} + +const char * +machine_get_internal_name_ex(int m) +{ + return (machines[m].internal_name); +} + +int +machine_get_nvrmask(int m) +{ + return (machines[m].nvrmask); +} + +int +machine_has_flags(int m, int flags) +{ + int ret = machines[m].flags & flags; + + /* Can't have PS/2 ports with an AT KBC. */ + if ((flags & MACHINE_PS2_KBC) && + (machines[m].bus_flags & MACHINE_BUS_PS2_PORTS)) + ret |= MACHINE_PS2_KBC; + + return ret; +} + +int +machine_has_bus(int m, int bus_flags) +{ + int ret = machines[m].bus_flags & bus_flags; + + /* TODO: Move the KBD flags to the machine table! */ + if ((bus_flags & MACHINE_BUS_XT_KBD) && + !(machines[m].bus_flags & MACHINE_BUS_ISA16) && + (!(machines[m].bus_flags & MACHINE_BUS_PS2_PORTS) || + !(strcmp(machine_get_internal_name(), "pc5086")))) ret |= MACHINE_BUS_XT_KBD; - if ((bus_flags & MACHINE_BUS_AT_KBD) && - (IS_AT(m)) && - !(machines[m].bus_flags & MACHINE_BUS_PS2_PORTS)) +#ifdef ONLY_AT_KBD_ON_AT_KBC + if ((bus_flags & MACHINE_BUS_AT_KBD) && + (IS_AT(m)) && + !(machines[m].bus_flags & MACHINE_BUS_PS2_PORTS)) ret |= MACHINE_BUS_AT_KBD; - - return ret; -} - -int -machine_has_cartridge(int m) -{ - return (machine_has_flags(m, MACHINE_CARTRIDGE) ? 1 : 0); -} - -int -machine_get_min_ram(int m) -{ - return (machines[m].ram.min); -} - -int -machine_get_max_ram(int m) -{ -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - return MIN(((int) machines[m].ram.max), 2097152); #else - return MIN(((int) machines[m].ram.max), 3145728); + if ((bus_flags & MACHINE_BUS_AT_KBD) && (IS_AT(m))) + ret |= MACHINE_BUS_AT_KBD; #endif -} - -int -machine_get_ram_granularity(int m) -{ - return (machines[m].ram.step); -} - -int -machine_get_type(int m) -{ - return (machines[m].type); -} - -int -machine_get_machine_from_internal_name(const char *s) -{ - int c = 0; - - while (machines[c].init != NULL) { - if (!strcmp(machines[c].internal_name, s)) - return c; - c++; - } - - return 0; -} - -int -machine_has_mouse(void) -{ - return (machines[machine].flags & MACHINE_MOUSE); -} - -int -machine_is_sony(void) -{ - return (!strcmp(machines[machine].internal_name, "pcv90")); -} - -const char * -machine_get_nvr_name_ex(int m) -{ - const char *ret = machines[m].internal_name; - const device_t *dev = machine_get_device(m); - - if (dev != NULL) { - device_context(dev); - const char *bios = device_get_config_string("bios"); - if ((bios != NULL) && (strcmp(bios, "") != 0)) - ret = bios; - device_context_restore(); - } - - return ret; -} - -const char * -machine_get_nvr_name(void) -{ - return machine_get_nvr_name_ex(machine); -} + + return ret; +} + +int +machine_has_cartridge(int m) +{ + return (machine_has_flags(m, MACHINE_CARTRIDGE) ? 1 : 0); +} + +int +machine_get_min_ram(int m) +{ + return (machines[m].ram.min); +} + +int +machine_get_max_ram(int m) +{ +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) + return MIN(((int) machines[m].ram.max), 2097152); +#else + return MIN(((int) machines[m].ram.max), 3145728); +#endif +} + +int +machine_get_ram_granularity(int m) +{ + return (machines[m].ram.step); +} + +int +machine_get_type(int m) +{ + return (machines[m].type); +} + +int +machine_get_chipset(int m) +{ + return (machines[m].chipset); +} + +int +machine_get_machine_from_internal_name(const char *s) +{ + int c = 0; + + while (machines[c].init != NULL) { + if (!strcmp(machines[c].internal_name, s)) + return c; + c++; + } + + return 0; +} + +int +machine_has_mouse(void) +{ + return (machines[machine].flags & MACHINE_MOUSE); +} + +int +machine_is_sony(void) +{ + return (!strcmp(machines[machine].internal_name, "pcv90")); +} + +const char * +machine_get_nvr_name_ex(int m) +{ + const char *ret = machines[m].internal_name; + const device_t *dev = machine_get_device(m); + + if (dev != NULL) { + device_context(dev); + const char *bios = device_get_config_string("bios"); + if ((bios != NULL) && (strcmp(bios, "") != 0)) + ret = bios; + device_context_restore(); + } + + return ret; +} + +const char * +machine_get_nvr_name(void) +{ + return machine_get_nvr_name_ex(machine); +} + diff --git a/src/machine_status.c b/src/machine_status.c index 3eb2762bc..c1396975d 100644 --- a/src/machine_status.c +++ b/src/machine_status.c @@ -16,7 +16,7 @@ #include <86box/cartridge.h> #include <86box/cassette.h> #include <86box/cdrom.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/mo.h> #include <86box/hdd.h> #include <86box/thread.h> @@ -36,9 +36,9 @@ machine_status_init(void) machine_status.cdrom[i].empty = (strlen(cdrom[i].image_path) == 0); machine_status.cdrom[i].active = false; } - for (size_t i = 0; i < ZIP_NUM; i++) { - machine_status.zip[i].empty = (strlen(zip_drives[i].image_path) == 0); - machine_status.zip[i].active = false; + for (size_t i = 0; i < RDISK_NUM; i++) { + machine_status.rdisk[i].empty = (strlen(rdisk_drives[i].image_path) == 0); + machine_status.rdisk[i].active = false; } for (size_t i = 0; i < MO_NUM; i++) { machine_status.mo[i].empty = (strlen(mo_drives[i].image_path) == 0); diff --git a/src/mem/catalyst_flash.c b/src/mem/catalyst_flash.c index 00e2422a3..5c8812464 100644 --- a/src/mem/catalyst_flash.c +++ b/src/mem/catalyst_flash.c @@ -29,6 +29,7 @@ #include <86box/timer.h> #include <86box/nvr.h> #include <86box/plat.h> +#include <86box/plat_fallthrough.h> #define FLAG_WORD 4 #define FLAG_BXB 2 @@ -44,21 +45,22 @@ enum { }; enum { - CMD_SET_READ = 0x00, - CMD_READ_SIGNATURE = 0x90, - CMD_ERASE = 0x20, - CMD_ERASE_CONFIRM = 0x20, - CMD_ERASE_VERIFY = 0xA0, - CMD_PROGRAM = 0x40, - CMD_PROGRAM_VERIFY = 0xC0, - CMD_RESET = 0xFF + CMD_SET_READ = 0x00, + CMD_READ_AUTO_SELECT = 0x80, + CMD_READ_SIGNATURE = 0x90, + CMD_ERASE = 0x20, + CMD_ERASE_CONFIRM = 0x20, + CMD_ERASE_VERIFY = 0xA0, + CMD_PROGRAM = 0x40, + CMD_PROGRAM_VERIFY = 0xC0, + CMD_RESET = 0xFF }; typedef struct flash_t { uint8_t command; + uint8_t is_amd; uint8_t pad; uint8_t pad0; - uint8_t pad1; uint8_t *array; mem_mapping_t mapping; @@ -83,11 +85,22 @@ flash_read(uint32_t addr, void *priv) ret = dev->array[addr]; break; + case CMD_READ_AUTO_SELECT: + if (!dev->is_amd) + break; + fallthrough; case CMD_READ_SIGNATURE: - if (addr == 0x00000) - ret = 0x31; /* CATALYST */ - else if (addr == 0x00001) - ret = 0xB4; /* 28F010 */ + if (dev->is_amd) { + if (addr == 0x00000) + ret = 0x01; /* AMD */ + else if (addr == 0x00001) + ret = 0xa7; /* Am28F010 */ + } else { + if (addr == 0x00000) + ret = 0x31; /* CATALYST */ + else if (addr == 0x00001) + ret = 0xb4; /* 28F010 */ + } break; default: @@ -205,6 +218,7 @@ catalyst_flash_init(UNUSED(const device_t *info)) catalyst_flash_add_mappings(dev); dev->command = CMD_RESET; + dev->is_amd = info->local; fp = nvr_fopen(flash_path, "rb"); if (fp) { @@ -244,3 +258,17 @@ const device_t catalyst_flash_device = { .force_redraw = NULL, .config = NULL }; + +const device_t amd_am28f010_flash_device = { + .name = "AMD Am28F010-D Flash BIOS", + .internal_name = "amd_am28f010_flash", + .flags = DEVICE_PCI, + .local = 1, + .init = catalyst_flash_init, + .close = catalyst_flash_close, + .reset = catalyst_flash_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/mem/mem.c b/src/mem/mem.c index 8c2cfd6cc..a544f333c 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -67,7 +67,9 @@ mem_mapping_t bios_mapping; mem_mapping_t bios_high_mapping; page_t *pages; /* RAM page table */ +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) page_t **page_lookup; /* pagetable lookup */ +#endif uint32_t pages_sz; /* #pages in table */ uint8_t *ram; /* the virtual RAM */ @@ -85,12 +87,23 @@ uint8_t *pccache2; int readlnext; int readlookup[256]; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) uintptr_t *readlookup2; +#endif uintptr_t old_rl2; uint8_t uncached = 0; int writelnext; int writelookup[256]; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) uintptr_t *writelookup2; +#endif + +#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) +/* The lookup tables. */ +page_t *page_lookup[1048576] = { 0 }; +uintptr_t readlookup2[1048576] = { 0 }; +uintptr_t writelookup2[1048576] = { 0 }; +#endif uint32_t mem_logical_addr; @@ -108,7 +121,6 @@ int mem_a20_alt = 0; int mem_a20_state = 0; int mmuflush = 0; -int mmu_perm = 4; #ifdef USE_NEW_DYNAREC uint64_t *byte_dirty_mask; @@ -125,10 +137,6 @@ mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; uint8_t *_mem_exec[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_bus[MEM_MAPPINGS_NO]; @@ -187,10 +195,8 @@ resetreadlookup(void) /* Initialize the tables for high (> 1024K) RAM. */ memset(readlookup2, 0xff, (1 << 20) * sizeof(uintptr_t)); - memset(readlookupp, 0x04, (1 << 20) * sizeof(uint8_t)); memset(writelookup2, 0xff, (1 << 20) * sizeof(uintptr_t)); - memset(writelookupp, 0x04, (1 << 20) * sizeof(uint8_t)); readlnext = 0; writelnext = 0; @@ -204,14 +210,11 @@ flushmmucache(void) for (uint16_t c = 0; c < 256; c++) { if (readlookup[c] != (int) 0xffffffff) { readlookup2[readlookup[c]] = LOOKUP_INV; - readlookupp[readlookup[c]] = 4; readlookup[c] = 0xffffffff; } if (writelookup[c] != (int) 0xffffffff) { page_lookup[writelookup[c]] = NULL; - page_lookupp[writelookup[c]] = 4; writelookup2[writelookup[c]] = LOOKUP_INV; - writelookupp[writelookup[c]] = 4; writelookup[c] = 0xffffffff; } } @@ -231,9 +234,7 @@ flushmmucache_write(void) for (uint16_t c = 0; c < 256; c++) { if (writelookup[c] != (int) 0xffffffff) { page_lookup[writelookup[c]] = NULL; - page_lookupp[writelookup[c]] = 4; writelookup2[writelookup[c]] = LOOKUP_INV; - writelookupp[writelookup[c]] = 4; writelookup[c] = 0xffffffff; } } @@ -259,14 +260,11 @@ flushmmucache_nopc(void) for (uint16_t c = 0; c < 256; c++) { if (readlookup[c] != (int) 0xffffffff) { readlookup2[readlookup[c]] = LOOKUP_INV; - readlookupp[readlookup[c]] = 4; readlookup[c] = 0xffffffff; } if (writelookup[c] != (int) 0xffffffff) { page_lookup[writelookup[c]] = NULL; - page_lookupp[writelookup[c]] = 4; writelookup2[writelookup[c]] = LOOKUP_INV; - writelookupp[writelookup[c]] = 4; writelookup[c] = 0xffffffff; } } @@ -348,7 +346,6 @@ mmutranslatereal_normal(uint32_t addr, int rw) return 0xffffffffffffffffULL; } - mmu_perm = temp & 4; rammap(addr2) |= (rw ? 0x60 : 0x20); uint64_t page = temp & ~0x3fffff; @@ -371,7 +368,6 @@ mmutranslatereal_normal(uint32_t addr, int rw) return 0xffffffffffffffffULL; } - mmu_perm = temp & 4; rammap(addr2) |= 0x20; rammap((temp2 & ~0xfff) + ((addr >> 10) & 0xffc)) |= (rw ? 0x60 : 0x20); @@ -435,7 +431,6 @@ mmutranslatereal_pae(uint32_t addr, int rw) return 0xffffffffffffffffULL; } - mmu_perm = temp & 4; rammap64(addr3) |= (rw ? 0x60 : 0x20); return ((temp & ~0x1fffffULL) + (addr & 0x1fffffULL)) & 0x000000ffffffffffULL; @@ -456,7 +451,6 @@ mmutranslatereal_pae(uint32_t addr, int rw) return 0xffffffffffffffffULL; } - mmu_perm = temp & 4; rammap64(addr3) |= 0x20; rammap64(addr4) |= (rw ? 0x60 : 0x20); @@ -631,7 +625,6 @@ addreadlookup(uint32_t virt, uint32_t phys) else readlookup2[virt >> 12] = (uintptr_t) &ram[a]; #endif - readlookupp[virt >> 12] = mmu_perm; readlookup[readlnext++] = virt >> 12; readlnext &= (cachesize - 1); @@ -671,7 +664,6 @@ addwritelookup(uint32_t virt, uint32_t phys) # endif #endif page_lookup[virt >> 12] = &pages[phys >> 12]; - page_lookupp[virt >> 12] = mmu_perm; } else { #if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) writelookup2[virt >> 12] = (uintptr_t) &ram[(uintptr_t) (phys & ~0xFFF) - (uintptr_t) (virt & ~0xfff)]; @@ -684,7 +676,6 @@ addwritelookup(uint32_t virt, uint32_t phys) writelookup2[virt >> 12] = (uintptr_t) &ram[a]; #endif } - writelookupp[virt >> 12] = mmu_perm; writelookup[writelnext++] = virt >> 12; writelnext &= (cachesize - 1); @@ -973,10 +964,8 @@ readmemwl(uint32_t addr) } return readmembl_no_mmut(addr, addr64a[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, addr64a[1])) << 8); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) return *(uint16_t *) (readlookup2[addr >> 12] + addr); - } } if (cr0 >> 31) { @@ -1044,7 +1033,6 @@ writememwl(uint32_t addr, uint16_t val) writemembl_no_mmut(addr + 1, addr64a[1], val >> 8); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; *(uint16_t *) (writelookup2[addr >> 12] + addr) = val; return; } @@ -1052,7 +1040,6 @@ writememwl(uint32_t addr, uint16_t val) if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) { page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]); - mmu_perm = page_lookupp[addr >> 12]; return; } @@ -1100,10 +1087,8 @@ readmemwl_no_mmut(uint32_t addr, uint32_t *a64) } return readmembl_no_mmut(addr, a64[0]) | (((uint16_t) readmembl_no_mmut(addr + 1, a64[1])) << 8); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) return *(uint16_t *) (readlookup2[addr >> 12] + addr); - } } if (cr0 >> 31) { @@ -1149,14 +1134,12 @@ writememwl_no_mmut(uint32_t addr, uint32_t *a64, uint16_t val) writemembl_no_mmut(addr + 1, a64[1], val >> 8); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; *(uint16_t *) (writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_w) { - mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]); return; } @@ -1231,10 +1214,8 @@ readmemll(uint32_t addr) /* 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); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) return *(uint32_t *) (readlookup2[addr >> 12] + addr); - } } if (cr0 >> 31) { @@ -1316,14 +1297,12 @@ writememll(uint32_t addr, uint32_t val) writememwl_no_mmut(addr + 2, &(addr64a[2]), val >> 16); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; *(uint32_t *) (writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { - mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); return; } @@ -1378,10 +1357,8 @@ readmemll_no_mmut(uint32_t addr, uint32_t *a64) } return readmemwl_no_mmut(addr, a64) | ((uint32_t) (readmemwl_no_mmut(addr + 2, &(a64[2]))) << 16); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) return *(uint32_t *) (readlookup2[addr >> 12] + addr); - } } if (cr0 >> 31) { @@ -1429,14 +1406,12 @@ writememll_no_mmut(uint32_t addr, uint32_t *a64, uint32_t val) writememwl_no_mmut(addr + 2, &(a64[2]), val >> 16); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; *(uint32_t *) (writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { - mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); return; } @@ -1516,10 +1491,8 @@ readmemql(uint32_t addr) /* 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); - } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = readlookupp[addr >> 12]; + } else if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) return *(uint64_t *) (readlookup2[addr >> 12] + addr); - } } if (cr0 >> 31) { @@ -1611,14 +1584,12 @@ writememql(uint32_t addr, uint64_t val) writememll_no_mmut(addr + 4, &(addr64a[4]), val >> 32); return; } else if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) { - mmu_perm = writelookupp[addr >> 12]; *(uint64_t *) (writelookup2[addr >> 12] + addr) = val; return; } } if (page_lookup[addr >> 12] && page_lookup[addr >> 12]->write_l) { - mmu_perm = page_lookupp[addr >> 12]; page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); page_lookup[addr >> 12]->write_l(addr + 4, val >> 32, page_lookup[addr >> 12]); return; @@ -1702,8 +1673,7 @@ do_mmutranslate(uint32_t addr, uint32_t *a64, int num, int write) a = (a & 0xfffffffffffff000ULL) | ((uint64_t) (addr & 0xfff)); a64[i] = (uint32_t) a; } - } else - mmu_perm = page_lookupp[addr >> 12]; + } addr++; } @@ -1870,6 +1840,9 @@ mem_read_ram(uint32_t addr, UNUSED(void *priv)) mem_log("Read B %02X from %08X\n", ram[addr], addr); #endif + if (is_pcjr) + pcjr_waitstates(NULL); + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); @@ -2130,6 +2103,9 @@ mem_write_ram(uint32_t addr, uint8_t val, UNUSED(void *priv)) if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write B %02X to %08X\n", val, addr); #endif + if (is_pcjr) + pcjr_waitstates(NULL); + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[addr >> 12]); @@ -2914,7 +2890,6 @@ mem_reset(void) pages = (page_t *) malloc(m * sizeof(page_t)); memset(page_lookup, 0x00, (1 << 20) * sizeof(page_t *)); - memset(page_lookupp, 0x04, (1 << 20) * sizeof(uint8_t)); memset(pages, 0x00, pages_sz * sizeof(page_t)); @@ -3031,20 +3006,32 @@ mem_init(void) ram2 = NULL; pages = NULL; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) /* Allocate the lookup tables. */ page_lookup = (page_t **) malloc((1 << 20) * sizeof(page_t *)); - page_lookupp = (uint8_t *) malloc((1 << 20) * sizeof(uint8_t)); readlookup2 = malloc((1 << 20) * sizeof(uintptr_t)); - readlookupp = malloc((1 << 20) * sizeof(uint8_t)); writelookup2 = malloc((1 << 20) * sizeof(uintptr_t)); - writelookupp = malloc((1 << 20) * sizeof(uint8_t)); +#endif } -static void -umc_page_recalc(uint32_t c, int set) +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) +void +mem_free(void) { + free(page_lookup); + free(readlookup2); + free(writelookup2); +} +#endif + + +static void +umc_page_recalc(uint32_t c, uint32_t phys, int set) +{ + uint32_t target = set ? phys : c; + if (set) { - pages[c].mem = &ram[(c & 0xff) << 12]; + pages[c].mem = &ram[(target & 0xff) << 12]; pages[c].write_b = mem_write_ramb_page; pages[c].write_w = mem_write_ramw_page; pages[c].write_l = mem_write_raml_page; @@ -3057,8 +3044,8 @@ umc_page_recalc(uint32_t c, int set) #ifdef USE_NEW_DYNAREC pages[c].evict_prev = EVICT_NOT_IN_LIST; - pages[c].byte_dirty_mask = &byte_dirty_mask[(c & 0xff) * 64]; - pages[c].byte_code_present_mask = &byte_code_present_mask[(c & 0xff) * 64]; + pages[c].byte_dirty_mask = &byte_dirty_mask[(target & 0xff) * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[(target & 0xff) * 64]; #endif } @@ -3066,7 +3053,7 @@ void umc_smram_recalc(uint32_t start, int set) { for (uint32_t c = start; c < (start + 0x0020); c++) - umc_page_recalc(c, set); + umc_page_recalc(c, c - start + 0x000a0000, set); } static void diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index 1a2782237..ebf062d95 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -211,7 +211,6 @@ mmutranslatereal_2386(uint32_t addr, int rw) return 0xffffffffffffffffULL; } - mmu_perm = temp & 4; mem_writel_map(addr2, mem_readl_map(addr2) | (rw ? 0x60 : 0x20)); return (temp & ~0x3fffff) + (addr & 0x3fffff); @@ -231,7 +230,6 @@ mmutranslatereal_2386(uint32_t addr, int rw) 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)); diff --git a/src/mem/rom.c b/src/mem/rom.c index 666652d53..f7b2b2b0d 100644 --- a/src/mem/rom.c +++ b/src/mem/rom.c @@ -97,7 +97,8 @@ rom_check(const char *fn) else { fp = fopen(fn, "rb"); ret = (fp != NULL); - fclose(fp); + if (fp != NULL) + fclose(fp); } return ret; @@ -134,6 +135,9 @@ rom_fopen(const char *fn, char *mode) char temp[1024]; FILE *fp = NULL; + if ((fn == NULL) || (mode == NULL)) + return NULL; + if (strstr(fn, "roms/") == fn) { /* Relative path */ for (rom_path_t *rom_path = &rom_paths; rom_path != NULL; rom_path = rom_path->next) { @@ -320,11 +324,12 @@ rom_load_linear_oddeven(const char *fn, uint32_t addr, int sz, int off, uint8_t } for (int i = 0; i < (sz >> 1); i++) { if (fread(ptr + (addr + (i << 1) + 1), 1, 1, fp) != 1) - fatal("rom_load_linear(): Error reading od data\n"); + fatal("rom_load_linear(): Error reading odd data\n"); } } - (void) fclose(fp); + if (fp != NULL) + (void) fclose(fp); return 1; } @@ -353,7 +358,8 @@ rom_load_linear(const char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) fatal("rom_load_linear(): Error reading data\n"); } - (void) fclose(fp); + if (fp != NULL) + (void) fclose(fp); return 1; } @@ -397,7 +403,8 @@ rom_load_linear_inverted(const char *fn, uint32_t addr, int sz, int off, uint8_t } } - (void) fclose(fp); + if (fp != NULL) + (void) fclose(fp); return 1; } @@ -438,8 +445,10 @@ rom_load_interleaved(const char *fnl, const char *fnh, uint32_t addr, int sz, in } } - (void) fclose(fph); - (void) fclose(fpl); + if (fph != NULL) + (void) fclose(fph); + if (fpl != NULL) + (void) fclose(fpl); return 1; } diff --git a/src/mem/smram.c b/src/mem/smram.c index afbc5475c..928760f3a 100644 --- a/src/mem/smram.c +++ b/src/mem/smram.c @@ -59,9 +59,12 @@ smram_read(uint32_t addr, void *priv) const smram_t *dev = (smram_t *) priv; uint32_t new_addr = addr - dev->host_base + dev->ram_base; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) if (new_addr >= (1 << 30)) return mem_read_ram_2gb(new_addr, priv); - else if (!use_separate_smram || (new_addr >= 0xa0000)) + else +#endif + if (!use_separate_smram || (new_addr >= 0xa0000)) return mem_read_ram(new_addr, priv); else return dev->mapping.exec[addr - dev->host_base]; @@ -73,9 +76,12 @@ smram_readw(uint32_t addr, void *priv) smram_t *dev = (smram_t *) priv; uint32_t new_addr = addr - dev->host_base + dev->ram_base; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) if (new_addr >= (1 << 30)) return mem_read_ram_2gbw(new_addr, priv); - else if (!use_separate_smram || (new_addr >= 0xa0000)) + else +#endif + if (!use_separate_smram || (new_addr >= 0xa0000)) return mem_read_ramw(new_addr, priv); else return *(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]); @@ -87,9 +93,12 @@ smram_readl(uint32_t addr, void *priv) smram_t *dev = (smram_t *) priv; uint32_t new_addr = addr - dev->host_base + dev->ram_base; +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) if (new_addr >= (1 << 30)) return mem_read_ram_2gbl(new_addr, priv); - else if (!use_separate_smram || (new_addr >= 0xa0000)) + else +#endif + if (!use_separate_smram || (new_addr >= 0xa0000)) return mem_read_raml(new_addr, priv); else return *(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]); diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 71f41f059..82d332e20 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -58,6 +58,18 @@ if(WIN32) target_link_libraries(86Box ws2_32) endif() +if(NETSWITCH) + add_compile_definitions(USE_NETSWITCH) + list(APPEND net_sources + net_netswitch.c + netswitch.c + pb_common.c + pb_encode.c + pb_decode.c + networkmessage.pb.c + ) +endif() + if (UNIX) find_path(HAS_VDE "libvdeplug.h" PATHS ${VDE_INCLUDE_DIR} "/usr/include /usr/local/include" "/opt/homebrew/include" ) if(HAS_VDE) @@ -70,5 +82,14 @@ if (UNIX) endif() endif() endif() +if (UNIX AND NOT APPLE) # Support for TAP on Linux and BSD, supposedly. + find_path(HAS_TAP "linux/if_tun.h" PATHS ${TAP_INCLUDE_DIR} "/usr/include /usr/local/include" "/opt/homebrew/include" ) + if(HAS_TAP) + add_compile_definitions(HAS_TAP) + list(APPEND net_sources net_tap.c) + else() + message(WARNING "TAP support not available. Are you on some BSD?") + endif() +endif() add_library(net OBJECT ${net_sources}) diff --git a/src/network/net_3c503.c b/src/network/net_3c503.c index b35e0d453..ea64633bc 100644 --- a/src/network/net_3c503.c +++ b/src/network/net_3c503.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -720,7 +721,7 @@ static const device_config_t threec503_config[] = { }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xCC000, diff --git a/src/network/net_dp8390.c b/src/network/net_dp8390.c index 623dec56c..a0e0e7129 100644 --- a/src/network/net_dp8390.c +++ b/src/network/net_dp8390.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -198,6 +199,11 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val) if (dev->TCR.loop_cntl) { dp8390_rx_common(dev, &dev->mem[((dev->tx_page_start * 256) - dev->mem_start) & dev->mem_wrap], dev->tx_bytes); + + if (dev->IMR.rx_inte && !dev->ISR.pkt_tx && dev->interrupt) + dev->interrupt(dev->priv, 1); + + dev->ISR.pkt_tx = 1; } } else if (val & 0x04) { if (dev->CR.stop || (!dev->CR.start && (dev->flags & DP8390_FLAG_CHECK_CR))) { @@ -220,12 +226,6 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val) if (!(dev->card->link_state & NET_LINK_DOWN)) network_tx(dev->card, &dev->mem[((dev->tx_page_start * 256) - dev->mem_start) & dev->mem_wrap], dev->tx_bytes); - /* some more debug */ -#ifdef ENABLE_DP8390_LOG - if (dev->tx_timer_active) - dp8390_log("DP8390: CR write, tx timer still active\n"); -#endif - dp8390_tx(dev, val); } @@ -247,12 +247,12 @@ dp8390_tx(dp8390_t *dev, UNUSED(uint32_t val)) { dev->CR.tx_packet = 0; dev->TSR.tx_ok = 1; - dev->ISR.pkt_tx = 1; /* Generate an interrupt if not masked */ - if (dev->IMR.tx_inte && dev->interrupt) + if (dev->IMR.tx_inte && !dev->ISR.pkt_tx && dev->interrupt) dev->interrupt(dev->priv, 1); - dev->tx_timer_active = 0; + + dev->ISR.pkt_tx = 1; } /* @@ -960,7 +960,6 @@ dp8390_reset(dp8390_t *dev) memset(&dev->TCR, 0x00, sizeof(dev->TCR)); memset(&dev->TSR, 0x00, sizeof(dev->TSR)); memset(&dev->RSR, 0x00, sizeof(dev->RSR)); - dev->tx_timer_active = 0; dev->local_dma = 0; dev->page_start = 0; dev->page_stop = 0; diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index e45b55b22..0174ef098 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -933,7 +934,7 @@ nic_init(const device_t *info) if (dev->board != NE2K_ETHERNEXT_MC) { dev->base_address = device_get_config_hex16("base"); dev->base_irq = device_get_config_int("irq"); - if ((dev->board == NE2K_NE2000) || (dev->board == NE2K_NE2000_COMPAT) || + if ((dev->board == NE2K_NE2000) || (dev->board == NE2K_NE2000_COMPAT) || (dev->board == NE2K_NE2000_COMPAT_8BIT) ) { dev->bios_addr = device_get_config_hex20("bios_addr"); dev->has_bios = !!dev->bios_addr; @@ -1061,7 +1062,7 @@ nic_init(const device_t *info) break; } - + if (set_oui) { /* See if we have a local MAC address configured. */ mac_oui = device_get_config_mac("mac_oui", -1); @@ -1411,7 +1412,7 @@ static const device_config_t ne2000_config[] = { }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0, @@ -1509,7 +1510,7 @@ static const device_config_t ne2000_compat_config[] = { }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0, @@ -1601,7 +1602,7 @@ static const device_config_t ne2000_compat_8bit_config[] = { }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0, @@ -1742,7 +1743,7 @@ const device_t ne2000_compat_device = { const device_t ne2000_compat_8bit_device = { .name = "NE2000 Compatible 8-bit", .internal_name = "ne2k8", - .flags = DEVICE_ISA, + .flags = DEVICE_ISA, .local = NE2K_NE2000_COMPAT_8BIT, .init = nic_init, .close = nic_close, diff --git a/src/network/net_netswitch.c b/src/network/net_netswitch.c new file mode 100644 index 000000000..336895dc6 --- /dev/null +++ b/src/network/net_netswitch.c @@ -0,0 +1,500 @@ +/* +* 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. +* +* Network Switch network driver +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed + */ + + +#include +#include +#include +#include +#include +#include +#include +#ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN +# include +# include +#else +# include +#endif + +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/thread.h> +#include <86box/timer.h> +#include <86box/network.h> +#include <86box/net_event.h> +#include "netswitch.h" +#include "networkmessage.pb.h" + +enum { + NET_EVENT_STOP = 0, + NET_EVENT_TX, + NET_EVENT_RX, + NET_EVENT_SWITCH, + NET_EVENT_MAX +}; + +/* Special define for the windows portion. We only need to poll up to + * NET_EVENT_SWITCH. NET_EVENT_SWITCH gives us a different NET_EVENT_MAX + * excluding the others, and windows does not like polling events that + * do not exist. */ +#define NET_EVENT_WIN_MAX NET_EVENT_SWITCH + +#define SWITCH_PKT_BATCH NET_QUEUE_LEN +/* In µs, how often to send a keepalive and perform connection maintenance */ +#define SWITCH_KEEPALIVE_INTERVAL 5000000 +/* In ms, how long until we consider a connection gone? */ +#define SWITCH_MAX_INTERVAL 10000 + +typedef struct { + void *nsconn; + uint8_t mac_addr[6]; + netcard_t *card; + thread_t *poll_tid; + net_evt_t tx_event; + net_evt_t stop_event; + netpkt_t pktv[SWITCH_PKT_BATCH]; + pc_timer_t stats_timer; + pc_timer_t maintenance_timer; + ns_rx_packet_t rx_packet; + char switch_type[16]; +#ifdef _WIN32 + HANDLE sock_event; +#endif +} net_netswitch_t; + +// Used for debugging, needs to be moved to an official location +void print_packet(const netpkt_t netpkt) { +#ifdef NET_SWITCH_LOG + if(netpkt.len == 0) { + net_switch_log("Something is wrong, len is %d\n", netpkt.len); + return; + } + /* Temporarily disable log suppression for packet dumping to allow specific formatting */ + pclog_toggle_suppr(); + uint8_t linebuff[17] = "\0"; + char src_mac_buf[32] = ""; + char dst_mac_buf[32] = ""; + for(int m_i=0; m_i < 6; m_i++) { + char src_octet[4]; + char dst_octet[4]; + snprintf(src_octet, sizeof(src_octet), "%02X%s", netpkt.data[m_i+6], m_i < 5 ? ":" : ""); + strncat(src_mac_buf, src_octet, sizeof (src_mac_buf) - 1); + + snprintf(dst_octet, sizeof(dst_octet), "%02X%s", netpkt.data[m_i], m_i < 5 ? ":" : ""); + strncat(dst_mac_buf, dst_octet, sizeof (dst_mac_buf) - 1); + } + net_switch_log("%s -> %s\n\n", src_mac_buf, dst_mac_buf); + + // Payload length (bytes 12-13 with zero index) + uint16_t payload_length = (netpkt.data[12] & 0xFF) << 8; + payload_length |= (netpkt.data[13] & 0xFF); + const uint16_t actual_length = netpkt.len - 14; + if(payload_length <= 1500) { + // 802.3 / 802.2 + net_switch_log("Payload length according to frame: %i\n", payload_length); + // remaining length of packet (len - 14) to calculate padding + net_switch_log("Actual payload length: %i\n", actual_length); + if(payload_length <=46 ) { + net_switch_log("Likely has %d bytes padding\n", actual_length - payload_length); + } + } else { + // Type II + net_switch_log("EtherType: 0x%04X\n", payload_length); + } + // actual packet size + net_switch_log("Full frame size: %i\n", netpkt.len); + net_switch_log("\n"); + + for(int i=0; i< netpkt.len; i++) { + + net_switch_log("%02x ", netpkt.data[i]); + if ((netpkt.data[i] < 0x20) || (netpkt.data[i] > 0x7e)) { + linebuff[i % 16] = '.'; + } else { + linebuff[i % 16] = netpkt.data[i]; + } + + if( (i+1) % 8 == 0) { + net_switch_log(" "); + } + + if( (i+1) % 16 == 0) { + net_switch_log("| %s |\n", (char *)linebuff); + linebuff[0] = '\0'; + } + + // last char? + if(i+1 == netpkt.len) { + const int togo = 16 - (i % 16); + for(int remaining = 0; remaining < togo-1; remaining++) { + // This would represent the byte display and the space + net_switch_log(" "); + } + // spacing between byte groupings + if(togo > 8) { + net_switch_log(" "); + } + linebuff[(i % 16) +1] = '\0'; + net_switch_log(" | %s", (char *)linebuff); + + for(int remaining = 0; remaining < togo-1; remaining++) { + // This would represent the remaining bytes on the right + net_switch_log(" "); + } + net_switch_log(" |\n"); + } + } + net_switch_log("\n"); + pclog_toggle_suppr(); +#endif /* NET_SWITCH_LOG*/ +} + +#ifdef ENABLE_NET_SWITCH_STATS +static void +stats_timer(void *priv) +{ + /* Get the device state structure. */ + net_netswitch_t *netswitch = priv; + const NSCONN *nsconn = netswitch->nsconn; + net_switch_log("Max (frame / packet) TX (%zu/%zu) RX (%zu/%zu)\n", + nsconn->stats.max_tx_frame, nsconn->stats.max_tx_packet, + nsconn->stats.max_rx_frame, nsconn->stats.max_rx_packet); + net_switch_log("Last ethertype (TX/RX) (%02x%02x/%02x%02x)\n", nsconn->stats.last_tx_ethertype[0], nsconn->stats.last_tx_ethertype[1], + nsconn->stats.last_rx_ethertype[0], nsconn->stats.last_rx_ethertype[1]); + net_switch_log("Packet totals (all/tx/rx/would fragment/max vec) (%zu/%zu/%zu/%zu/%i)\n", nsconn->stats.total_tx_packets + nsconn->stats.total_rx_packets, + nsconn->stats.total_tx_packets, nsconn->stats.total_rx_packets, nsconn->stats.total_fragments, nsconn->stats.max_vec); + net_switch_log("---\n"); + /* Restart the timer */ + timer_on_auto(&netswitch->stats_timer, 60000000); +} +#endif + +static void +maintenance_timer(void *priv) +{ + /* Get the device state structure. */ + net_netswitch_t *netswitch = (net_netswitch_t *) priv; + NSCONN *nsconn = (NSCONN *) netswitch->nsconn; + if (!ns_send_control(nsconn, MessageType_MESSAGE_TYPE_KEEPALIVE)) { + net_switch_log("Failed to send keepalive packet\n"); + } + const int64_t interval = ns_get_current_millis() - nsconn->last_packet_stamp; +// net_switch_log("Last packet time: %lld ago\n", interval); +// net_switch_log("Last packet time: %lld ago\n", interval); + + /* A timeout has likely occurred, try to fix the connection if type is REMOTE */ + if((interval > SWITCH_MAX_INTERVAL) && nsconn->switch_type == SWITCH_TYPE_REMOTE) { + /* FIXME: This is really rough, needs moar logic */ + nsconn->client_state = CONNECTING; + net_switch_log("We appear to be disconnected, attempting to reconnect\n"); + /* TODO: Proper connect function! This is duplicated code */ + if(!ns_send_control(nsconn, MessageType_MESSAGE_TYPE_CONNECT_REQUEST)) { + /* TODO: Failure */ + } + } + /* Restart the timer */ + timer_on_auto(&netswitch->maintenance_timer, SWITCH_KEEPALIVE_INTERVAL); +} + +/* Lots of #ifdef madness here thanks to the polling differences on windows */ +static void +net_netswitch_thread(void *priv) +{ + net_netswitch_t *net_netswitch = (net_netswitch_t *) priv; + NSCONN *nsconn = (NSCONN *) net_netswitch->nsconn; + bool status; + char switch_type[32]; + snprintf(switch_type, sizeof(switch_type), "%s", nsconn->switch_type == SWITCH_TYPE_REMOTE ? "Remote" : "Local"); + + net_switch_log("%s Net Switch: polling started.\n", switch_type); + +#ifdef _WIN32 + WSAEventSelect(ns_pollfd(net_netswitch->nsconn), net_netswitch->sock_event, FD_READ); + + HANDLE events[NET_EVENT_MAX]; + events[NET_EVENT_STOP] = net_event_get_handle(&net_netswitch->stop_event); + events[NET_EVENT_TX] = net_event_get_handle(&net_netswitch->tx_event); + events[NET_EVENT_RX] = net_netswitch->sock_event; + + bool run = true; +#else + struct pollfd pfd[NET_EVENT_MAX]; + pfd[NET_EVENT_STOP].fd = net_event_get_fd(&net_netswitch->stop_event); + pfd[NET_EVENT_STOP].events = POLLIN | POLLPRI; + + pfd[NET_EVENT_TX].fd = net_event_get_fd(&net_netswitch->tx_event); + pfd[NET_EVENT_TX].events = POLLIN | POLLPRI; + + pfd[NET_EVENT_RX].fd = ns_pollfd(net_netswitch->nsconn); + pfd[NET_EVENT_RX].events = POLLIN | POLLPRI; +#endif + +#ifdef _WIN32 + while (run) { + int ret = WaitForMultipleObjects(NET_EVENT_WIN_MAX, events, FALSE, INFINITE); + + switch (ret - WAIT_OBJECT_0) { +#else + while (1) { + poll(pfd, NET_EVENT_MAX, -1); +#endif + +#ifdef _WIN32 + case NET_EVENT_STOP: + net_event_clear(&net_netswitch->stop_event); + run = false; + break; + case NET_EVENT_TX: +#else + if (pfd[NET_EVENT_STOP].revents & POLLIN) { + net_event_clear(&net_netswitch->stop_event); + break; + } + if (pfd[NET_EVENT_TX].revents & POLLIN) { +#endif + net_event_clear(&net_netswitch->tx_event); + + const int packets = network_tx_popv(net_netswitch->card, net_netswitch->pktv, SWITCH_PKT_BATCH); + if (packets > nsconn->stats.max_vec) { + nsconn->stats.max_vec = packets; + } + for (int i = 0; i < packets; i++) { + // net_switch_log("%d packet(s) to send\n", packets); +#if defined(NET_PRINT_PACKET_TX) || defined(NET_PRINT_PACKET_ALL) + data_packet_info_t packet_info = get_data_packet_info(&net_netswitch->pktv[i], net_netswitch->mac_addr); + /* Temporarily disable log suppression for packet logging */ + pclog_toggle_suppr(); + net_switch_log("%s Net Switch: TX: %s\n", switch_type, packet_info.printable); + pclog_toggle_suppr(); + print_packet(net_netswitch->pktv[i]); +#endif + /* Only send if we're in a connected state (always true for local) */ + if(ns_connected(net_netswitch->nsconn)) { + const ssize_t nc = ns_send_pb(net_netswitch->nsconn, &net_netswitch->pktv[i], 0); + if (nc < 1) { + perror("Got"); + net_switch_log("%s Net Switch: Problem, no bytes sent. Got back %i\n", switch_type, nc); + } + } + } +#ifdef _WIN32 + break; + case NET_EVENT_RX: +#else + } + if (pfd[NET_EVENT_RX].revents & POLLIN) { +#endif + + /* Packets are available for reading */ + status = ns_recv_pb(net_netswitch->nsconn, &net_netswitch->rx_packet, NET_MAX_FRAME, 0); + if (!status) { + net_switch_log("Receive packet failed. Skipping.\n"); + continue; + } + + /* These types are handled in the backend and don't need to be considered */ + if (is_control_packet(&net_netswitch->rx_packet) || is_fragment_packet(&net_netswitch->rx_packet)) { + continue; + } + data_packet_info_t packet_info = get_data_packet_info(&net_netswitch->rx_packet.pkt, net_netswitch->mac_addr); +#if defined(NET_PRINT_PACKET_RX) || defined(NET_PRINT_PACKET_ALL) + print_packet(net_netswitch->rx_packet.pkt); +#endif + /* + * Accept packets that are + * Unicast for us + * Broadcasts that are not from us + * All other packets *if* promiscuous mode is enabled (excluding our own) + */ + if (packet_info.is_packet_for_me || (packet_info.is_broadcast && !packet_info.is_packet_from_me)) { + /* Temporarily disable log suppression for packet logging */ + pclog_toggle_suppr(); + net_switch_log("%s Net Switch: RX: %s\n", switch_type, packet_info.printable); + pclog_toggle_suppr(); + network_rx_put_pkt(net_netswitch->card, &net_netswitch->rx_packet.pkt); + } else if (packet_info.is_packet_from_me) { + net_switch_log("%s Net Switch: Got my own packet... ignoring\n", switch_type); + } else { + /* Not our packet. Pass it along if promiscuous mode is enabled. */ + if (ns_flags(net_netswitch->nsconn) & FLAGS_PROMISC) { + net_switch_log("%s Net Switch: Got packet from %s (not mine, promiscuous is set, getting)\n", switch_type, packet_info.src_mac_h); + network_rx_put_pkt(net_netswitch->card, &net_netswitch->rx_packet.pkt); + } else { + net_switch_log("%s Net Switch: RX: %s (not mine, dest %s != %s, promiscuous not set, ignoring)\n", switch_type, packet_info.printable, packet_info.dest_mac_h, packet_info.my_mac_h); + } + } +#ifdef _WIN32 + break; + } +#else + } +#endif + } + + net_switch_log("%s Net Switch: polling stopped.\n", switch_type); +} + +void +net_netswitch_error(char *errbuf, const char *message) { + strncpy(errbuf, message, NET_DRV_ERRBUF_SIZE); + net_switch_log("Net Switch: %s\n", message); +} + +void * +net_netswitch_init(const netcard_t *card, const uint8_t *mac_addr, void *priv, char *netdrv_errbuf) +{ + net_switch_log("Net Switch: Init\n"); + + netcard_conf_t *netcard = (netcard_conf_t *) priv; + + ns_flags_t flags = FLAGS_NONE; + ns_type_t switch_type; + + const int net_type = netcard->net_type; + if(net_type == NET_TYPE_NRSWITCH) { + net_switch_log("Switch type: Remote\n"); + switch_type = SWITCH_TYPE_REMOTE; + } else if (net_type == NET_TYPE_NMSWITCH) { + net_switch_log("Switch type: Local Multicast\n"); + switch_type = SWITCH_TYPE_LOCAL; + if(netcard->promisc_mode) { + flags |= FLAGS_PROMISC; + } + } else { + net_switch_log("Failed: Unknown net switch type %d\n", net_type); + return NULL; + } + + // FIXME: Only here during dev. This would be an error otherwise (hostname not specified) + if(strlen(netcard->nrs_hostname) == 0) { + strncpy(netcard->nrs_hostname, "127.0.0.1", 128 - 1); + } + + net_netswitch_t *net_netswitch = calloc(1, sizeof(net_netswitch_t)); + net_netswitch->card = (netcard_t *) card; + memcpy(net_netswitch->mac_addr, mac_addr, sizeof(net_netswitch->mac_addr)); + snprintf(net_netswitch->switch_type, sizeof(net_netswitch->switch_type), "%s", net_type == NET_TYPE_NRSWITCH ? "Remote" : "Local"); + +// net_switch_log("%s Net Switch: mode: %d, group %d, hostname %s len %lu\n", net_netswitch->switch_type, netcard->promisc_mode, netcard->switch_group, netcard->nrs_hostname, strlen(netcard->nrs_hostname)); + + struct ns_open_args ns_args; + ns_args.type = switch_type; + /* Setting FLAGS_PROMISC here lets all packets through except the ones from us */ + ns_args.flags = flags; + /* This option sets which switch group you want to be a part of. + * Functionally equivalent to being plugged into a different switch */ + ns_args.group = netcard->switch_group; + /* You could also set the client_id here. If 0, it will be generated. */ + ns_args.client_id = 0; + memcpy(ns_args.mac_addr, net_netswitch->mac_addr, 6); + /* The remote switch hostname */ + strncpy(ns_args.nrs_hostname, netcard->nrs_hostname, sizeof(ns_args.nrs_hostname) - 1); + + net_switch_log("%s Net Switch: Starting up virtual switch with group %d, flags %d\n", net_netswitch->switch_type, ns_args.group, ns_args.flags); + + if ((net_netswitch->nsconn = ns_open(&ns_args)) == NULL) { + char buf[NET_DRV_ERRBUF_SIZE]; + /* We're using some errnos for our own purposes */ + switch (errno) { + case EFAULT: + snprintf(buf, NET_DRV_ERRBUF_SIZE, "Unable to open switch group %d: Cannot resolve remote switch hostname %s", ns_args.group, ns_args.nrs_hostname); + break; + default: + snprintf(buf, NET_DRV_ERRBUF_SIZE, "Unable to open switch group %d (%s)", ns_args.group, strerror(errno)); + break; + + } + net_netswitch_error(netdrv_errbuf, buf); + free(net_netswitch); + return NULL; + } + + for (int i = 0; i < SWITCH_PKT_BATCH; i++) { + net_netswitch->pktv[i].data = calloc(1, NET_MAX_FRAME); + } + net_netswitch->rx_packet.pkt.data = calloc(1, NET_MAX_FRAME); + + net_event_init(&net_netswitch->tx_event); + net_event_init(&net_netswitch->stop_event); +#ifdef _WIN32 + net_netswitch->sock_event = CreateEvent(NULL, FALSE, FALSE, NULL); +#endif + net_netswitch->poll_tid = thread_create(net_netswitch_thread, net_netswitch); + + /* Add the timers */ +#ifdef ENABLE_NET_SWITCH_STATS + timer_add(&net_netswitch->stats_timer, stats_timer, net_netswitch, 0); + timer_on_auto(&net_netswitch->stats_timer, 5000000); +#endif + timer_add(&net_netswitch->maintenance_timer, maintenance_timer, net_netswitch, 0); + timer_on_auto(&net_netswitch->maintenance_timer, SWITCH_KEEPALIVE_INTERVAL); + + /* Send join message. Return status not checked here. */ + ns_send_control(net_netswitch->nsconn, MessageType_MESSAGE_TYPE_JOIN); + + return net_netswitch; +} + +void +net_netswitch_in_available(void *priv) +{ + net_netswitch_t *net_netswitch = (net_netswitch_t *) priv; + net_event_set(&net_netswitch->tx_event); +} + +void +net_netswitch_close(void *priv) +{ + if (priv == NULL) + return; + + net_netswitch_t *net_netswitch = (net_netswitch_t *) priv; + + net_switch_log("%s Net Switch: closing.\n", net_netswitch->switch_type); + + /* Tell the thread to terminate. */ + net_event_set(&net_netswitch->stop_event); + + /* Wait for the thread to finish. */ + net_switch_log("%s Net Switch: waiting for thread to end...\n", net_netswitch->switch_type); + thread_wait(net_netswitch->poll_tid); + net_switch_log("%s Net Switch: thread ended\n", net_netswitch->switch_type); + + for (int i = 0; i < SWITCH_PKT_BATCH; i++) { + free(net_netswitch->pktv[i].data); + } + free(net_netswitch->rx_packet.pkt.data); + + net_event_close(&net_netswitch->tx_event); + net_event_close(&net_netswitch->stop_event); + +#ifdef _WIN32 + WSACleanup(); +#endif + + ns_close(net_netswitch->nsconn); + free(net_netswitch); +} + +const netdrv_t net_netswitch_drv = { + .notify_in = &net_netswitch_in_available, + .init = &net_netswitch_init, + .close = &net_netswitch_close, + .priv = NULL, +}; diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index b13fd8438..16fd7c65c 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -3256,8 +3256,12 @@ const device_t pcnet_am79c960_eb_device = { .config = pcnet_isa_config }; +/* + Used to be incorrectly called "AMD PCnet-VL" but the real name of the chip is "AMD PCnet-32" per the relevant datasheet. + https://theretroweb.com/chip/documentation/am79c965-66c24a7e6969d347126123.pdf +*/ const device_t pcnet_am79c960_vlb_device = { - .name = "AMD PCnet-VL", + .name = "AMD PCnet-32", .internal_name = "pcnetvlb", .flags = DEVICE_VLB, .local = DEV_AM79C960_VLB, diff --git a/src/network/net_plip.c b/src/network/net_plip.c index 8c46213c6..c45ad5527 100644 --- a/src/network/net_plip.c +++ b/src/network/net_plip.c @@ -27,10 +27,10 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/timer.h> +#include <86box/device.h> #include <86box/lpt.h> #include <86box/timer.h> #include <86box/pit.h> -#include <86box/device.h> #include <86box/thread.h> #include <86box/network.h> #include <86box/plat_unused.h> @@ -488,15 +488,20 @@ plip_close(void *priv) } const lpt_device_t lpt_plip_device = { - .name = "Parallel Line Internet Protocol", - .internal_name = "plip", - .init = plip_lpt_init, - .close = plip_close, - .write_data = plip_write_data, - .write_ctrl = plip_write_ctrl, - .read_data = NULL, - .read_status = plip_read_status, - .read_ctrl = NULL + .name = "Parallel Line Internet Protocol", + .internal_name = "plip", + .init = plip_lpt_init, + .close = plip_close, + .write_data = plip_write_data, + .write_ctrl = plip_write_ctrl, + .autofeed = NULL, + .strobe = NULL, + .read_status = plip_read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL, + .priv = NULL, + .lpt = NULL }; const device_t plip_device = { diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 5138b5168..0d07a8f83 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -2549,6 +2549,12 @@ rtl8139_io_writeb(uint32_t addr, uint8_t val, void *priv) break; + case RxConfig: + rtl8139_log("RxConfig write(b) val=0x%02x\n", val); + rtl8139_RxConfig_write(s, + (rtl8139_RxConfig_read(s) & 0xFFFFFF00) | val); + break; + default: rtl8139_log("not implemented write(b) addr=0x%x val=0x%02x\n", addr, val); break; diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 92c4c4ddf..e8cfd6cd7 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -291,8 +291,12 @@ net_slirp_get_revents(int idx, void *opaque) WSA_TO_POLL(FD_WRITE, SLIRP_POLL_OUT); WSA_TO_POLL(FD_CONNECT, SLIRP_POLL_OUT); WSA_TO_POLL(FD_OOB, SLIRP_POLL_PRI); + WSA_TO_POLL(FD_CLOSE, SLIRP_POLL_IN); WSA_TO_POLL(FD_CLOSE, SLIRP_POLL_HUP); + if (ret == 0) + ret |= SLIRP_POLL_IN; + return ret; } #else diff --git a/src/network/net_tap.c b/src/network/net_tap.c new file mode 100644 index 000000000..762f68b60 --- /dev/null +++ b/src/network/net_tap.c @@ -0,0 +1,353 @@ +/* + * 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. + * + * Linux TAP network interface for 86box. + * + * This file was created by looking at the VDE network backend + * as a reference, credit to jguillaumes. + * + * Authors: Doug Johnson + * + * + * Copyright 2023 Doug Johnson + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef _WIN32 +# error TAP networking is only supported on Linux +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HAVE_STDARG_H + +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/plat.h> +#include <86box/plat_dynld.h> +#include <86box/thread.h> +#include <86box/timer.h> +#include <86box/network.h> +#include <86box/net_event.h> + +typedef struct net_tap_t { + int fd; // tap device file descriptor + netcard_t *card; + thread_t *poll_tid; + net_evt_t tx_event; + net_evt_t stop_event; + netpkt_t pkt_rx; + netpkt_t pkts_tx[NET_QUEUE_LEN]; +} net_tap_t; + +#ifdef ENABLE_TAP_LOG +int tap_do_log = ENABLE_TAP_LOG; + + +static void tap_logv(const char *fmt, va_list ap) +{ + if (tap_do_log) { + pclog_ex(fmt, ap); + } +} + +static void tap_log(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (tap_do_log) { + va_start(ap, fmt); + tap_logv(fmt, ap); + va_end(ap); + } + va_end(ap); +} + +#else +# define tap_log(...) \ + do { \ + } while (0) +# define tap_logv(...) \ + do { \ + } while (0) +#endif + +static void net_tap_thread(void *priv) { + enum { + NET_EVENT_STOP = 0, + NET_EVENT_TX, + NET_EVENT_RX, + NET_EVENT_TAP, + NET_EVENT_MAX, + }; + net_tap_t *tap = priv; + tap_log("TAP: poll thread started.\n"); + struct pollfd pfd[NET_EVENT_MAX]; + pfd[NET_EVENT_STOP].fd = net_event_get_fd(&tap->stop_event); + pfd[NET_EVENT_STOP].events = POLLIN | POLLPRI; + + pfd[NET_EVENT_TX].fd = net_event_get_fd(&tap->tx_event); + pfd[NET_EVENT_TX].events = POLLIN | POLLPRI; + + pfd[NET_EVENT_RX].fd = tap->fd; + pfd[NET_EVENT_RX].events = POLLIN | POLLPRI; + + pfd[NET_EVENT_TAP].fd = tap->fd; + pfd[NET_EVENT_TAP].events = POLLERR | POLLHUP | POLLPRI; + fcntl(tap->fd, F_SETFL, O_NONBLOCK); + while(1) { + ssize_t ret = poll(pfd, NET_EVENT_MAX, -1); + if (ret < 0) { + tap_log("TAP: poll error: %s\n", strerror(errno)); + net_event_set(&tap->stop_event); + break; + } + if (pfd[NET_EVENT_TAP].revents) { + tap_log("TAP: tap close/error event received.\n"); + net_event_set(&tap->stop_event); + } + if (pfd[NET_EVENT_TX].revents & POLLIN) { + net_event_clear(&tap->tx_event); + int packets = network_tx_popv(tap->card, tap->pkts_tx, + NET_QUEUE_LEN); + for(int i = 0; i < packets; i++) { + netpkt_t *pkt = &tap->pkts_tx[i]; + ssize_t ret = write(tap->fd, pkt->data, pkt->len); + if (ret < 0) { + tap_log("TAP: write error: %s\n", strerror(errno)); + } + } + } + if (pfd[NET_EVENT_RX].revents & POLLIN) { + ssize_t len = read(tap->fd, tap->pkt_rx.data, NET_MAX_FRAME); + if (len < 0) { + tap_log("TAP: read error: %s\n", strerror(errno)); + continue; + } + tap->pkt_rx.len = len; + network_rx_put_pkt(tap->card, &tap->pkt_rx); + } + if (pfd[NET_EVENT_STOP].revents & POLLIN) { + net_event_clear(&tap->stop_event); + break; + } + } +} + +void net_tap_close(void *priv) +{ + if (!priv) { + return; + } + net_tap_t *tap = priv; + tap_log("TAP: closing.\n"); + net_event_set(&tap->stop_event); + tap_log("TAP: waiting for poll thread to exit.\n"); + thread_wait(tap->poll_tid); + tap_log("TAP: poll thread exited.\n"); + for(int i = 0; i < NET_QUEUE_LEN; i++) { + free(tap->pkts_tx[i].data); + } + free(tap->pkt_rx.data); + if (tap->fd >= 0) { + close(tap->fd); + } + free(tap); +} + +void net_tap_error(char *errbuf, const char* format, ...) +{ + va_list ap; + va_start(ap, format); + vsnprintf(errbuf, NET_DRV_ERRBUF_SIZE, format, ap); + tap_log("TAP: %s", errbuf); + va_end(ap); +} + +// Error handling macro for the many ioctl calls we use in net_tap_alloc +#define ioctl_or_fail(fd, request, argp) \ + do { \ + if ((err = ioctl(fd, request, argp)) < 0) { \ + tap_log("TAP: ioctl " #request " error: %s\n", strerror(errno)); \ + goto fail; \ + } \ + } while (0) + +// Returns -ERRNO so we can get an idea what's wrong +int net_tap_alloc(const uint8_t *mac_addr, const char* bridge_dev) +{ + int fd; + struct ifreq ifr = {0}; + if ((fd = open("/dev/net/tun", O_RDWR)) < 0) { + tap_log("TAP: open error: %s\n", strerror(errno)); + return -errno; + } + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + int err; + if ((err = ioctl(fd, TUNSETIFF, &ifr)) < 0) { + tap_log("TAP: ioctl TUNSETIFF error: %s\n", strerror(errno)); + close(fd); + return -errno; + } + // Create a socket for ioctl operations + int sock; + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + tap_log("TAP: socket error: %s\n", strerror(errno)); + close(fd); + return -errno; + } + // Bring the interface up + tap_log("TAP: Bringing interface '%s' up.\n", ifr.ifr_name); + ifr.ifr_flags = IFF_UP; + ioctl_or_fail(sock, SIOCSIFFLAGS, &ifr); + // Add interface to bridge, if specified + if (bridge_dev && bridge_dev[0] != '\0') { + // First see if the bridge exists + struct ifreq ifr_bridge; + //NOTE strncpy does not null terminate if the string is too long, I use + // snprintf or strlcpy instead + //strncpy(ifr_bridge.ifr_name, bridge_dev, IFNAMSIZ); + snprintf(ifr_bridge.ifr_name, IFNAMSIZ, "%s", bridge_dev); + if ((err = ioctl(sock, SIOCGIFINDEX, &ifr_bridge)) < 0) { + if (errno != ENODEV) { + tap_log("TAP: ioctl SIOCGIFINDEX error: %s\n", strerror(errno)); + goto fail; + } else { + // Create the bridge + ioctl_or_fail(sock, SIOCBRADDBR, &ifr_bridge); + // Set the bridge up + ifr_bridge.ifr_flags = IFF_UP; + ioctl_or_fail(sock, SIOCSIFFLAGS, &ifr_bridge); + } + } + // Get TAP index + ioctl_or_fail(sock, SIOCGIFINDEX, &ifr); + // Add the tap device to the bridge + ifr_bridge.ifr_ifindex = ifr.ifr_ifindex; + ioctl_or_fail(sock, SIOCBRADDIF, &ifr_bridge); + } + // close the socket we used for ioctl operations + close(sock); + tap_log("Allocated tap device %s\n", ifr.ifr_name); + return fd; + // cleanup point used by ioctl_or_fail macro +fail: + close(sock); + close(fd); + return -errno; +} + +void net_tap_in_available(void *priv) +{ + net_tap_t *tap = priv; + net_event_set(&tap->tx_event); +} + +void * +net_tap_init( + const netcard_t *card, + const uint8_t *mac_addr, + void *priv, + char *netdrv_errbuf) +{ + const char *bridge_dev = (void *) priv; + int tap_fd = net_tap_alloc(mac_addr, bridge_dev); + if (tap_fd < 0) { + if (tap_fd == -EPERM) { + net_tap_error( + netdrv_errbuf, + "No permissions to allocate tap device. " + "Try adding NET_CAP_ADMIN,NET_CAP_RAW to 86box (" + "sudo setcap 'CAP_NET_RAW,CAP_NET_ADMIN=eip')"); + } else { + net_tap_error( + netdrv_errbuf, + "Unable to allocate TAP device: %s", + strerror(-tap_fd)); + } + return NULL; + } + if (bridge_dev && bridge_dev[0] != '\0') { + } + net_tap_t *tap = calloc(1, sizeof(net_tap_t)); + if (!tap) { + goto alloc_fail; + } + tap->pkt_rx.data = calloc(1, NET_MAX_FRAME); + if (!tap->pkt_rx.data) { + goto alloc_fail; + } + for(int i = 0; i < NET_QUEUE_LEN; i++) { + tap->pkts_tx[i].data = calloc(1, NET_MAX_FRAME); + if (!tap->pkts_tx[i].data) { + goto alloc_fail; + } + } + tap->fd = tap_fd; + tap->card = (netcard_t *) card; + net_event_init(&tap->tx_event); + net_event_init(&tap->stop_event); + tap->poll_tid = thread_create(net_tap_thread, tap); + return tap; +alloc_fail: + net_tap_error(netdrv_errbuf, "Failed to allocate memory"); + close(tap_fd); + free(tap); + return NULL; +} + +const netdrv_t net_tap_drv = { + &net_tap_in_available, + &net_tap_init, + &net_tap_close, + NULL +}; diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index 1ca8d8697..890b221e2 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include diff --git a/src/network/netswitch.c b/src/network/netswitch.c new file mode 100644 index 000000000..54815a682 --- /dev/null +++ b/src/network/netswitch.c @@ -0,0 +1,973 @@ +/* +* 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. +* +* Network Switch backend +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN +# include +# include +#else +# include +# include +#endif + +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/thread.h> +#include <86box/timer.h> +#include <86box/network.h> +#include <86box/net_event.h> +#include <86box/random.h> +#include +#include "netswitch.h" +#include "pb_encode.h" +#include "pb_decode.h" + +#include "networkmessage.pb.h" + +bool ns_socket_setup(NSCONN *conn) { + + if(conn == NULL) { + errno=EINVAL; + return false; + } + +#ifdef _WIN32 + // Initialize Windows Socket API with the given version. + WSADATA wsaData; + if (WSAStartup(MAKEWORD(2, 0), &wsaData)) { + perror("WSAStartup"); + return false; + } +#endif + + /* Create the "main" socket + * Local mode: the listener socket for multicast packets + * Remote mode: the "main" socket for send and receive */ + conn->fddata = socket(AF_INET, SOCK_DGRAM, 0); + if (conn->fddata < 0) { + perror("socket"); + return false; + } + + /* Here things diverge depending on local or remote type */ + if(conn->switch_type == SWITCH_TYPE_LOCAL) { + + /* Set socket options - allow multiple sockets to use the same address */ + u_int on = 1; + if (setsockopt(conn->fddata, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) < 0) { + perror("Reusing ADDR failed"); + return false; + } +#ifndef _WIN32 + /* ... and same port number + * Not needed on windows because SO_REUSEPORT doesn't exist there. However, the same + * functionality comes along with SO_REUSEADDR. */ + if (setsockopt(conn->fddata, SOL_SOCKET, SO_REUSEPORT, (char *) &on, sizeof(on)) < 0) { + perror("Reusing PORT failed"); + return false; + } +#endif + + memset(&conn->addr, 0, sizeof(conn->addr)); + conn->addr.sin_family = AF_INET; + conn->addr.sin_addr.s_addr = htonl(INADDR_ANY); + conn->addr.sin_port = htons(conn->local_multicast_port); + + /* Bind to receive address */ + if (bind(conn->fddata, (struct sockaddr *) &conn->addr, sizeof(conn->addr)) < 0) { + perror("bind"); + return false; + } + + /* Request to join multicast group */ + /*** NOTE: intermittent airplane (non-connected wifi) failures with 239.255.86.86 - needs more investigation */ + struct ip_mreq mreq; + mreq.imr_multiaddr.s_addr = inet_addr(conn->mcast_group); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + if (setsockopt(conn->fddata, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreq, sizeof(mreq)) < 0) { + perror("setsockopt"); + return false; + } + + /* Now create the outgoing data socket */ + conn->fdout = socket(AF_INET, SOCK_DGRAM, 0); + if (conn->fdout < 0) { + perror("out socket"); + return false; + } + + /* Set up destination address */ + memset(&conn->outaddr, 0, sizeof(conn->outaddr)); + conn->outaddr.sin_family = AF_INET; + conn->outaddr.sin_addr.s_addr = inet_addr(conn->mcast_group); + conn->outaddr.sin_port = htons(conn->local_multicast_port); + } else if (conn->switch_type == SWITCH_TYPE_REMOTE) { + /* Remote switch path */ + int status; + struct addrinfo hints; + struct addrinfo *servinfo; + char connect_ip[128] = "\0"; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; // not sure? + + if((status = getaddrinfo(conn->nrs_hostname, NULL, &hints, &servinfo)) != 0) { + net_switch_log("getaddrinfo error: %s\n", gai_strerror(status)); + errno=EFAULT; + return false; + } + + for(const struct addrinfo *p = servinfo; p != NULL; p = p->ai_next) { // NOLINT (only want the first result) + /* Take the first result, ipv4 since AF_INET was set in the hints */ + const struct sockaddr_in *ipv4 = (struct sockaddr_in *) p->ai_addr; + const void *addr = &(ipv4->sin_addr); + inet_ntop(p->ai_family, addr, connect_ip, sizeof connect_ip); + break; + } + freeaddrinfo(servinfo); + + if(strlen(connect_ip) == 0) { + /* Couldn't look up the hostname */ + net_switch_log("Hostname lookup failure?\n"); + errno=EFAULT; + return false; + } + + /* Set up local socket address and port */ + memset(&conn->addr, 0, sizeof(conn->addr)); + conn->addr.sin_family = AF_INET; + conn->addr.sin_addr.s_addr = htonl(INADDR_ANY); + conn->addr.sin_port = htons(conn->remote_source_port); + + /* Bind to receive address. Try the first 100 ports to allow the use of multiple systems simultaneously */ + for(int i=0; i<100; i++) { + if(i==99) { + net_switch_log("Unable to find an available port to bind\n"); + return false; + } + if (bind(conn->fddata, (struct sockaddr *) &conn->addr, sizeof(conn->addr)) < 0) { + net_switch_log("local port %d unavailable, trying next..\n", conn->remote_source_port); + conn->remote_source_port += 1; + conn->addr.sin_port = htons(conn->remote_source_port); + continue ; + } else { + net_switch_log("** Local port for net remote switch is %d\n", conn->remote_source_port); + break; + } + + } + + + /* Set up remote address and port */ + memset(&conn->outaddr, 0, sizeof(conn->outaddr)); + conn->outaddr.sin_family = AF_INET; + conn->outaddr.sin_addr.s_addr = inet_addr(connect_ip); + conn->outaddr.sin_port = htons(conn->remote_network_port); + + /* In remote mode the file descriptor for send (fdout) is the same as receive */ + conn->fdout = conn->fddata; + + } else { + errno=EINVAL; + return false; + } + + return true; +} + +NSCONN * +ns_open(struct ns_open_args *open_args) { + struct nsconn *conn=NULL; + + /* Each "group" is really just the base port + group number + * A different group effectively gets you a different switch + * Clamp the group at MAX_SWITCH_GROUP */ + if(open_args->group > MAX_SWITCH_GROUP) { + open_args->group = MAX_SWITCH_GROUP; + } + // FIXME: hardcoded for testing + char *mcast_group = "239.255.86.86"; // Admin scope + // char *mcast_group = "224.0.0.86"; // Local scope + + if ( (conn=calloc(1,sizeof(struct nsconn)))==NULL) { + errno=ENOMEM; + return NULL; + } + + /* Type */ + conn->switch_type = open_args->type; + + /* Allocate the fragment buffer */ + for (int i = 0; i < FRAGMENT_BUFFER_LENGTH; i++) { + conn->fragment_buffer[i] = calloc(1, sizeof(ns_fragment_t)); + /* Set the default size to 0 and null data buffer to indicate it is unused. + * The data buffer will be allocated as needed. */ + conn->fragment_buffer[i]->size = 0; + conn->fragment_buffer[i]->data = NULL; + } +// net_switch_log("Fragment buffers: %d total, %d each\n", FRAGMENT_BUFFER_LENGTH, MAX_FRAME_SEND_SIZE); + + snprintf(conn->mcast_group, MAX_MCAST_GROUP_LEN, "%s", mcast_group); + conn->flags = open_args->flags; + + /* Increment the multicast port by the switch group number. Each group is + * just a different port. */ + conn->local_multicast_port = open_args->group + NET_SWITCH_MULTICAST_PORT; + conn->remote_network_port = NET_SWITCH_REMOTE_PORT; + /* Source ports for remote switch will start here and be incremented until an available port is found */ + conn->remote_source_port = NET_SWITCH_REMOTE_PORT + NET_SWITCH_RECV_PORT_OFFSET; + + /* Remote switch hostname */ + strncpy(conn->nrs_hostname, open_args->nrs_hostname, sizeof(conn->nrs_hostname) - 1); + + /* Switch type */ + if(conn->switch_type == SWITCH_TYPE_REMOTE) { + net_switch_log("Connecting to remote %s:%d, initial local port %d, group %d\n", conn->nrs_hostname, conn->remote_network_port, conn->remote_source_port, open_args->group); + } else { + net_switch_log("Opening IP %s, port %d, group %d\n", mcast_group, conn->local_multicast_port, open_args->group); + } + + /* Client state, disconnected by default. + * Primarily used in remote mode */ + conn->client_state = DISCONNECTED; + + /* Client ID. Generate the ID if set to zero. */ + if(open_args->client_id == 0) { + conn->client_id = ns_gen_client_id(); + } + + /* MAC address is set from the emulated card */ + memcpy(conn->mac_addr, open_args->mac_addr, PB_MAC_ADDR_SIZE); + + /* Protocol version */ + conn->version = NS_PROTOCOL_VERSION; + + if(!ns_socket_setup(conn)) { + goto fail; + } + + if (conn->switch_type == SWITCH_TYPE_REMOTE) { + /* Perhaps one day do the entire handshake process here */ + if(!ns_send_control(conn, MessageType_MESSAGE_TYPE_CONNECT_REQUEST)) { + goto fail; + } + conn->client_state = CONNECTING; + net_switch_log("Client state is now CONNECTING\n"); + } else { + conn->client_state = LOCAL; + } + + /* Initialize sequence numbers */ + conn->sequence = 1; + conn->remote_sequence = 1; + + /* Initialize stats */ + conn->stats.max_tx_frame = 0; + conn->stats.max_tx_packet = 0; + conn->stats.max_rx_frame = 0; + conn->stats.max_rx_packet = 0; + conn->stats.total_rx_packets = 0; + conn->stats.total_tx_packets = 0; + conn->stats.total_fragments = 0; + conn->stats.max_vec = 0; + memcpy(conn->stats.last_tx_ethertype, (uint8_t []) { 0, 0}, sizeof(conn->stats.last_tx_ethertype)); + memcpy(conn->stats.last_rx_ethertype, (uint8_t []) { 0, 0}, sizeof(conn->stats.last_rx_ethertype)); + + /* Assuming all went well we have our sockets */ + return conn; + + /* Cleanup */ +fail: + for (int i = 0; i < FRAGMENT_BUFFER_LENGTH; i++) { + free(conn->fragment_buffer[i]); + } + return NULL; +} + +int +ns_pollfd(const NSCONN *conn) { + if (conn->fddata != 0) + return conn->fddata; + else { + errno=EBADF; + return -1; + } +} + +ssize_t +ns_sock_recv(const NSCONN *conn,void *buf, const size_t len, const int flags) { + if (fd_valid(conn->fddata)) + return recv(conn->fddata,buf,len,0); + else { + errno=EBADF; + return -1; + } +} + +ssize_t +ns_sock_send(NSCONN *conn,const void *buf, const size_t len, const int flags) { + if (fd_valid(conn->fddata)) { + /* Use the outgoing socket for sending, set elsewhere: + * Remote mode: same as sending + * Local mode: different from sending */ + return sendto(conn->fdout, buf, len, 0, (struct sockaddr *) &conn->outaddr, sizeof(conn->outaddr)); + } else { + errno=EBADF; + return -1; + } +} + +ssize_t +ns_send_pb(NSCONN *conn, const netpkt_t *packet,int flags) { + + NetworkMessage network_message = NetworkMessage_init_zero; + uint8_t fragment_count; + + /* Do we need to fragment? First, determine how many packets we will be sending */ + if(packet->len <= MAX_FRAME_SEND_SIZE) { + fragment_count = 1; +// net_switch_log("No Fragmentation. Frame size %d is less than max size %d\n", packet->len, MAX_FRAME_SEND_SIZE); + } else { + /* Since we're using integer math and the remainder is + * discarded we'll add one to the result *unless* the result can be evenly divided. */ + const uint8_t extra = (packet->len % MAX_FRAME_SEND_SIZE) == 0 ? 0 : 1; + fragment_count = (packet->len / MAX_FRAME_SEND_SIZE) + extra; +// net_switch_log("Fragmentation required, frame size %d exceeds max size %d\n", packet->len, MAX_FRAME_SEND_SIZE); + } + + /* Loop here for each fragment. Send each fragment. In the even that the packet is *not* a fragment (regular data packet) + * this will only execute once. */ + const uint32_t fragment_sequence = conn->sequence; + const int64_t packet_timestamp = ns_get_current_millis(); + for (uint8_t fragment_index = 0; fragment_index < fragment_count; fragment_index++) { + uint8_t buffer[NET_SWITCH_BUFFER_LENGTH]; + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); +#ifdef ENABLE_NET_SWITCH_PB_FILE_DEBUG + uint8_t file_buffer[NET_SWITCH_BUFFER_LENGTH]; + /* file_stream used for debugging and writing the message to a file */ + pb_ostream_t file_stream = pb_ostream_from_buffer(file_buffer, sizeof(file_buffer)); +#endif + /* Single frame is type DATA, fragments are FRAGMENT */ + network_message.message_type = fragment_count > 1 ? MessageType_MESSAGE_TYPE_FRAGMENT : MessageType_MESSAGE_TYPE_DATA; + network_message.client_id = conn->client_id; + network_message.timestamp = packet_timestamp; + network_message.version = conn->version; + + /* Need some additional data if we're a fragment */ + if(fragment_count > 1) { + network_message.fragment.total = fragment_count; + network_message.fragment.id = fragment_sequence; + network_message.fragment.sequence = fragment_index + 1; + network_message.has_fragment = true; + } + + /* TODO: Better / real ack logic. Needs its own function. Currently just putting in dummy data. */ + network_message.ack.id = 1; + network_message.ack.history = 1; + network_message.has_ack = true; + network_message.sequence = conn->sequence; + + /* Frame data must be allocated */ + network_message.frame = calloc(1, PB_BYTES_ARRAY_T_ALLOCSIZE(packet->len)); + + /* Calculate offsets based on our position in the fragment. + * For anything other than the *last* packet, we'll have a max frame size */ + uint16_t copy_length; + const uint16_t copy_offset = fragment_index * MAX_FRAME_SEND_SIZE; + if(fragment_index == (fragment_count - 1)) { + copy_length = packet->len % MAX_FRAME_SEND_SIZE == 0 ? MAX_FRAME_SEND_SIZE : packet->len % MAX_FRAME_SEND_SIZE; + } else { + copy_length = MAX_FRAME_SEND_SIZE; + } + if(fragment_count > 1) { +// net_switch_log("Fragment %d/%d, %d bytes\n", fragment_index + 1, fragment_count, copy_length); + } + network_message.frame->size = copy_length; + memcpy(network_message.frame->bytes, packet->data + copy_offset, copy_length); + + /* mac address must be allocated */ + network_message.mac = calloc(1, PB_BYTES_ARRAY_T_ALLOCSIZE(PB_MAC_ADDR_SIZE)); + network_message.mac->size = PB_MAC_ADDR_SIZE; + memcpy(network_message.mac->bytes, conn->mac_addr, PB_MAC_ADDR_SIZE); + + /* Encode the protobuf message */ + if (!pb_encode_ex(&stream, NetworkMessage_fields, &network_message,PB_ENCODE_DELIMITED)) { + net_switch_log("Encoding failed: %s\n", PB_GET_ERROR(&stream)); + errno = EBADF; + return -1; + } + + /* Send on the socket */ + const ssize_t nc = ns_sock_send(conn, buffer, stream.bytes_written, 0); + if(!nc) { + net_switch_log("Error sending data on the socket\n"); + errno=EBADF; + pb_release(NetworkMessage_fields, &network_message); + return -1; + } +#ifdef ENABLE_NET_SWITCH_PB_FILE_DEBUG + /* File writing for troubleshooting when needed */ + FILE *f = fopen("/var/tmp/pbuf", "wb"); + if (f) { + if (!pb_encode(&file_stream, NetworkMessage_fields, &network_message)) { + net_switch_log("File encoding failed: %s\n", PB_GET_ERROR(&file_stream)); + } + fwrite(file_buffer, file_stream.bytes_written, 1, f); + fclose(f); + } else { + net_switch_log("file open failed\n"); + } +#endif + + /* Stats */ + if(network_message.frame->size > conn->stats.max_tx_frame) { + conn->stats.max_tx_frame = network_message.frame->size; + } + if(nc > conn->stats.max_tx_packet) { + conn->stats.max_tx_packet = nc; + } + if(nc > MAX_FRAME_SEND_SIZE) { + conn->stats.total_fragments = fragment_count > 1 ? conn->stats.total_fragments + fragment_count : conn->stats.total_fragments; + } + conn->stats.total_tx_packets++; + memcpy(conn->stats.last_tx_ethertype, &packet->data[12], 2); + + /* Increment the sequence number */ + seq_increment(conn); + + /* nanopb will free all the allocated entries for us */ + pb_release(NetworkMessage_fields, &network_message); + + } + + return packet->len; +} + +bool store_fragment(const NSCONN *conn, const NetworkMessage *network_message) { + + if(conn == NULL || network_message == NULL) { + return false; + } + + /* The fragment sequence indicates which fragment this is in the overall fragment + * collection. This is used to index the fragments while being stored for reassembly + * (zero indexed locally) */ + const uint32_t fragment_index = network_message->fragment.sequence - 1; + const uint32_t fragment_size = network_message->frame->size; + + /* Make sure the fragments aren't too small + * (see header notes about size requirements for MIN_FRAG_RECV_SIZE and FRAGMENT_BUFFER_LENGTH) + * NOTE: The last packet is exempt from this rule because it can have a smaller amount. + * This is primarily to ensure there's enough space to fit all the fragments. */ + if(network_message->fragment.sequence != network_message->fragment.total) { + if (network_message->frame->size < MIN_FRAG_RECV_SIZE) { + net_switch_log("size: %d < %d\n", network_message->frame->size, MIN_FRAG_RECV_SIZE); + return false; + } + } + + /* Make sure we can handle the amount of incoming fragments */ + if (network_message->fragment.total > FRAGMENT_BUFFER_LENGTH) { + net_switch_log("buflen: %d > %d\n", network_message->fragment.total, FRAGMENT_BUFFER_LENGTH); + return false; + } + + /* Allocate or reallocate as needed. + * size > 0 indicates this buffer has already been allocated. */ + if(conn->fragment_buffer[fragment_index]->size > 0) { + conn->fragment_buffer[fragment_index]->data = realloc(conn->fragment_buffer[fragment_index]->data, sizeof(char) * fragment_size); + } else { + conn->fragment_buffer[fragment_index]->data = calloc(1, sizeof(char) * fragment_size); + } + + if (conn->fragment_buffer[fragment_index]->data == NULL) { + net_switch_log("Failed to allocate / reallocate fragment buffer space\n"); + return false; + } + + /* Each fragment will belong to a particular ID. All members will have the same ID, + * which is generally set to the sequence number of the first fragment */ + conn->fragment_buffer[fragment_index]->id = network_message->fragment.id; + /* The sequence here is set to the index of the packet in the total fragment collection + * (network_message->fragment.sequence) */ + conn->fragment_buffer[fragment_index]->sequence = fragment_index; + /* Total number of fragments in this set */ + conn->fragment_buffer[fragment_index]->total = network_message->fragment.total; + /* The sequence number from the packet that contained the fragment */ + conn->fragment_buffer[fragment_index]->packet_sequence = network_message->sequence; + /* Copy the fragment data and size */ + /* The size of fragment_buffer[fragment_index]->data is checked against MAX_FRAME_SEND_SIZE above */ + memcpy(conn->fragment_buffer[fragment_index]->data, network_message->frame->bytes, fragment_size); + conn->fragment_buffer[fragment_index]->size = fragment_size; + /* 10 seconds for a TTL */ + conn->fragment_buffer[fragment_index]->ttl = ns_get_current_millis() + 10000; + + return true; +} + +bool +reassemble_fragment(const NSCONN *conn, netpkt_t *pkt, const uint32_t packet_count) +{ + uint32_t total = 0; + + /* Make sure the reassembled packet doesn't exceed NET_MAX_FRAME */ +// if (packet_count * MAX_FRAME_SEND_SIZE > NET_MAX_FRAME) { +// return false; +// } + + /* Too many packets! */ + if (packet_count > FRAGMENT_BUFFER_LENGTH) { + return false; + } + + // TODO: Check fragment ID + // TODO: Check TTL + + /* Get the fragment size from the first entry. All fragments in a particular + * set must be of the same size except the last fragment, which may be smaller. + * The fragment size will be used to determine the offset. */ + const uint16_t fragment_size = conn->fragment_buffer[0]->size; + +// net_switch_log("Reassembling %d fragments\n", packet_count); + + for(int i = 0; i < packet_count; i++) { + /* Size of zero means we're trying to assemble from a bad fragment */ + if(conn->fragment_buffer[i]->size == 0) { + net_switch_log("Fragment size 0 when trying to reassemble (id %i/index %i/seq %i/ total %i)\n",conn->fragment_buffer[i]->id, i, conn->fragment_buffer[i]->sequence, conn->fragment_buffer[i]->total); + return false; + } + if(conn->fragment_buffer[i]->data == NULL) { + net_switch_log("Missing fragment data when trying to reassemble\n"); + return false; + } + + memcpy(pkt->data + (fragment_size * i), conn->fragment_buffer[i]->data, conn->fragment_buffer[i]->size); + total += conn->fragment_buffer[i]->size; + + /* Zero out the size to indicate the slot is unused */ + conn->fragment_buffer[i]->size = 0; + free(conn->fragment_buffer[i]->data); + conn->fragment_buffer[i]->data = NULL; + } + + /* Set the size, must cast due to netpkt_t (len is int) */ + pkt->len = (int) total; +// net_switch_log("%d bytes reassembled and converted to data packet.\n", pkt->len); + + return true; +} + +bool +ns_recv_pb(NSCONN *conn, ns_rx_packet_t *packet,size_t len,int flags) { + NetworkMessage network_message = NetworkMessage_init_zero; + ns_rx_packet_t *ns_packet = packet; + + uint8_t buffer[NET_SWITCH_BUFFER_LENGTH]; + + /* TODO: Use the passed len? Most likely not needed */ + const ssize_t nc = ns_sock_recv(conn, buffer, NET_SWITCH_BUFFER_LENGTH, 0); + if(!nc) { + net_switch_log("Error receiving data on the socket\n"); + errno=EBADF; + return false; + } + pb_istream_t stream = pb_istream_from_buffer(buffer, sizeof(buffer)); + + if (!pb_decode_delimited(&stream, NetworkMessage_fields, &network_message)) { + /* Decode failed */ + net_switch_log("PB decoding failed: %s\n", PB_GET_ERROR(&stream)); + /* Allocated fields are automatically released upon failure */ + return false; + } + + /* Basic checks for validity */ + if(network_message.mac == NULL || network_message.message_type == MessageType_MESSAGE_TYPE_UNSPECIFIED || + network_message.client_id == 0) { + net_switch_log("Invalid packet received! Skipping..\n"); + goto fail; + } + + /* These fields should always be set. Start copying into our packet structure. */ + ns_packet->client_id = network_message.client_id; + ns_packet->type = network_message.message_type; + memcpy(ns_packet->mac, network_message.mac->bytes, PB_MAC_ADDR_SIZE); + ns_packet->timestamp = network_message.timestamp; + ns_packet->version = network_message.version; + conn->remote_sequence = network_message.sequence; + conn->last_packet_stamp = network_message.timestamp; + + /* Control messages take a different path */ + if(network_message.message_type != MessageType_MESSAGE_TYPE_DATA && + network_message.message_type != MessageType_MESSAGE_TYPE_FRAGMENT) { + process_control_packet(conn, ns_packet); + pb_release(NetworkMessage_fields, &network_message); + return true; + } + + /* All packets should be DATA or FRAGMENT at this point and have a frame */ + if(network_message.frame == NULL) { + net_switch_log("Invalid data packet received! Frame is null. Skipping..\n"); + goto fail; + } + + /* Fragment path first */ + if(network_message.message_type == MessageType_MESSAGE_TYPE_FRAGMENT) { + + /* Store fragment */ + if(!store_fragment(conn, &network_message)) { + net_switch_log("Failed to store fragment\n"); + goto fail; + } + + /* Is this the last fragment? If not, return */ + if(network_message.fragment.sequence != network_message.fragment.total) { + // FIXME: Really dumb, needs to be smarter + pb_release(NetworkMessage_fields, &network_message); + return true; + } + + /* This is the last fragment. Attempt to reassemble */ + if(!reassemble_fragment(conn, &ns_packet->pkt, network_message.fragment.total)) { + net_switch_log("Failed to reassemble fragment\n"); + goto fail; + } + /* Change the type to DATA */ + ns_packet->type = MessageType_MESSAGE_TYPE_DATA; + + } else { + /* Standard DATA packet path. Copy frame from the message */ + memcpy(ns_packet->pkt.data, network_message.frame->bytes, network_message.frame->size); + ns_packet->pkt.len = network_message.frame->size; + } + + /* Stats */ + if(network_message.frame->size > conn->stats.max_rx_frame) { + conn->stats.max_rx_frame = network_message.frame->size; + } + if(nc > conn->stats.max_rx_packet) { + conn->stats.max_rx_packet = nc; + } + memcpy(conn->stats.last_rx_ethertype, &packet->pkt.data[12], 2); + conn->stats.total_rx_packets++; + /* End Stats */ + + /* nanopb allocates the necessary fields while serializing. + They need to be manually released once you are done with the message */ + pb_release(NetworkMessage_fields, &network_message); + return true; +fail: + pb_release(NetworkMessage_fields, &network_message); + return false; +} + +bool process_control_packet(NSCONN *conn, const ns_rx_packet_t *packet) { + + control_packet_info_t packet_info = get_control_packet_info(*packet, conn->mac_addr); +// net_switch_log("Last timestamp: %lld\n", ns_get_current_millis()); +// net_switch_log("(%lld ms) [%03d] ", ns_get_current_millis() - packet_info.timestamp, conn->sequence); + + /* I probably want to eventually differentiate between local and remote here, kind of basic now */ + if(!packet_info.is_packet_from_me) { /* in case of local mode */ + switch (packet_info.type) { + case MessageType_MESSAGE_TYPE_JOIN: + net_switch_log("Client ID 0x%08llx (MAC %s) has joined the chat\n", packet_info.client_id, packet_info.src_mac_h); + break; + case MessageType_MESSAGE_TYPE_LEAVE: + net_switch_log("Client ID 0x%08llx (MAC %s) has left us\n", packet_info.client_id, packet_info.src_mac_h); + break; + case MessageType_MESSAGE_TYPE_KEEPALIVE: +// net_switch_log("Client ID 0x%08llx (MAC %s) is still alive\n", packet_info.client_id, packet_info.src_mac_h); + break; + case MessageType_MESSAGE_TYPE_ACK: +// net_switch_log("Client ID 0x%08llx (MAC %s) has sent an ACK\n", packet_info.client_id, packet_info.src_mac_h); + break; + case MessageType_MESSAGE_TYPE_CONNECT_REPLY: + conn->client_state = CONNECTED; + net_switch_log("Client ID 0x%08llx (MAC %s) has sent a connection reply\n", packet_info.client_id, packet_info.src_mac_h); + net_switch_log("Client state is now CONNECTED\n"); + break; + case MessageType_MESSAGE_TYPE_FRAGMENT: + net_switch_log("Client ID 0x%08llx (MAC %s) has sent a fragment\n", packet_info.client_id, packet_info.src_mac_h); + break; + default: + net_switch_log("Client ID 0x%08llx (MAC %s) has sent a message that we don't understand (type %d)\n", packet_info.client_id, packet_info.src_mac_h, packet_info.type); + break; + } + } + return true; + +} + +bool +ns_send_control(NSCONN *conn, const MessageType type) { + + NetworkMessage network_message = NetworkMessage_init_zero; + uint8_t buffer[NET_SWITCH_BUFFER_LENGTH]; + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + network_message.message_type = type; + network_message.client_id = conn->client_id; + + /* No frame data so we only need to allocate mac address */ + network_message.mac = calloc(1, PB_BYTES_ARRAY_T_ALLOCSIZE(PB_MAC_ADDR_SIZE)); + network_message.mac->size = PB_MAC_ADDR_SIZE; + memcpy(network_message.mac->bytes, conn->mac_addr, PB_MAC_ADDR_SIZE); + + network_message.timestamp = ns_get_current_millis(); + network_message.version = conn->version; + network_message.sequence = conn->sequence; + + if (!pb_encode_ex(&stream, NetworkMessage_fields, &network_message, PB_ENCODE_DELIMITED)) { + net_switch_log("Encoding failed: %s\n", PB_GET_ERROR(&stream)); + errno = EBADF; + return false; + } + + const ssize_t nc = ns_sock_send(conn, buffer, stream.bytes_written, 0); + if(!nc) { + net_switch_log("Error sending control message on the socket\n"); + errno=EBADF; + pb_release(NetworkMessage_fields, &network_message); + return -1; + } + /* Increment the sequence number */ + seq_increment(conn); + + /* Stats */ + conn->stats.total_tx_packets++; + + /* Must release allocated data */ + pb_release(NetworkMessage_fields, &network_message); + + return true; +} + +uint32_t +ns_gen_client_id(void) { + uint32_t msb; + do { + msb = random_generate(); + } while (msb < 0x10); + return ( random_generate() | (random_generate() << 8) | (random_generate() << 16) | (msb << 24)); +} + +const char * +ns_printable_message_type(const MessageType type) +{ + switch (type) { + case MessageType_MESSAGE_TYPE_DATA: + return "Data"; + case MessageType_MESSAGE_TYPE_JOIN: + return "Join"; + case MessageType_MESSAGE_TYPE_LEAVE: + return "Leave"; + case MessageType_MESSAGE_TYPE_KEEPALIVE: + return "Keepalive"; + case MessageType_MESSAGE_TYPE_FRAGMENT: + return "Fragment"; + case MessageType_MESSAGE_TYPE_ACK: + return "Ack"; + case MessageType_MESSAGE_TYPE_UNSPECIFIED: + return "Unspecified (shouldn't get this)"; + default: + return "Unknown message type - probably hasn't been added yet!"; + } +} + +int64_t +ns_get_current_millis(void) { + struct timeval time; + gettimeofday(&time, NULL); + /* Windows won't properly promote integers so this is necessary */ + const int64_t seconds = (int64_t) time.tv_sec * 1000; + + return seconds + (time.tv_usec / 1000); +} + +int +ns_flags(const NSCONN *conn) { + return conn->flags; +} + +int +ns_close(NSCONN *conn) { + if(conn->switch_type == SWITCH_TYPE_REMOTE) { + /* TBD */ + } + /* No need to check the return here as we're closing out */ + ns_send_control(conn, MessageType_MESSAGE_TYPE_LEAVE); + for (int i = 0; i < FRAGMENT_BUFFER_LENGTH; i++) { + if (conn->fragment_buffer[i]->size > 0) { + free(conn->fragment_buffer[i]->data); + conn->fragment_buffer[i]->data = NULL; + } + free(conn->fragment_buffer[i]); + } + close(conn->fddata); + close(conn->fdout); + return 0; +} + +bool is_control_packet(const ns_rx_packet_t *packet) { + return packet->type != MessageType_MESSAGE_TYPE_DATA; +} + +bool is_fragment_packet(const ns_rx_packet_t *packet) { + return packet->type == MessageType_MESSAGE_TYPE_FRAGMENT; +} + +bool ns_connected(const NSCONN *conn) { + if(conn->switch_type == SWITCH_TYPE_LOCAL) { + return true; + } + + if(conn->switch_type == SWITCH_TYPE_REMOTE) { + if(conn->client_state == CONNECTED) { + return true; + } + } + + return false; +} + +char* formatted_mac(uint8_t mac_addr[6]) +{ + char *mac_h = calloc(1, sizeof(char)* 32); + for(int i=0; i < 6; i++) { + char octet[4]; + snprintf(octet, sizeof(octet), "%02X%s", mac_addr[i], i < 5 ? ":" : ""); + strncat(mac_h, octet, sizeof(mac_h) - 1); + } + return mac_h; +} + +control_packet_info_t get_control_packet_info(const ns_rx_packet_t packet, const uint8_t *my_mac) +{ + control_packet_info_t packet_info; + + packet_info.src_mac_h[0] = '\0'; + packet_info.printable[0] = '\0'; + packet_info.client_id = packet.client_id; + memcpy(packet_info.src_mac, &packet.mac, 6); + packet_info.type = packet.type; + packet_info.is_packet_from_me = (memcmp(my_mac, packet_info.src_mac, sizeof(uint8_t) * 6) == 0); + char *formatted_mac_h = formatted_mac(packet_info.src_mac); + strncpy(packet_info.src_mac_h, formatted_mac_h, MAX_PRINTABLE_MAC); + free(formatted_mac_h); + snprintf(packet_info.printable, sizeof(packet_info.printable), "%s", ns_printable_message_type(packet_info.type)); + packet_info.timestamp = packet.timestamp; + + return packet_info; +} + +data_packet_info_t +get_data_packet_info(const netpkt_t *packet, const uint8_t *my_mac) { + data_packet_info_t packet_info; + + packet_info.src_mac_h[0] = '\0'; + packet_info.dest_mac_h[0] = '\0'; + packet_info.my_mac_h[0] = '\0'; + packet_info.printable[0] = '\0'; + + memcpy(packet_info.dest_mac,&packet->data[0], 6); + memcpy(packet_info.src_mac, &packet->data[6], 6); + + /* Broadcast and multicast are treated the same at L2 and both will have the + * least significant bit of 1 in the first transmitted byte. + * The below test matches 0xFF for standard broadcast along with 0x01 and 0x33 for multicast */ + packet_info.is_broadcast = ((packet->data[0] & 1) == 1); + packet_info.is_packet_for_me = (memcmp(my_mac, packet_info.dest_mac, sizeof(uint8_t) * 6) == 0); + packet_info.is_packet_from_me = (memcmp(my_mac, packet_info.src_mac, sizeof(uint8_t) * 6) == 0); + packet_info.is_data_packet = packet->len > 0; + packet_info.size = packet->len; + + /* Since this function is applied to every packet, only enable the pretty formatting below + * if logging is specifically enabled. */ +#ifdef ENABLE_NET_SWITCH_LOG + /* Pretty formatting for hardware addresses */ + for(int i=0; i < 6; i++) { + char octet[4]; + snprintf(octet, sizeof(octet), "%02X%s", packet_info.src_mac[i], i < 5 ? ":" : ""); + strncat(packet_info.src_mac_h, octet, sizeof (packet_info.src_mac_h) - 1); + + snprintf(octet, sizeof(octet), "%02X%s", packet_info.dest_mac[i], i < 5 ? ":" : ""); + strncat(packet_info.dest_mac_h, octet, sizeof (packet_info.dest_mac_h) - 1); + + snprintf(octet, sizeof(octet), "%02X%s", my_mac[i], i < 5 ? ":" : ""); + strncat(packet_info.my_mac_h, octet, sizeof (packet_info.my_mac_h) - 1); + } + + /* Printable output formatting */ + if(packet_info.is_broadcast) { + if(packet_info.is_packet_from_me) { + snprintf(packet_info.printable, sizeof(packet_info.printable), "(broadcast)"); + } else { + snprintf(packet_info.printable, sizeof(packet_info.printable), "%s (broadcast)", packet_info.src_mac_h); + } + } else { + snprintf(packet_info.printable, sizeof(packet_info.printable), "%s%s -> %s%s", packet_info.src_mac_h, packet_info.is_packet_from_me ? " (me)" : " ", + packet_info.dest_mac_h, packet_info.is_packet_for_me ? " (me)" : ""); + } +#endif + return packet_info; +} + +bool +fd_valid(const int fd) +{ +#ifdef _WIN32 + int error_code; + int error_code_size = sizeof(error_code); + getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *) &error_code, &error_code_size); + if (error_code == WSAENOTSOCK) { + return false; + } + return true; +#else + if (fcntl(fd, F_GETFD) == -1) { + return false; + } + /* All other values will be a valid fd */ + return true; +#endif +} + +bool +seq_increment(NSCONN *conn) +{ + if(conn == NULL) { + return false; + } + conn->sequence++; + if (conn->sequence == 0) { + conn->sequence = 1; + } + return true; +} diff --git a/src/network/netswitch.h b/src/network/netswitch.h new file mode 100644 index 000000000..02534ff30 --- /dev/null +++ b/src/network/netswitch.h @@ -0,0 +1,298 @@ +/* +* 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. +* +* Network Switch backend +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#ifndef NET_SWITCH_H +#define NET_SWITCH_H + +#ifdef _WIN32 +#include // before Windows.h, else Winsock 1 conflict +#include // needed for ip_mreq definition for multicast +#include +#else +#include +#include +#include +#include +#include +#endif +#include +#include "pb.h" +#include "networkmessage.pb.h" + +/* Local switch multicast port */ +#define NET_SWITCH_MULTICAST_PORT 8086 +/* Remote switch connect port */ +#define NET_SWITCH_REMOTE_PORT 8088 +/* Remove switch. This offset is where the local source ports will begin. */ +#define NET_SWITCH_RECV_PORT_OFFSET 198 +/* Multicast group (IP Address) maximum length. String representation. */ +#define MAX_MCAST_GROUP_LEN 32 +/* The buffer length used for both receiving on sockets and protobuf serialize / deserialize */ +#define NET_SWITCH_BUFFER_LENGTH 2048 + +/* Any frame above this size gets fragmented */ +#define MAX_FRAME_SEND_SIZE 1200 +/* Minimum fragment size we'll accept */ +#define MIN_FRAG_RECV_SIZE 12 +/* + Size of the fragment buffer - how many can we hold? + Note: FRAGMENT_BUFFER_LENGTH * MIN_FRAG_RECV_SIZE *must* be greater + than NET_MAX_FRAME or bad things will happen with large packets! +*/ +#define FRAGMENT_BUFFER_LENGTH 128 +/* Maximum number of switch groups */ +#define MAX_SWITCH_GROUP 31 +/* Size of a mac address in bytes. Used for the protobuf serializing / deserializing */ +#define PB_MAC_ADDR_SIZE 6 +/* This will define the version in use and the minimum required for communication */ +#define NS_PROTOCOL_VERSION 1 +/* Maximum string size for a printable (formatted) mac address */ +#define MAX_PRINTABLE_MAC 32 +/* Maximum hostname length for a remote switch host */ +#define MAX_HOSTNAME 128 + +typedef enum { + FLAGS_NONE = 0, + FLAGS_PROMISC = 1 << 0, +} ns_flags_t; + +typedef enum { + SWITCH_TYPE_LOCAL = 0, + SWITCH_TYPE_REMOTE, +} ns_type_t; + +typedef enum { + DISCONNECTED, + CONNECTING, + CONNECTED, + LOCAL, +} ns_client_state_t; + +struct ns_open_args { + uint8_t group; + ns_flags_t flags; + ns_type_t type; + char *client_id; + uint8_t mac_addr[6]; + char nrs_hostname[MAX_HOSTNAME]; +}; + +struct nsconn; + +typedef struct nsconn NSCONN; + +struct ns_stats { + size_t max_tx_frame; + size_t max_tx_packet; + size_t max_rx_frame; + size_t max_rx_packet; + uint8_t last_tx_ethertype[2]; + uint8_t last_rx_ethertype[2]; + u_long total_rx_packets; + u_long total_tx_packets; + u_long total_fragments; + uint8_t max_vec; +}; + +typedef struct { + /* The ID of the fragment. All fragments in a set should have the same ID. */ + uint32_t id; + /* The fragment index in the sequence of fragments. NOTE: one indexed, not zero! + * Example: the first fragment of three would be 1 in the sequence */ + uint32_t sequence; + /* Total number of fragments for the collection */ + uint32_t total; + /* The sequence number of the packet that delivered the fragment. Not the same as fragment sequence above! */ + uint32_t packet_sequence; + /* Frame data */ + char *data; + /* Frame size. A size of zero indicates an unused fragment slot and unallocated data field. */ + uint32_t size; + /* Epoch time (in ms) that the fragment is valid until */ + uint64_t ttl; +} ns_fragment_t; + +struct nsconn { + uint16_t flags; + int fdctl; + int fddata; + int fdout; + char mcast_group[MAX_MCAST_GROUP_LEN]; + struct sockaddr_in addr; + struct sockaddr_in outaddr; + size_t outlen; + struct sockaddr *sock; + struct sockaddr *outsock; + struct ns_stats stats; + uint32_t client_id; + uint8_t mac_addr[6]; + uint16_t sequence; + uint16_t remote_sequence; + uint8_t version; + uint8_t switch_type; + ns_client_state_t client_state; + int64_t last_packet_stamp; + /* Remote switch hostname */ + char nrs_hostname[MAX_HOSTNAME]; + /* Remote connect port for remote network switch */ + uint16_t remote_network_port; + /* Local multicast port for the local network switch */ + uint16_t local_multicast_port; + /* + * The source port to receive packets. Only applies to remote mode. + * This will also be the source port for sent packets in order to aid + * NAT + */ + uint16_t remote_source_port; + ns_fragment_t *fragment_buffer[FRAGMENT_BUFFER_LENGTH]; +}; + +typedef struct { + uint32_t id; + uint32_t history; +} ns_ack_t; + +typedef struct { + uint32_t id; + uint32_t sequence; + uint32_t total; +} ns_fragment_info_t; + +typedef struct { + netpkt_t pkt; + MessageType type; + uint32_t client_id; + uint8_t mac[6]; + uint32_t flags; + int64_t timestamp; + ns_ack_t ack; + ns_fragment_info_t fragment; + uint32_t version; +} ns_rx_packet_t; + +typedef struct { + size_t size; + char src_mac_h[MAX_PRINTABLE_MAC]; + char dest_mac_h[MAX_PRINTABLE_MAC]; + char my_mac_h[MAX_PRINTABLE_MAC]; + uint8_t src_mac[6]; + uint8_t dest_mac[6]; + bool is_packet_from_me; + bool is_broadcast; + bool is_packet_for_me; + bool is_data_packet; + char printable[128]; +} data_packet_info_t; + +typedef struct { + uint8_t src_mac[6]; + char src_mac_h[MAX_PRINTABLE_MAC]; + bool is_packet_from_me; + MessageType type; + char printable[128]; + uint64_t client_id; + int64_t timestamp; +} control_packet_info_t; + +/* Initializes and opens the Net Multicast Switch */ +NSCONN *ns_open(struct ns_open_args *open_args); + +/* Returns the flags */ +int ns_flags(const NSCONN *conn); + +/* Returns the file descriptor for polling */ +int ns_pollfd(const NSCONN *conn); + +/* This should be used to receive serialized protobuf packets + * and have the output placed in the packet struct */ +bool ns_recv_pb(NSCONN *conn, ns_rx_packet_t *packet,size_t len,int flags); + +/* Do not call directly! Used internally */ +ssize_t ns_sock_recv(const NSCONN *conn,void *buf,size_t len,int flags); + +/* This should be used to send serialized protobuf packets +* and have the output placed in the packet struct */ +ssize_t ns_send_pb(NSCONN *conn, const netpkt_t *packet,int flags); + +/* Send control messages */ +bool ns_send_control(NSCONN *conn, MessageType type); + +const char* ns_printable_message_type(MessageType type); + +/* Do not call directly! Used internally */ +ssize_t ns_sock_send(NSCONN *conn,const void *buf,size_t len,int flags); + +uint32_t ns_gen_client_id(void); + +/* Closes and cleans up */ +int ns_close(NSCONN *conn); + +/* Return current time in milliseconds */ +int64_t ns_get_current_millis(void); + +/* Is the packet a control packet? + * Any type other than DATA is a control packet, including fragments */ +bool is_control_packet(const ns_rx_packet_t *packet); + +/* Logic for handling control packets */ +bool process_control_packet(NSCONN *conn, const ns_rx_packet_t *packet); + +/* Is the packet a fragment packet? */ +bool is_fragment_packet(const ns_rx_packet_t *packet); + +/* Store a fragment in the fragment buffer */ +bool store_fragment(const NSCONN *conn, const NetworkMessage *network_message); + +/* Reassemble a fragment from the fragment buffer */ +bool reassemble_fragment(const NSCONN *conn, netpkt_t *pkt, uint32_t packet_count); + +/* Set up the socket. Accounts for the differences between local and remote modes */ +bool ns_socket_setup(NSCONN *conn); + +/* Is the switch in a connected state? Always returns true in local mode */ +bool ns_connected(const NSCONN *conn); + +/* Return a string with a properly formatted mac address. + * Note: Caller must free! */ +char* formatted_mac(uint8_t mac_addr[6]); + +/* Used for control packet info and logic */ +control_packet_info_t get_control_packet_info(ns_rx_packet_t packet, const uint8_t *my_mac); + +/* Used for data packet info and logic */ +data_packet_info_t get_data_packet_info(const netpkt_t *packet, const uint8_t *my_mac); + +/* Checks for a valid file descriptor */ +bool fd_valid(int fd); + +/* Wrapping increment for the sequence number */ +bool seq_increment(NSCONN *conn); + +#ifdef ENABLE_NET_SWITCH_LOG +static void +net_switch_log(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); +} +#else +# define net_switch_log(fmt, ...) +#endif + +#endif \ No newline at end of file diff --git a/src/network/network.c b/src/network/network.c index 239178a5d..9b56515e8 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -85,36 +85,43 @@ static const NETWORK_CARD net_cards[] = { // clang-format off { &device_none }, { &device_internal }, + /* ISA */ { &threec501_device }, { &threec503_device }, - { &pcnet_am79c960_device }, - { &pcnet_am79c961_device }, - { &de220p_device }, { &ne1000_compat_device }, - { &ne2000_compat_device }, { &ne2000_compat_8bit_device }, { &ne1000_device }, - { &ne2000_device }, - { &pcnet_am79c960_eb_device }, - { &rtl8019as_pnp_device }, { &wd8003e_device }, { &wd8003eb_device }, { &wd8013ebt_device }, + /* COM */ + { &modem_device }, + /* LPT */ { &plip_device }, + /* ISA16 */ + { &pcnet_am79c960_device }, + { &pcnet_am79c961_device }, + { &de220p_device }, + { &ne2000_compat_device }, + { &ne2000_device }, + { &pcnet_am79c960_eb_device }, + { &rtl8019as_pnp_device }, + /* MCA */ { ðernext_mc_device }, { &wd8003eta_device }, { &wd8003ea_device }, { &wd8013epa_device }, + /* VLB */ + { &pcnet_am79c960_vlb_device }, + /* PCI */ { &pcnet_am79c973_device }, { &pcnet_am79c970a_device }, + { &dec_tulip_21140_device }, + { &dec_tulip_21040_device }, { &dec_tulip_device }, + { &dec_tulip_21140_vpc_device }, { &rtl8029as_device }, { &rtl8139c_plus_device }, - { &dec_tulip_21140_device }, - { &dec_tulip_21140_vpc_device }, - { &dec_tulip_21040_device }, - { &pcnet_am79c960_vlb_device }, - { &modem_device }, { NULL } // clang-format on }; @@ -490,6 +497,19 @@ network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_lin card->host_drv.priv = card->host_drv.init(card, mac, net_cards_conf[net_card_current].host_dev_name, net_drv_error); break; #endif +#ifdef HAS_TAP + case NET_TYPE_TAP: + card->host_drv = net_tap_drv; + card->host_drv.priv = card->host_drv.init(card, mac, net_cards_conf[net_card_current].host_dev_name, net_drv_error); + break; +#endif +#ifdef USE_NETSWITCH + case NET_TYPE_NMSWITCH: + case NET_TYPE_NRSWITCH: + card->host_drv = net_netswitch_drv; + card->host_drv.priv = card->host_drv.init(card, mac, &net_cards_conf[net_card_current], net_drv_error); + break; +#endif /* USE_NETSWITCH */ default: card->host_drv.priv = NULL; break; @@ -501,6 +521,14 @@ network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_lin if (!card->host_drv.priv) { if(net_cards_conf[net_card_current].net_type != NET_TYPE_NONE) { +#ifdef USE_NETSWITCH + // FIXME: Hardcoded during dev + // FIXME: Remove when done! + if((net_cards_conf[net_card_current].net_type == NET_TYPE_NMSWITCH) || + (net_cards_conf[net_card_current].net_type == NET_TYPE_NRSWITCH)) + fatal("%s", net_drv_error); +#endif /* USE_NETSWITCH */ + // We're here because of a failure swprintf(tempmsg, sizeof_w(tempmsg), L"%ls:\n\n%s\n\n%ls", plat_get_string(STRING_NET_ERROR), net_drv_error, plat_get_string(STRING_NET_ERROR_DESC)); ui_msgbox(MBX_ERROR, tempmsg); diff --git a/src/network/networkmessage.pb.c b/src/network/networkmessage.pb.c new file mode 100644 index 000000000..c15f03e01 --- /dev/null +++ b/src/network/networkmessage.pb.c @@ -0,0 +1,19 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8-dev */ + +#include "networkmessage.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(Fragment, Fragment, AUTO) + + +PB_BIND(Ack, Ack, AUTO) + + +PB_BIND(NetworkMessage, NetworkMessage, AUTO) + + + + diff --git a/src/network/networkmessage.pb.h b/src/network/networkmessage.pb.h new file mode 100644 index 000000000..0a74e55b9 --- /dev/null +++ b/src/network/networkmessage.pb.h @@ -0,0 +1,140 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8-dev */ + +#ifndef PB_NETWORKMESSAGE_PB_H_INCLUDED +#define PB_NETWORKMESSAGE_PB_H_INCLUDED +#include "pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Enum definitions */ +typedef enum _MessageType { + MessageType_MESSAGE_TYPE_UNSPECIFIED = 0, + MessageType_MESSAGE_TYPE_DATA = 1, + MessageType_MESSAGE_TYPE_JOIN = 2, + MessageType_MESSAGE_TYPE_LEAVE = 3, + MessageType_MESSAGE_TYPE_KEEPALIVE = 4, + MessageType_MESSAGE_TYPE_FRAGMENT = 5, + MessageType_MESSAGE_TYPE_ACK = 6, + MessageType_MESSAGE_TYPE_CONNECT_REQUEST = 7, + MessageType_MESSAGE_TYPE_CONNECT_REPLY = 8 +} MessageType; + +/* Struct definitions */ +typedef struct _Fragment { + uint32_t id; + uint32_t sequence; + uint32_t total; +} Fragment; + +typedef struct _Ack { + uint32_t id; + uint32_t history; +} Ack; + +typedef struct _NetworkMessage { + MessageType message_type; + uint32_t client_id; + pb_bytes_array_t *mac; + pb_bytes_array_t *frame; + uint32_t flags; + uint32_t version; + bool has_ack; + Ack ack; + bool has_fragment; + Fragment fragment; + int64_t timestamp; + uint32_t sequence; +} NetworkMessage; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Helper constants for enums */ +#define _MessageType_MIN MessageType_MESSAGE_TYPE_UNSPECIFIED +#define _MessageType_MAX MessageType_MESSAGE_TYPE_CONNECT_REPLY +#define _MessageType_ARRAYSIZE ((MessageType)(MessageType_MESSAGE_TYPE_CONNECT_REPLY+1)) + + + +#define NetworkMessage_message_type_ENUMTYPE MessageType + + +/* Initializer values for message structs */ +#define Fragment_init_default {0, 0, 0} +#define Ack_init_default {0, 0} +#define NetworkMessage_init_default {_MessageType_MIN, 0, NULL, NULL, 0, 0, false, Ack_init_default, false, Fragment_init_default, 0, 0} +#define Fragment_init_zero {0, 0, 0} +#define Ack_init_zero {0, 0} +#define NetworkMessage_init_zero {_MessageType_MIN, 0, NULL, NULL, 0, 0, false, Ack_init_zero, false, Fragment_init_zero, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define Fragment_id_tag 1 +#define Fragment_sequence_tag 2 +#define Fragment_total_tag 3 +#define Ack_id_tag 1 +#define Ack_history_tag 2 +#define NetworkMessage_message_type_tag 1 +#define NetworkMessage_client_id_tag 2 +#define NetworkMessage_mac_tag 3 +#define NetworkMessage_frame_tag 4 +#define NetworkMessage_flags_tag 5 +#define NetworkMessage_version_tag 6 +#define NetworkMessage_ack_tag 7 +#define NetworkMessage_fragment_tag 8 +#define NetworkMessage_timestamp_tag 9 +#define NetworkMessage_sequence_tag 10 + +/* Struct field encoding specification for nanopb */ +#define Fragment_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, id, 1) \ +X(a, STATIC, SINGULAR, UINT32, sequence, 2) \ +X(a, STATIC, SINGULAR, UINT32, total, 3) +#define Fragment_CALLBACK NULL +#define Fragment_DEFAULT NULL + +#define Ack_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, id, 1) \ +X(a, STATIC, SINGULAR, UINT32, history, 2) +#define Ack_CALLBACK NULL +#define Ack_DEFAULT NULL + +#define NetworkMessage_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, message_type, 1) \ +X(a, STATIC, SINGULAR, UINT32, client_id, 2) \ +X(a, POINTER, SINGULAR, BYTES, mac, 3) \ +X(a, POINTER, SINGULAR, BYTES, frame, 4) \ +X(a, STATIC, SINGULAR, UINT32, flags, 5) \ +X(a, STATIC, SINGULAR, UINT32, version, 6) \ +X(a, STATIC, OPTIONAL, MESSAGE, ack, 7) \ +X(a, STATIC, OPTIONAL, MESSAGE, fragment, 8) \ +X(a, STATIC, SINGULAR, INT64, timestamp, 9) \ +X(a, STATIC, SINGULAR, UINT32, sequence, 10) +#define NetworkMessage_CALLBACK NULL +#define NetworkMessage_DEFAULT NULL +#define NetworkMessage_ack_MSGTYPE Ack +#define NetworkMessage_fragment_MSGTYPE Fragment + +extern const pb_msgdesc_t Fragment_msg; +extern const pb_msgdesc_t Ack_msg; +extern const pb_msgdesc_t NetworkMessage_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define Fragment_fields &Fragment_msg +#define Ack_fields &Ack_msg +#define NetworkMessage_fields &NetworkMessage_msg + +/* Maximum encoded size of messages (where known) */ +/* NetworkMessage_size depends on runtime parameters */ +#define Ack_size 12 +#define Fragment_size 18 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/network/networkmessage.proto.txt b/src/network/networkmessage.proto.txt new file mode 100644 index 000000000..9511f17c8 --- /dev/null +++ b/src/network/networkmessage.proto.txt @@ -0,0 +1,38 @@ +syntax = "proto3"; +import "nanopb.proto"; + +enum MessageType { + MESSAGE_TYPE_UNSPECIFIED = 0; + MESSAGE_TYPE_DATA = 1; + MESSAGE_TYPE_JOIN = 2; + MESSAGE_TYPE_LEAVE = 3; + MESSAGE_TYPE_KEEPALIVE = 4; + MESSAGE_TYPE_FRAGMENT = 5; + MESSAGE_TYPE_ACK = 6; + MESSAGE_TYPE_CONNECT_REQUEST = 7; + MESSAGE_TYPE_CONNECT_REPLY = 8; +} + +message Fragment { + uint32 id = 1; + uint32 sequence = 2; + uint32 total = 3; +} + +message Ack { + uint32 id = 1; + uint32 history = 2; +} + +message NetworkMessage { + MessageType message_type = 1; + uint32 client_id = 2; + bytes mac = 3 [(nanopb).type = FT_POINTER]; + bytes frame = 4 [(nanopb).type = FT_POINTER]; + uint32 flags = 5; + uint32 version = 6; + Ack ack = 7; + Fragment fragment = 8; + int64 timestamp = 9; + uint32 sequence = 10; +} \ No newline at end of file diff --git a/src/network/pb.h b/src/network/pb.h new file mode 100644 index 000000000..7433ac24b --- /dev/null +++ b/src/network/pb.h @@ -0,0 +1,917 @@ +/* Common parts of the nanopb library. Most of these are quite low-level + * stuff. For the high-level interface, see pb_encode.h and pb_decode.h. + */ + +#ifndef PB_H_INCLUDED +#define PB_H_INCLUDED + +/***************************************************************** + * Nanopb compilation time options. You can change these here by * + * uncommenting the lines, or on the compiler command line. * + *****************************************************************/ + +/* Enable support for dynamically allocated fields */ +#define PB_ENABLE_MALLOC 1 + +/* Define this if your CPU / compiler combination does not support + * unaligned memory access to packed structures. Note that packed + * structures are only used when requested in .proto options. */ +/* #define PB_NO_PACKED_STRUCTS 1 */ + +/* Increase the number of required fields that are tracked. + * A compiler warning will tell if you need this. */ +/* #define PB_MAX_REQUIRED_FIELDS 256 */ + +/* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */ +/* #define PB_FIELD_32BIT 1 */ + +/* Disable support for error messages in order to save some code space. */ +/* #define PB_NO_ERRMSG 1 */ + +/* Disable support for custom streams (support only memory buffers). */ +#define PB_BUFFER_ONLY 1 + +/* Disable support for 64-bit datatypes, for compilers without int64_t + or to save some code space. */ +/* #define PB_WITHOUT_64BIT 1 */ + +/* Don't encode scalar arrays as packed. This is only to be used when + * the decoder on the receiving side cannot process packed scalar arrays. + * Such example is older protobuf.js. */ +/* #define PB_ENCODE_ARRAYS_UNPACKED 1 */ + +/* Enable conversion of doubles to floats for platforms that do not + * support 64-bit doubles. Most commonly AVR. */ +/* #define PB_CONVERT_DOUBLE_FLOAT 1 */ + +/* Check whether incoming strings are valid UTF-8 sequences. Slows down + * the string processing slightly and slightly increases code size. */ +/* #define PB_VALIDATE_UTF8 1 */ + +/* This can be defined if the platform is little-endian and has 8-bit bytes. + * Normally it is automatically detected based on __BYTE_ORDER__ macro. */ +/* #define PB_LITTLE_ENDIAN_8BIT 1 */ + +/* Configure static assert mechanism. Instead of changing these, set your + * compiler to C11 standard mode if possible. */ +/* #define PB_C99_STATIC_ASSERT 1 */ +/* #define PB_NO_STATIC_ASSERT 1 */ + +/****************************************************************** + * You usually don't need to change anything below this line. * + * Feel free to look around and use the defined macros, though. * + ******************************************************************/ + + +/* Version of the nanopb library. Just in case you want to check it in + * your own program. */ +#define NANOPB_VERSION "nanopb-0.4.8-dev" + +/* Include all the system headers needed by nanopb. You will need the + * definitions of the following: + * - strlen, memcpy, memset functions + * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t + * - size_t + * - bool + * + * If you don't have the standard header files, you can instead provide + * a custom header that defines or includes all this. In that case, + * define PB_SYSTEM_HEADER to the path of this file. + */ +#ifdef PB_SYSTEM_HEADER +#include PB_SYSTEM_HEADER +#else +#include +#include +#include +#include +#include + +#ifdef PB_ENABLE_MALLOC +#include +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Macro for defining packed structures (compiler dependent). + * This just reduces memory requirements, but is not required. + */ +#if defined(PB_NO_PACKED_STRUCTS) + /* Disable struct packing */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed +#elif defined(__GNUC__) || defined(__clang__) + /* For GCC and clang */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed __attribute__((packed)) +#elif defined(__ICCARM__) || defined(__CC_ARM) + /* For IAR ARM and Keil MDK-ARM compilers */ +# define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") +# define PB_PACKED_STRUCT_END _Pragma("pack(pop)") +# define pb_packed +#elif defined(_MSC_VER) && (_MSC_VER >= 1500) + /* For Microsoft Visual C++ */ +# define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) +# define PB_PACKED_STRUCT_END __pragma(pack(pop)) +# define pb_packed +#else + /* Unknown compiler */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed +#endif + +/* Detect endianness */ +#ifndef PB_LITTLE_ENDIAN_8BIT +#if ((defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ + (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \ + defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \ + defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || \ + defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM)) \ + && CHAR_BIT == 8 +#define PB_LITTLE_ENDIAN_8BIT 1 +#endif +#endif + +/* Handly macro for suppressing unreferenced-parameter compiler warnings. */ +#ifndef PB_UNUSED +#define PB_UNUSED(x) (void)(x) +#endif + +/* Harvard-architecture processors may need special attributes for storing + * field information in program memory. */ +#ifndef PB_PROGMEM +#ifdef __AVR__ +#include +#define PB_PROGMEM PROGMEM +#define PB_PROGMEM_READU32(x) pgm_read_dword(&x) +#else +#define PB_PROGMEM +#define PB_PROGMEM_READU32(x) (x) +#endif +#endif + +/* Compile-time assertion, used for checking compatible compilation options. + * If this does not work properly on your compiler, use + * #define PB_NO_STATIC_ASSERT to disable it. + * + * But before doing that, check carefully the error message / place where it + * comes from to see if the error has a real cause. Unfortunately the error + * message is not always very clear to read, but you can see the reason better + * in the place where the PB_STATIC_ASSERT macro was called. + */ +#ifndef PB_NO_STATIC_ASSERT +# ifndef PB_STATIC_ASSERT +# if defined(__ICCARM__) + /* IAR has static_assert keyword but no _Static_assert */ +# define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); +# elif defined(_MSC_VER) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112) + /* MSVC in C89 mode supports static_assert() keyword anyway */ +# define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); +# elif defined(PB_C99_STATIC_ASSERT) + /* Classic negative-size-array static assert mechanism */ +# define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1]; +# define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) +# define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##_##LINE##_##COUNTER +# elif defined(__cplusplus) + /* C++11 standard static_assert mechanism */ +# define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); +# else + /* C11 standard _Static_assert mechanism */ +# define PB_STATIC_ASSERT(COND,MSG) _Static_assert(COND,#MSG); +# endif +# endif +#else + /* Static asserts disabled by PB_NO_STATIC_ASSERT */ +# define PB_STATIC_ASSERT(COND,MSG) +#endif + +/* Test that PB_STATIC_ASSERT works + * If you get errors here, you may need to do one of these: + * - Enable C11 standard support in your compiler + * - Define PB_C99_STATIC_ASSERT to enable C99 standard support + * - Define PB_NO_STATIC_ASSERT to disable static asserts altogether + */ +PB_STATIC_ASSERT(1, STATIC_ASSERT_IS_NOT_WORKING) + +/* Number of required fields to keep track of. */ +#ifndef PB_MAX_REQUIRED_FIELDS +#define PB_MAX_REQUIRED_FIELDS 64 +#endif + +#if PB_MAX_REQUIRED_FIELDS < 64 +#error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64). +#endif + +#ifdef PB_WITHOUT_64BIT +#ifdef PB_CONVERT_DOUBLE_FLOAT +/* Cannot use doubles without 64-bit types */ +#undef PB_CONVERT_DOUBLE_FLOAT +#endif +#endif + +/* List of possible field types. These are used in the autogenerated code. + * Least-significant 4 bits tell the scalar type + * Most-significant 4 bits specify repeated/required/packed etc. + */ + +typedef uint_least8_t pb_type_t; + +/**** Field data types ****/ + +/* Numeric types */ +#define PB_LTYPE_BOOL 0x00U /* bool */ +#define PB_LTYPE_VARINT 0x01U /* int32, int64, enum, bool */ +#define PB_LTYPE_UVARINT 0x02U /* uint32, uint64 */ +#define PB_LTYPE_SVARINT 0x03U /* sint32, sint64 */ +#define PB_LTYPE_FIXED32 0x04U /* fixed32, sfixed32, float */ +#define PB_LTYPE_FIXED64 0x05U /* fixed64, sfixed64, double */ + +/* Marker for last packable field type. */ +#define PB_LTYPE_LAST_PACKABLE 0x05U + +/* Byte array with pre-allocated buffer. + * data_size is the length of the allocated PB_BYTES_ARRAY structure. */ +#define PB_LTYPE_BYTES 0x06U + +/* String with pre-allocated buffer. + * data_size is the maximum length. */ +#define PB_LTYPE_STRING 0x07U + +/* Submessage + * submsg_fields is pointer to field descriptions */ +#define PB_LTYPE_SUBMESSAGE 0x08U + +/* Submessage with pre-decoding callback + * The pre-decoding callback is stored as pb_callback_t right before pSize. + * submsg_fields is pointer to field descriptions */ +#define PB_LTYPE_SUBMSG_W_CB 0x09U + +/* Extension pseudo-field + * The field contains a pointer to pb_extension_t */ +#define PB_LTYPE_EXTENSION 0x0AU + +/* Byte array with inline, pre-allocated byffer. + * data_size is the length of the inline, allocated buffer. + * This differs from PB_LTYPE_BYTES by defining the element as + * pb_byte_t[data_size] rather than pb_bytes_array_t. */ +#define PB_LTYPE_FIXED_LENGTH_BYTES 0x0BU + +/* Number of declared LTYPES */ +#define PB_LTYPES_COUNT 0x0CU +#define PB_LTYPE_MASK 0x0FU + +/**** Field repetition rules ****/ + +#define PB_HTYPE_REQUIRED 0x00U +#define PB_HTYPE_OPTIONAL 0x10U +#define PB_HTYPE_SINGULAR 0x10U +#define PB_HTYPE_REPEATED 0x20U +#define PB_HTYPE_FIXARRAY 0x20U +#define PB_HTYPE_ONEOF 0x30U +#define PB_HTYPE_MASK 0x30U + +/**** Field allocation types ****/ + +#define PB_ATYPE_STATIC 0x00U +#define PB_ATYPE_POINTER 0x80U +#define PB_ATYPE_CALLBACK 0x40U +#define PB_ATYPE_MASK 0xC0U + +#define PB_ATYPE(x) ((x) & PB_ATYPE_MASK) +#define PB_HTYPE(x) ((x) & PB_HTYPE_MASK) +#define PB_LTYPE(x) ((x) & PB_LTYPE_MASK) +#define PB_LTYPE_IS_SUBMSG(x) (PB_LTYPE(x) == PB_LTYPE_SUBMESSAGE || \ + PB_LTYPE(x) == PB_LTYPE_SUBMSG_W_CB) + +/* Data type used for storing sizes of struct fields + * and array counts. + */ +#if defined(PB_FIELD_32BIT) + typedef uint32_t pb_size_t; + typedef int32_t pb_ssize_t; +#else + typedef uint_least16_t pb_size_t; + typedef int_least16_t pb_ssize_t; +#endif +#define PB_SIZE_MAX ((pb_size_t)-1) + +/* Data type for storing encoded data and other byte streams. + * This typedef exists to support platforms where uint8_t does not exist. + * You can regard it as equivalent on uint8_t on other platforms. + */ +typedef uint_least8_t pb_byte_t; + +/* Forward declaration of struct types */ +typedef struct pb_istream_s pb_istream_t; +typedef struct pb_ostream_s pb_ostream_t; +typedef struct pb_field_iter_s pb_field_iter_t; + +/* This structure is used in auto-generated constants + * to specify struct fields. + */ +typedef struct pb_msgdesc_s pb_msgdesc_t; +struct pb_msgdesc_s { + const uint32_t *field_info; + const pb_msgdesc_t * const * submsg_info; + const pb_byte_t *default_value; + + bool (*field_callback)(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field); + + pb_size_t field_count; + pb_size_t required_field_count; + pb_size_t largest_tag; +}; + +/* Iterator for message descriptor */ +struct pb_field_iter_s { + const pb_msgdesc_t *descriptor; /* Pointer to message descriptor constant */ + void *message; /* Pointer to start of the structure */ + + pb_size_t index; /* Index of the field */ + pb_size_t field_info_index; /* Index to descriptor->field_info array */ + pb_size_t required_field_index; /* Index that counts only the required fields */ + pb_size_t submessage_index; /* Index that counts only submessages */ + + pb_size_t tag; /* Tag of current field */ + pb_size_t data_size; /* sizeof() of a single item */ + pb_size_t array_size; /* Number of array entries */ + pb_type_t type; /* Type of current field */ + + void *pField; /* Pointer to current field in struct */ + void *pData; /* Pointer to current data contents. Different than pField for arrays and pointers. */ + void *pSize; /* Pointer to count/has field */ + + const pb_msgdesc_t *submsg_desc; /* For submessage fields, pointer to field descriptor for the submessage. */ +}; + +/* For compatibility with legacy code */ +typedef pb_field_iter_t pb_field_t; + +/* Make sure that the standard integer types are of the expected sizes. + * Otherwise fixed32/fixed64 fields can break. + * + * If you get errors here, it probably means that your stdint.h is not + * correct for your platform. + */ +#ifndef PB_WITHOUT_64BIT +PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE) +#endif + +/* This structure is used for 'bytes' arrays. + * It has the number of bytes in the beginning, and after that an array. + * Note that actual structs used will have a different length of bytes array. + */ +#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; } +#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes)) + +struct pb_bytes_array_s { + pb_size_t size; + pb_byte_t bytes[1]; +}; +typedef struct pb_bytes_array_s pb_bytes_array_t; + +/* This structure is used for giving the callback function. + * It is stored in the message structure and filled in by the method that + * calls pb_decode. + * + * The decoding callback will be given a limited-length stream + * If the wire type was string, the length is the length of the string. + * If the wire type was a varint/fixed32/fixed64, the length is the length + * of the actual value. + * The function may be called multiple times (especially for repeated types, + * but also otherwise if the message happens to contain the field multiple + * times.) + * + * The encoding callback will receive the actual output stream. + * It should write all the data in one call, including the field tag and + * wire type. It can write multiple fields. + * + * The callback can be null if you want to skip a field. + */ +typedef struct pb_callback_s pb_callback_t; +struct pb_callback_s { + /* Callback functions receive a pointer to the arg field. + * You can access the value of the field as *arg, and modify it if needed. + */ + union { + bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); + bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg); + } funcs; + + /* Free arg for use by callback */ + void *arg; +}; + +extern bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field); + +/* Wire types. Library user needs these only in encoder callbacks. */ +typedef enum { + PB_WT_VARINT = 0, + PB_WT_64BIT = 1, + PB_WT_STRING = 2, + PB_WT_32BIT = 5, + PB_WT_PACKED = 255 /* PB_WT_PACKED is internal marker for packed arrays. */ +} pb_wire_type_t; + +/* Structure for defining the handling of unknown/extension fields. + * Usually the pb_extension_type_t structure is automatically generated, + * while the pb_extension_t structure is created by the user. However, + * if you want to catch all unknown fields, you can also create a custom + * pb_extension_type_t with your own callback. + */ +typedef struct pb_extension_type_s pb_extension_type_t; +typedef struct pb_extension_s pb_extension_t; +struct pb_extension_type_s { + /* Called for each unknown field in the message. + * If you handle the field, read off all of its data and return true. + * If you do not handle the field, do not read anything and return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*decode)(pb_istream_t *stream, pb_extension_t *extension, + uint32_t tag, pb_wire_type_t wire_type); + + /* Called once after all regular fields have been encoded. + * If you have something to write, do so and return true. + * If you do not have anything to write, just return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); + + /* Free field for use by the callback. */ + const void *arg; +}; + +struct pb_extension_s { + /* Type describing the extension field. Usually you'll initialize + * this to a pointer to the automatically generated structure. */ + const pb_extension_type_t *type; + + /* Destination for the decoded data. This must match the datatype + * of the extension field. */ + void *dest; + + /* Pointer to the next extension handler, or NULL. + * If this extension does not match a field, the next handler is + * automatically called. */ + pb_extension_t *next; + + /* The decoder sets this to true if the extension was found. + * Ignored for encoding. */ + bool found; +}; + +#define pb_extension_init_zero {NULL,NULL,NULL,false} + +/* Memory allocation functions to use. You can define pb_realloc and + * pb_free to custom functions if you want. */ +#ifdef PB_ENABLE_MALLOC +# ifndef pb_realloc +# define pb_realloc(ptr, size) realloc(ptr, size) +# endif +# ifndef pb_free +# define pb_free(ptr) free(ptr) +# endif +#endif + +/* This is used to inform about need to regenerate .pb.h/.pb.c files. */ +#define PB_PROTO_HEADER_VERSION 40 + +/* These macros are used to declare pb_field_t's in the constant array. */ +/* Size of a structure member, in bytes. */ +#define pb_membersize(st, m) (sizeof ((st*)0)->m) +/* Number of entries in an array. */ +#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) +/* Delta from start of one member to the start of another member. */ +#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) + +/* Force expansion of macro value */ +#define PB_EXPAND(x) x + +/* Binding of a message field set into a specific structure */ +#define PB_BIND(msgname, structname, width) \ + const uint32_t structname ## _field_info[] PB_PROGMEM = \ + { \ + msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ ## width, structname) \ + 0 \ + }; \ + const pb_msgdesc_t* const structname ## _submsg_info[] = \ + { \ + msgname ## _FIELDLIST(PB_GEN_SUBMSG_INFO, structname) \ + NULL \ + }; \ + const pb_msgdesc_t structname ## _msg = \ + { \ + structname ## _field_info, \ + structname ## _submsg_info, \ + msgname ## _DEFAULT, \ + msgname ## _CALLBACK, \ + 0 msgname ## _FIELDLIST(PB_GEN_FIELD_COUNT, structname), \ + 0 msgname ## _FIELDLIST(PB_GEN_REQ_FIELD_COUNT, structname), \ + 0 msgname ## _FIELDLIST(PB_GEN_LARGEST_TAG, structname), \ + }; \ + msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ASSERT_ ## width, structname) + +#define PB_GEN_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) +1 +#define PB_GEN_REQ_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) \ + + (PB_HTYPE_ ## htype == PB_HTYPE_REQUIRED) +#define PB_GEN_LARGEST_TAG(structname, atype, htype, ltype, fieldname, tag) \ + * 0 + tag + +/* X-macro for generating the entries in struct_field_info[] array. */ +#define PB_GEN_FIELD_INFO_1(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_1(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_2(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_2(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_4(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_4(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_8(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_8(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_AUTO(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_ ## atype, _PB_HTYPE_ ## htype, _PB_LTYPE_ ## ltype), \ + tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_FIELDINFO_AUTO2(width, tag, type, data_offset, data_size, size_offset, array_size) \ + PB_FIELDINFO_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) + +#define PB_FIELDINFO_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) \ + PB_FIELDINFO_ ## width(tag, type, data_offset, data_size, size_offset, array_size) + +/* X-macro for generating asserts that entries fit in struct_field_info[] array. + * The structure of macros here must match the structure above in PB_GEN_FIELD_INFO_x(), + * but it is not easily reused because of how macro substitutions work. */ +#define PB_GEN_FIELD_INFO_ASSERT_1(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_1(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_ASSERT_2(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_2(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_ASSERT_4(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_4(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_ASSERT_8(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_8(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_ASSERT_AUTO(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_ ## atype, _PB_HTYPE_ ## htype, _PB_LTYPE_ ## ltype), \ + tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_FIELDINFO_ASSERT_AUTO2(width, tag, type, data_offset, data_size, size_offset, array_size) \ + PB_FIELDINFO_ASSERT_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) + +#define PB_FIELDINFO_ASSERT_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) \ + PB_FIELDINFO_ASSERT_ ## width(tag, type, data_offset, data_size, size_offset, array_size) + +#define PB_DATA_OFFSET_STATIC(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) +#define PB_DATA_OFFSET_POINTER(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) +#define PB_DATA_OFFSET_CALLBACK(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) +#define PB_DO_PB_HTYPE_REQUIRED(structname, fieldname) offsetof(structname, fieldname) +#define PB_DO_PB_HTYPE_SINGULAR(structname, fieldname) offsetof(structname, fieldname) +#define PB_DO_PB_HTYPE_ONEOF(structname, fieldname) offsetof(structname, PB_ONEOF_NAME(FULL, fieldname)) +#define PB_DO_PB_HTYPE_OPTIONAL(structname, fieldname) offsetof(structname, fieldname) +#define PB_DO_PB_HTYPE_REPEATED(structname, fieldname) offsetof(structname, fieldname) +#define PB_DO_PB_HTYPE_FIXARRAY(structname, fieldname) offsetof(structname, fieldname) + +#define PB_SIZE_OFFSET_STATIC(htype, structname, fieldname) PB_SO ## htype(structname, fieldname) +#define PB_SIZE_OFFSET_POINTER(htype, structname, fieldname) PB_SO_PTR ## htype(structname, fieldname) +#define PB_SIZE_OFFSET_CALLBACK(htype, structname, fieldname) PB_SO_CB ## htype(structname, fieldname) +#define PB_SO_PB_HTYPE_REQUIRED(structname, fieldname) 0 +#define PB_SO_PB_HTYPE_SINGULAR(structname, fieldname) 0 +#define PB_SO_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF2(structname, PB_ONEOF_NAME(FULL, fieldname), PB_ONEOF_NAME(UNION, fieldname)) +#define PB_SO_PB_HTYPE_ONEOF2(structname, fullname, unionname) PB_SO_PB_HTYPE_ONEOF3(structname, fullname, unionname) +#define PB_SO_PB_HTYPE_ONEOF3(structname, fullname, unionname) pb_delta(structname, fullname, which_ ## unionname) +#define PB_SO_PB_HTYPE_OPTIONAL(structname, fieldname) pb_delta(structname, fieldname, has_ ## fieldname) +#define PB_SO_PB_HTYPE_REPEATED(structname, fieldname) pb_delta(structname, fieldname, fieldname ## _count) +#define PB_SO_PB_HTYPE_FIXARRAY(structname, fieldname) 0 +#define PB_SO_PTR_PB_HTYPE_REQUIRED(structname, fieldname) 0 +#define PB_SO_PTR_PB_HTYPE_SINGULAR(structname, fieldname) 0 +#define PB_SO_PTR_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF(structname, fieldname) +#define PB_SO_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) 0 +#define PB_SO_PTR_PB_HTYPE_REPEATED(structname, fieldname) PB_SO_PB_HTYPE_REPEATED(structname, fieldname) +#define PB_SO_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_REQUIRED(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_SINGULAR(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF(structname, fieldname) +#define PB_SO_CB_PB_HTYPE_OPTIONAL(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_REPEATED(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_FIXARRAY(structname, fieldname) 0 + +#define PB_ARRAY_SIZE_STATIC(htype, structname, fieldname) PB_AS ## htype(structname, fieldname) +#define PB_ARRAY_SIZE_POINTER(htype, structname, fieldname) PB_AS_PTR ## htype(structname, fieldname) +#define PB_ARRAY_SIZE_CALLBACK(htype, structname, fieldname) 1 +#define PB_AS_PB_HTYPE_REQUIRED(structname, fieldname) 1 +#define PB_AS_PB_HTYPE_SINGULAR(structname, fieldname) 1 +#define PB_AS_PB_HTYPE_OPTIONAL(structname, fieldname) 1 +#define PB_AS_PB_HTYPE_ONEOF(structname, fieldname) 1 +#define PB_AS_PB_HTYPE_REPEATED(structname, fieldname) pb_arraysize(structname, fieldname) +#define PB_AS_PB_HTYPE_FIXARRAY(structname, fieldname) pb_arraysize(structname, fieldname) +#define PB_AS_PTR_PB_HTYPE_REQUIRED(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_SINGULAR(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_ONEOF(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_REPEATED(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) pb_arraysize(structname, fieldname[0]) + +#define PB_DATA_SIZE_STATIC(htype, structname, fieldname) PB_DS ## htype(structname, fieldname) +#define PB_DATA_SIZE_POINTER(htype, structname, fieldname) PB_DS_PTR ## htype(structname, fieldname) +#define PB_DATA_SIZE_CALLBACK(htype, structname, fieldname) PB_DS_CB ## htype(structname, fieldname) +#define PB_DS_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) +#define PB_DS_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)[0]) +#define PB_DS_PTR_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0][0]) +#define PB_DS_CB_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_CB_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_CB_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_CB_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) +#define PB_DS_CB_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_CB_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname) + +#define PB_ONEOF_NAME(type, tuple) PB_EXPAND(PB_ONEOF_NAME_ ## type tuple) +#define PB_ONEOF_NAME_UNION(unionname,membername,fullname) unionname +#define PB_ONEOF_NAME_MEMBER(unionname,membername,fullname) membername +#define PB_ONEOF_NAME_FULL(unionname,membername,fullname) fullname + +#define PB_GEN_SUBMSG_INFO(structname, atype, htype, ltype, fieldname, tag) \ + PB_SUBMSG_INFO_ ## htype(_PB_LTYPE_ ## ltype, structname, fieldname) + +#define PB_SUBMSG_INFO_REQUIRED(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SUBMSG_INFO_SINGULAR(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SUBMSG_INFO_OPTIONAL(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SUBMSG_INFO_ONEOF(ltype, structname, fieldname) PB_SUBMSG_INFO_ONEOF2(ltype, structname, PB_ONEOF_NAME(UNION, fieldname), PB_ONEOF_NAME(MEMBER, fieldname)) +#define PB_SUBMSG_INFO_ONEOF2(ltype, structname, unionname, membername) PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) +#define PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) PB_SI ## ltype(structname ## _ ## unionname ## _ ## membername ## _MSGTYPE) +#define PB_SUBMSG_INFO_REPEATED(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SUBMSG_INFO_FIXARRAY(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SI_PB_LTYPE_BOOL(t) +#define PB_SI_PB_LTYPE_BYTES(t) +#define PB_SI_PB_LTYPE_DOUBLE(t) +#define PB_SI_PB_LTYPE_ENUM(t) +#define PB_SI_PB_LTYPE_UENUM(t) +#define PB_SI_PB_LTYPE_FIXED32(t) +#define PB_SI_PB_LTYPE_FIXED64(t) +#define PB_SI_PB_LTYPE_FLOAT(t) +#define PB_SI_PB_LTYPE_INT32(t) +#define PB_SI_PB_LTYPE_INT64(t) +#define PB_SI_PB_LTYPE_MESSAGE(t) PB_SUBMSG_DESCRIPTOR(t) +#define PB_SI_PB_LTYPE_MSG_W_CB(t) PB_SUBMSG_DESCRIPTOR(t) +#define PB_SI_PB_LTYPE_SFIXED32(t) +#define PB_SI_PB_LTYPE_SFIXED64(t) +#define PB_SI_PB_LTYPE_SINT32(t) +#define PB_SI_PB_LTYPE_SINT64(t) +#define PB_SI_PB_LTYPE_STRING(t) +#define PB_SI_PB_LTYPE_UINT32(t) +#define PB_SI_PB_LTYPE_UINT64(t) +#define PB_SI_PB_LTYPE_EXTENSION(t) +#define PB_SI_PB_LTYPE_FIXED_LENGTH_BYTES(t) +#define PB_SUBMSG_DESCRIPTOR(t) &(t ## _msg), + +/* The field descriptors use a variable width format, with width of either + * 1, 2, 4 or 8 of 32-bit words. The two lowest bytes of the first byte always + * encode the descriptor size, 6 lowest bits of field tag number, and 8 bits + * of the field type. + * + * Descriptor size is encoded as 0 = 1 word, 1 = 2 words, 2 = 4 words, 3 = 8 words. + * + * Formats, listed starting with the least significant bit of the first word. + * 1 word: [2-bit len] [6-bit tag] [8-bit type] [8-bit data_offset] [4-bit size_offset] [4-bit data_size] + * + * 2 words: [2-bit len] [6-bit tag] [8-bit type] [12-bit array_size] [4-bit size_offset] + * [16-bit data_offset] [12-bit data_size] [4-bit tag>>6] + * + * 4 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit array_size] + * [8-bit size_offset] [24-bit tag>>6] + * [32-bit data_offset] + * [32-bit data_size] + * + * 8 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit reserved] + * [8-bit size_offset] [24-bit tag>>6] + * [32-bit data_offset] + * [32-bit data_size] + * [32-bit array_size] + * [32-bit reserved] + * [32-bit reserved] + * [32-bit reserved] + */ + +#define PB_FIELDINFO_1(tag, type, data_offset, data_size, size_offset, array_size) \ + (0 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(data_offset) & 0xFF) << 16) | \ + (((uint32_t)(size_offset) & 0x0F) << 24) | (((uint32_t)(data_size) & 0x0F) << 28)), + +#define PB_FIELDINFO_2(tag, type, data_offset, data_size, size_offset, array_size) \ + (1 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFF) << 16) | (((uint32_t)(size_offset) & 0x0F) << 28)), \ + (((uint32_t)(data_offset) & 0xFFFF) | (((uint32_t)(data_size) & 0xFFF) << 16) | (((uint32_t)(tag) & 0x3c0) << 22)), + +#define PB_FIELDINFO_4(tag, type, data_offset, data_size, size_offset, array_size) \ + (2 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFFF) << 16)), \ + ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ + (data_offset), (data_size), + +#define PB_FIELDINFO_8(tag, type, data_offset, data_size, size_offset, array_size) \ + (3 | (((tag) << 2) & 0xFF) | ((type) << 8)), \ + ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ + (data_offset), (data_size), (array_size), 0, 0, 0, + +/* These assertions verify that the field information fits in the allocated space. + * The generator tries to automatically determine the correct width that can fit all + * data associated with a message. These asserts will fail only if there has been a + * problem in the automatic logic - this may be worth reporting as a bug. As a workaround, + * you can increase the descriptor width by defining PB_FIELDINFO_WIDTH or by setting + * descriptorsize option in .options file. + */ +#define PB_FITS(value,bits) ((uint32_t)(value) < ((uint32_t)1<2GB messages with nanopb anyway. + */ +#define PB_FIELDINFO_ASSERT_4(tag, type, data_offset, data_size, size_offset, array_size) \ + PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS(size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,16), FIELDINFO_DOES_NOT_FIT_width4_field ## tag) + +#define PB_FIELDINFO_ASSERT_8(tag, type, data_offset, data_size, size_offset, array_size) \ + PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS(size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,31), FIELDINFO_DOES_NOT_FIT_width8_field ## tag) +#endif + + +/* Automatic picking of FIELDINFO width: + * Uses width 1 when possible, otherwise resorts to width 2. + * This is used when PB_BIND() is called with "AUTO" as the argument. + * The generator will give explicit size argument when it knows that a message + * structure grows beyond 1-word format limits. + */ +#define PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype) PB_FI_WIDTH ## atype(htype, ltype) +#define PB_FI_WIDTH_PB_ATYPE_STATIC(htype, ltype) PB_FI_WIDTH ## htype(ltype) +#define PB_FI_WIDTH_PB_ATYPE_POINTER(htype, ltype) PB_FI_WIDTH ## htype(ltype) +#define PB_FI_WIDTH_PB_ATYPE_CALLBACK(htype, ltype) 2 +#define PB_FI_WIDTH_PB_HTYPE_REQUIRED(ltype) PB_FI_WIDTH ## ltype +#define PB_FI_WIDTH_PB_HTYPE_SINGULAR(ltype) PB_FI_WIDTH ## ltype +#define PB_FI_WIDTH_PB_HTYPE_OPTIONAL(ltype) PB_FI_WIDTH ## ltype +#define PB_FI_WIDTH_PB_HTYPE_ONEOF(ltype) PB_FI_WIDTH ## ltype +#define PB_FI_WIDTH_PB_HTYPE_REPEATED(ltype) 2 +#define PB_FI_WIDTH_PB_HTYPE_FIXARRAY(ltype) 2 +#define PB_FI_WIDTH_PB_LTYPE_BOOL 1 +#define PB_FI_WIDTH_PB_LTYPE_BYTES 2 +#define PB_FI_WIDTH_PB_LTYPE_DOUBLE 1 +#define PB_FI_WIDTH_PB_LTYPE_ENUM 1 +#define PB_FI_WIDTH_PB_LTYPE_UENUM 1 +#define PB_FI_WIDTH_PB_LTYPE_FIXED32 1 +#define PB_FI_WIDTH_PB_LTYPE_FIXED64 1 +#define PB_FI_WIDTH_PB_LTYPE_FLOAT 1 +#define PB_FI_WIDTH_PB_LTYPE_INT32 1 +#define PB_FI_WIDTH_PB_LTYPE_INT64 1 +#define PB_FI_WIDTH_PB_LTYPE_MESSAGE 2 +#define PB_FI_WIDTH_PB_LTYPE_MSG_W_CB 2 +#define PB_FI_WIDTH_PB_LTYPE_SFIXED32 1 +#define PB_FI_WIDTH_PB_LTYPE_SFIXED64 1 +#define PB_FI_WIDTH_PB_LTYPE_SINT32 1 +#define PB_FI_WIDTH_PB_LTYPE_SINT64 1 +#define PB_FI_WIDTH_PB_LTYPE_STRING 2 +#define PB_FI_WIDTH_PB_LTYPE_UINT32 1 +#define PB_FI_WIDTH_PB_LTYPE_UINT64 1 +#define PB_FI_WIDTH_PB_LTYPE_EXTENSION 1 +#define PB_FI_WIDTH_PB_LTYPE_FIXED_LENGTH_BYTES 2 + +/* The mapping from protobuf types to LTYPEs is done using these macros. */ +#define PB_LTYPE_MAP_BOOL PB_LTYPE_BOOL +#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES +#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT +#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE +#define PB_LTYPE_MAP_MSG_W_CB PB_LTYPE_SUBMSG_W_CB +#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING +#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION +#define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES + +/* These macros are used for giving out error messages. + * They are mostly a debugging aid; the main error information + * is the true/false return value from functions. + * Some code space can be saved by disabling the error + * messages if not used. + * + * PB_SET_ERROR() sets the error message if none has been set yet. + * msg must be a constant string literal. + * PB_GET_ERROR() always returns a pointer to a string. + * PB_RETURN_ERROR() sets the error and returns false from current + * function. + */ +#ifdef PB_NO_ERRMSG +#define PB_SET_ERROR(stream, msg) PB_UNUSED(stream) +#define PB_GET_ERROR(stream) "(errmsg disabled)" +#else +#define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg)) +#define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)") +#endif + +#define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#ifdef __cplusplus +#if __cplusplus >= 201103L +#define PB_CONSTEXPR constexpr +#else // __cplusplus >= 201103L +#define PB_CONSTEXPR +#endif // __cplusplus >= 201103L + +#if __cplusplus >= 201703L +#define PB_INLINE_CONSTEXPR inline constexpr +#else // __cplusplus >= 201703L +#define PB_INLINE_CONSTEXPR PB_CONSTEXPR +#endif // __cplusplus >= 201703L + +extern "C++" +{ +namespace nanopb { +// Each type will be partially specialized by the generator. +template struct MessageDescriptor; +} // namespace nanopb +} +#endif /* __cplusplus */ + +#endif diff --git a/src/network/pb_common.c b/src/network/pb_common.c new file mode 100644 index 000000000..6aee76b1e --- /dev/null +++ b/src/network/pb_common.c @@ -0,0 +1,388 @@ +/* pb_common.c: Common support functions for pb_encode.c and pb_decode.c. + * + * 2014 Petteri Aimonen + */ + +#include "pb_common.h" + +static bool load_descriptor_values(pb_field_iter_t *iter) +{ + uint32_t word0; + uint32_t data_offset; + int_least8_t size_offset; + + if (iter->index >= iter->descriptor->field_count) + return false; + + word0 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index]); + iter->type = (pb_type_t)((word0 >> 8) & 0xFF); + + switch(word0 & 3) + { + case 0: { + /* 1-word format */ + iter->array_size = 1; + iter->tag = (pb_size_t)((word0 >> 2) & 0x3F); + size_offset = (int_least8_t)((word0 >> 24) & 0x0F); + data_offset = (word0 >> 16) & 0xFF; + iter->data_size = (pb_size_t)((word0 >> 28) & 0x0F); + break; + } + + case 1: { + /* 2-word format */ + uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); + + iter->array_size = (pb_size_t)((word0 >> 16) & 0x0FFF); + iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 28) << 6)); + size_offset = (int_least8_t)((word0 >> 28) & 0x0F); + data_offset = word1 & 0xFFFF; + iter->data_size = (pb_size_t)((word1 >> 16) & 0x0FFF); + break; + } + + case 2: { + /* 4-word format */ + uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); + uint32_t word2 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 2]); + uint32_t word3 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 3]); + + iter->array_size = (pb_size_t)(word0 >> 16); + iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 8) << 6)); + size_offset = (int_least8_t)(word1 & 0xFF); + data_offset = word2; + iter->data_size = (pb_size_t)word3; + break; + } + + default: { + /* 8-word format */ + uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); + uint32_t word2 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 2]); + uint32_t word3 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 3]); + uint32_t word4 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 4]); + + iter->array_size = (pb_size_t)word4; + iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 8) << 6)); + size_offset = (int_least8_t)(word1 & 0xFF); + data_offset = word2; + iter->data_size = (pb_size_t)word3; + break; + } + } + + if (!iter->message) + { + /* Avoid doing arithmetic on null pointers, it is undefined */ + iter->pField = NULL; + iter->pSize = NULL; + } + else + { + iter->pField = (char*)iter->message + data_offset; + + if (size_offset) + { + iter->pSize = (char*)iter->pField - size_offset; + } + else if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && + (PB_ATYPE(iter->type) == PB_ATYPE_STATIC || + PB_ATYPE(iter->type) == PB_ATYPE_POINTER)) + { + /* Fixed count array */ + iter->pSize = &iter->array_size; + } + else + { + iter->pSize = NULL; + } + + if (PB_ATYPE(iter->type) == PB_ATYPE_POINTER && iter->pField != NULL) + { + iter->pData = *(void**)iter->pField; + } + else + { + iter->pData = iter->pField; + } + } + + if (PB_LTYPE_IS_SUBMSG(iter->type)) + { + iter->submsg_desc = iter->descriptor->submsg_info[iter->submessage_index]; + } + else + { + iter->submsg_desc = NULL; + } + + return true; +} + +static void advance_iterator(pb_field_iter_t *iter) +{ + iter->index++; + + if (iter->index >= iter->descriptor->field_count) + { + /* Restart */ + iter->index = 0; + iter->field_info_index = 0; + iter->submessage_index = 0; + iter->required_field_index = 0; + } + else + { + /* Increment indexes based on previous field type. + * All field info formats have the following fields: + * - lowest 2 bits tell the amount of words in the descriptor (2^n words) + * - bits 2..7 give the lowest bits of tag number. + * - bits 8..15 give the field type. + */ + uint32_t prev_descriptor = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index]); + pb_type_t prev_type = (prev_descriptor >> 8) & 0xFF; + pb_size_t descriptor_len = (pb_size_t)(1 << (prev_descriptor & 3)); + + /* Add to fields. + * The cast to pb_size_t is needed to avoid -Wconversion warning. + * Because the data is is constants from generator, there is no danger of overflow. + */ + iter->field_info_index = (pb_size_t)(iter->field_info_index + descriptor_len); + iter->required_field_index = (pb_size_t)(iter->required_field_index + (PB_HTYPE(prev_type) == PB_HTYPE_REQUIRED)); + iter->submessage_index = (pb_size_t)(iter->submessage_index + PB_LTYPE_IS_SUBMSG(prev_type)); + } +} + +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, void *message) +{ + memset(iter, 0, sizeof(*iter)); + + iter->descriptor = desc; + iter->message = message; + + return load_descriptor_values(iter); +} + +bool pb_field_iter_begin_extension(pb_field_iter_t *iter, pb_extension_t *extension) +{ + const pb_msgdesc_t *msg = (const pb_msgdesc_t*)extension->type->arg; + bool status; + + uint32_t word0 = PB_PROGMEM_READU32(msg->field_info[0]); + if (PB_ATYPE(word0 >> 8) == PB_ATYPE_POINTER) + { + /* For pointer extensions, the pointer is stored directly + * in the extension structure. This avoids having an extra + * indirection. */ + status = pb_field_iter_begin(iter, msg, &extension->dest); + } + else + { + status = pb_field_iter_begin(iter, msg, extension->dest); + } + + iter->pSize = &extension->found; + return status; +} + +bool pb_field_iter_next(pb_field_iter_t *iter) +{ + advance_iterator(iter); + (void)load_descriptor_values(iter); + return iter->index != 0; +} + +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag) +{ + if (iter->tag == tag) + { + return true; /* Nothing to do, correct field already. */ + } + else if (tag > iter->descriptor->largest_tag) + { + return false; + } + else + { + pb_size_t start = iter->index; + uint32_t fieldinfo; + + if (tag < iter->tag) + { + /* Fields are in tag number order, so we know that tag is between + * 0 and our start position. Setting index to end forces + * advance_iterator() call below to restart from beginning. */ + iter->index = iter->descriptor->field_count; + } + + do + { + /* Advance iterator but don't load values yet */ + advance_iterator(iter); + + /* Do fast check for tag number match */ + fieldinfo = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index]); + + if (((fieldinfo >> 2) & 0x3F) == (tag & 0x3F)) + { + /* Good candidate, check further */ + (void)load_descriptor_values(iter); + + if (iter->tag == tag && + PB_LTYPE(iter->type) != PB_LTYPE_EXTENSION) + { + /* Found it */ + return true; + } + } + } while (iter->index != start); + + /* Searched all the way back to start, and found nothing. */ + (void)load_descriptor_values(iter); + return false; + } +} + +bool pb_field_iter_find_extension(pb_field_iter_t *iter) +{ + if (PB_LTYPE(iter->type) == PB_LTYPE_EXTENSION) + { + return true; + } + else + { + pb_size_t start = iter->index; + uint32_t fieldinfo; + + do + { + /* Advance iterator but don't load values yet */ + advance_iterator(iter); + + /* Do fast check for field type */ + fieldinfo = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index]); + + if (PB_LTYPE((fieldinfo >> 8) & 0xFF) == PB_LTYPE_EXTENSION) + { + return load_descriptor_values(iter); + } + } while (iter->index != start); + + /* Searched all the way back to start, and found nothing. */ + (void)load_descriptor_values(iter); + return false; + } +} + +static void *pb_const_cast(const void *p) +{ + /* Note: this casts away const, in order to use the common field iterator + * logic for both encoding and decoding. The cast is done using union + * to avoid spurious compiler warnings. */ + union { + void *p1; + const void *p2; + } t; + t.p2 = p; + return t.p1; +} + +bool pb_field_iter_begin_const(pb_field_iter_t *iter, const pb_msgdesc_t *desc, const void *message) +{ + return pb_field_iter_begin(iter, desc, pb_const_cast(message)); +} + +bool pb_field_iter_begin_extension_const(pb_field_iter_t *iter, const pb_extension_t *extension) +{ + return pb_field_iter_begin_extension(iter, (pb_extension_t*)pb_const_cast(extension)); +} + +bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field) +{ + if (field->data_size == sizeof(pb_callback_t)) + { + pb_callback_t *pCallback = (pb_callback_t*)field->pData; + + if (pCallback != NULL) + { + if (istream != NULL && pCallback->funcs.decode != NULL) + { + return pCallback->funcs.decode(istream, field, &pCallback->arg); + } + + if (ostream != NULL && pCallback->funcs.encode != NULL) + { + return pCallback->funcs.encode(ostream, field, &pCallback->arg); + } + } + } + + return true; /* Success, but didn't do anything */ + +} + +#ifdef PB_VALIDATE_UTF8 + +/* This function checks whether a string is valid UTF-8 text. + * + * Algorithm is adapted from https://www.cl.cam.ac.uk/~mgk25/ucs/utf8_check.c + * Original copyright: Markus Kuhn 2005-03-30 + * Licensed under "Short code license", which allows use under MIT license or + * any compatible with it. + */ + +bool pb_validate_utf8(const char *str) +{ + const pb_byte_t *s = (const pb_byte_t*)str; + while (*s) + { + if (*s < 0x80) + { + /* 0xxxxxxx */ + s++; + } + else if ((s[0] & 0xe0) == 0xc0) + { + /* 110XXXXx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[0] & 0xfe) == 0xc0) /* overlong? */ + return false; + else + s += 2; + } + else if ((s[0] & 0xf0) == 0xe0) + { + /* 1110XXXX 10Xxxxxx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[2] & 0xc0) != 0x80 || + (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || /* overlong? */ + (s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || /* surrogate? */ + (s[0] == 0xef && s[1] == 0xbf && + (s[2] & 0xfe) == 0xbe)) /* U+FFFE or U+FFFF? */ + return false; + else + s += 3; + } + else if ((s[0] & 0xf8) == 0xf0) + { + /* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[2] & 0xc0) != 0x80 || + (s[3] & 0xc0) != 0x80 || + (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || /* overlong? */ + (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) /* > U+10FFFF? */ + return false; + else + s += 4; + } + else + { + return false; + } + } + + return true; +} + +#endif + diff --git a/src/network/pb_common.h b/src/network/pb_common.h new file mode 100644 index 000000000..58aa90f76 --- /dev/null +++ b/src/network/pb_common.h @@ -0,0 +1,49 @@ +/* pb_common.h: Common support functions for pb_encode.c and pb_decode.c. + * These functions are rarely needed by applications directly. + */ + +#ifndef PB_COMMON_H_INCLUDED +#define PB_COMMON_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initialize the field iterator structure to beginning. + * Returns false if the message type is empty. */ +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, void *message); + +/* Get a field iterator for extension field. */ +bool pb_field_iter_begin_extension(pb_field_iter_t *iter, pb_extension_t *extension); + +/* Same as pb_field_iter_begin(), but for const message pointer. + * Note that the pointers in pb_field_iter_t will be non-const but shouldn't + * be written to when using these functions. */ +bool pb_field_iter_begin_const(pb_field_iter_t *iter, const pb_msgdesc_t *desc, const void *message); +bool pb_field_iter_begin_extension_const(pb_field_iter_t *iter, const pb_extension_t *extension); + +/* Advance the iterator to the next field. + * Returns false when the iterator wraps back to the first field. */ +bool pb_field_iter_next(pb_field_iter_t *iter); + +/* Advance the iterator until it points at a field with the given tag. + * Returns false if no such field exists. */ +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag); + +/* Find a field with type PB_LTYPE_EXTENSION, or return false if not found. + * There can be only one extension range field per message. */ +bool pb_field_iter_find_extension(pb_field_iter_t *iter); + +#ifdef PB_VALIDATE_UTF8 +/* Validate UTF-8 text string */ +bool pb_validate_utf8(const char *s); +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + diff --git a/src/network/pb_decode.c b/src/network/pb_decode.c new file mode 100644 index 000000000..788998eb9 --- /dev/null +++ b/src/network/pb_decode.c @@ -0,0 +1,1727 @@ +/* pb_decode.c -- decode a protobuf using minimal resources + * + * 2011 Petteri Aimonen + */ + +/* Use the GCC warn_unused_result attribute to check that all return values + * are propagated correctly. On other compilers and gcc before 3.4.0 just + * ignore the annotation. + */ +#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) + #define checkreturn +#else + #define checkreturn __attribute__((warn_unused_result)) +#endif + +#include "pb.h" +#include "pb_decode.h" +#include "pb_common.h" + +/************************************** + * Declarations internal to this file * + **************************************/ + +static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); +static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof); +static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size); +static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); +static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); +static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); +static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); +static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); +static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type); +static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_extension_t *extension); +static bool pb_field_set_to_default(pb_field_iter_t *field); +static bool pb_message_set_to_defaults(pb_field_iter_t *iter); +static bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_skip_varint(pb_istream_t *stream); +static bool checkreturn pb_skip_string(pb_istream_t *stream); + +#ifdef PB_ENABLE_MALLOC +static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size); +static void initialize_pointer_field(void *pItem, pb_field_iter_t *field); +static bool checkreturn pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *field); +static void pb_release_single_field(pb_field_iter_t *field); +#endif + +#ifdef PB_WITHOUT_64BIT +#define pb_int64_t int32_t +#define pb_uint64_t uint32_t +#else +#define pb_int64_t int64_t +#define pb_uint64_t uint64_t +#endif + +typedef struct { + uint32_t bitfield[(PB_MAX_REQUIRED_FIELDS + 31) / 32]; +} pb_fields_seen_t; + +/******************************* + * pb_istream_t implementation * + *******************************/ + +static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) +{ + const pb_byte_t *source = (const pb_byte_t*)stream->state; + stream->state = (pb_byte_t*)stream->state + count; + + if (buf != NULL) + { + memcpy(buf, source, count * sizeof(pb_byte_t)); + } + + return true; +} + +bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) +{ + if (count == 0) + return true; + +#ifndef PB_BUFFER_ONLY + if (buf == NULL && stream->callback != buf_read) + { + /* Skip input bytes */ + pb_byte_t tmp[16]; + while (count > 16) + { + if (!pb_read(stream, tmp, 16)) + return false; + + count -= 16; + } + + return pb_read(stream, tmp, count); + } +#endif + + if (stream->bytes_left < count) + PB_RETURN_ERROR(stream, "end-of-stream"); + +#ifndef PB_BUFFER_ONLY + if (!stream->callback(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#else + if (!buf_read(stream, buf, count)) + return false; +#endif + + if (stream->bytes_left < count) + stream->bytes_left = 0; + else + stream->bytes_left -= count; + + return true; +} + +/* Read a single byte from input stream. buf may not be NULL. + * This is an optimization for the varint decoding. */ +static bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf) +{ + if (stream->bytes_left == 0) + PB_RETURN_ERROR(stream, "end-of-stream"); + +#ifndef PB_BUFFER_ONLY + if (!stream->callback(stream, buf, 1)) + PB_RETURN_ERROR(stream, "io error"); +#else + *buf = *(const pb_byte_t*)stream->state; + stream->state = (pb_byte_t*)stream->state + 1; +#endif + + stream->bytes_left--; + + return true; +} + +pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen) +{ + pb_istream_t stream; + /* Cast away the const from buf without a compiler error. We are + * careful to use it only in a const manner in the callbacks. + */ + union { + void *state; + const void *c_state; + } state; +#ifdef PB_BUFFER_ONLY + stream.callback = NULL; +#else + stream.callback = &buf_read; +#endif + state.c_state = buf; + stream.state = state.state; + stream.bytes_left = msglen; +#ifndef PB_NO_ERRMSG + stream.errmsg = NULL; +#endif + return stream; +} + +/******************** + * Helper functions * + ********************/ + +static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof) +{ + pb_byte_t byte; + uint32_t result; + + if (!pb_readbyte(stream, &byte)) + { + if (stream->bytes_left == 0) + { + if (eof) + { + *eof = true; + } + } + + return false; + } + + if ((byte & 0x80) == 0) + { + /* Quick case, 1 byte value */ + result = byte; + } + else + { + /* Multibyte case */ + uint_fast8_t bitpos = 7; + result = byte & 0x7F; + + do + { + if (!pb_readbyte(stream, &byte)) + return false; + + if (bitpos >= 32) + { + /* Note: The varint could have trailing 0x80 bytes, or 0xFF for negative. */ + pb_byte_t sign_extension = (bitpos < 63) ? 0xFF : 0x01; + bool valid_extension = ((byte & 0x7F) == 0x00 || + ((result >> 31) != 0 && byte == sign_extension)); + + if (bitpos >= 64 || !valid_extension) + { + PB_RETURN_ERROR(stream, "varint overflow"); + } + } + else if (bitpos == 28) + { + if ((byte & 0x70) != 0 && (byte & 0x78) != 0x78) + { + PB_RETURN_ERROR(stream, "varint overflow"); + } + result |= (uint32_t)(byte & 0x0F) << bitpos; + } + else + { + result |= (uint32_t)(byte & 0x7F) << bitpos; + } + bitpos = (uint_fast8_t)(bitpos + 7); + } while (byte & 0x80); + } + + *dest = result; + return true; +} + +bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) +{ + return pb_decode_varint32_eof(stream, dest, NULL); +} + +#ifndef PB_WITHOUT_64BIT +bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) +{ + pb_byte_t byte; + uint_fast8_t bitpos = 0; + uint64_t result = 0; + + do + { + if (!pb_readbyte(stream, &byte)) + return false; + + if (bitpos >= 63 && (byte & 0xFE) != 0) + PB_RETURN_ERROR(stream, "varint overflow"); + + result |= (uint64_t)(byte & 0x7F) << bitpos; + bitpos = (uint_fast8_t)(bitpos + 7); + } while (byte & 0x80); + + *dest = result; + return true; +} +#endif + +bool checkreturn pb_skip_varint(pb_istream_t *stream) +{ + pb_byte_t byte; + do + { + if (!pb_read(stream, &byte, 1)) + return false; + } while (byte & 0x80); + return true; +} + +bool checkreturn pb_skip_string(pb_istream_t *stream) +{ + uint32_t length; + if (!pb_decode_varint32(stream, &length)) + return false; + + if ((size_t)length != length) + { + PB_RETURN_ERROR(stream, "size too large"); + } + + return pb_read(stream, NULL, (size_t)length); +} + +bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof) +{ + uint32_t temp; + *eof = false; + *wire_type = (pb_wire_type_t) 0; + *tag = 0; + + if (!pb_decode_varint32_eof(stream, &temp, eof)) + { + return false; + } + + *tag = temp >> 3; + *wire_type = (pb_wire_type_t)(temp & 7); + return true; +} + +bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type) +{ + switch (wire_type) + { + case PB_WT_VARINT: return pb_skip_varint(stream); + case PB_WT_64BIT: return pb_read(stream, NULL, 8); + case PB_WT_STRING: return pb_skip_string(stream); + case PB_WT_32BIT: return pb_read(stream, NULL, 4); + default: PB_RETURN_ERROR(stream, "invalid wire_type"); + } +} + +/* Read a raw value to buffer, for the purpose of passing it to callback as + * a substream. Size is maximum size on call, and actual size on return. + */ +static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size) +{ + size_t max_size = *size; + switch (wire_type) + { + case PB_WT_VARINT: + *size = 0; + do + { + (*size)++; + if (*size > max_size) + PB_RETURN_ERROR(stream, "varint overflow"); + + if (!pb_read(stream, buf, 1)) + return false; + } while (*buf++ & 0x80); + return true; + + case PB_WT_64BIT: + *size = 8; + return pb_read(stream, buf, 8); + + case PB_WT_32BIT: + *size = 4; + return pb_read(stream, buf, 4); + + case PB_WT_STRING: + /* Calling read_raw_value with a PB_WT_STRING is an error. + * Explicitly handle this case and fallthrough to default to avoid + * compiler warnings. + */ + + default: PB_RETURN_ERROR(stream, "invalid wire_type"); + } +} + +/* Decode string length from stream and return a substream with limited length. + * Remember to close the substream using pb_close_string_substream(). + */ +bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream) +{ + uint32_t size; + if (!pb_decode_varint32(stream, &size)) + return false; + + *substream = *stream; + if (substream->bytes_left < size) + PB_RETURN_ERROR(stream, "parent stream too short"); + + substream->bytes_left = (size_t)size; + stream->bytes_left -= (size_t)size; + return true; +} + +bool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream) +{ + if (substream->bytes_left) { + if (!pb_read(substream, NULL, substream->bytes_left)) + return false; + } + + stream->state = substream->state; + +#ifndef PB_NO_ERRMSG + stream->errmsg = substream->errmsg; +#endif + return true; +} + +/************************* + * Decode a single field * + *************************/ + +static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +{ + switch (PB_LTYPE(field->type)) + { + case PB_LTYPE_BOOL: + if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_dec_bool(stream, field); + + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_dec_varint(stream, field); + + case PB_LTYPE_FIXED32: + if (wire_type != PB_WT_32BIT && wire_type != PB_WT_PACKED) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_decode_fixed32(stream, field->pData); + + case PB_LTYPE_FIXED64: + if (wire_type != PB_WT_64BIT && wire_type != PB_WT_PACKED) + PB_RETURN_ERROR(stream, "wrong wire type"); + +#ifdef PB_CONVERT_DOUBLE_FLOAT + if (field->data_size == sizeof(float)) + { + return pb_decode_double_as_float(stream, (float*)field->pData); + } +#endif + +#ifdef PB_WITHOUT_64BIT + PB_RETURN_ERROR(stream, "invalid data_size"); +#else + return pb_decode_fixed64(stream, field->pData); +#endif + + case PB_LTYPE_BYTES: + if (wire_type != PB_WT_STRING) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_dec_bytes(stream, field); + + case PB_LTYPE_STRING: + if (wire_type != PB_WT_STRING) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_dec_string(stream, field); + + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_SUBMSG_W_CB: + if (wire_type != PB_WT_STRING) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_dec_submessage(stream, field); + + case PB_LTYPE_FIXED_LENGTH_BYTES: + if (wire_type != PB_WT_STRING) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_dec_fixed_length_bytes(stream, field); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +{ + switch (PB_HTYPE(field->type)) + { + case PB_HTYPE_REQUIRED: + return decode_basic_field(stream, wire_type, field); + + case PB_HTYPE_OPTIONAL: + if (field->pSize != NULL) + *(bool*)field->pSize = true; + return decode_basic_field(stream, wire_type, field); + + case PB_HTYPE_REPEATED: + if (wire_type == PB_WT_STRING + && PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) + { + /* Packed array */ + bool status = true; + pb_istream_t substream; + pb_size_t *size = (pb_size_t*)field->pSize; + field->pData = (char*)field->pField + field->data_size * (*size); + + if (!pb_make_string_substream(stream, &substream)) + return false; + + while (substream.bytes_left > 0 && *size < field->array_size) + { + if (!decode_basic_field(&substream, PB_WT_PACKED, field)) + { + status = false; + break; + } + (*size)++; + field->pData = (char*)field->pData + field->data_size; + } + + if (substream.bytes_left != 0) + PB_RETURN_ERROR(stream, "array overflow"); + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; + } + else + { + /* Repeated field */ + pb_size_t *size = (pb_size_t*)field->pSize; + field->pData = (char*)field->pField + field->data_size * (*size); + + if ((*size)++ >= field->array_size) + PB_RETURN_ERROR(stream, "array overflow"); + + return decode_basic_field(stream, wire_type, field); + } + + case PB_HTYPE_ONEOF: + if (PB_LTYPE_IS_SUBMSG(field->type) && + *(pb_size_t*)field->pSize != field->tag) + { + /* We memset to zero so that any callbacks are set to NULL. + * This is because the callbacks might otherwise have values + * from some other union field. + * If callbacks are needed inside oneof field, use .proto + * option submsg_callback to have a separate callback function + * that can set the fields before submessage is decoded. + * pb_dec_submessage() will set any default values. */ + memset(field->pData, 0, (size_t)field->data_size); + + /* Set default values for the submessage fields. */ + if (field->submsg_desc->default_value != NULL || + field->submsg_desc->field_callback != NULL || + field->submsg_desc->submsg_info[0] != NULL) + { + pb_field_iter_t submsg_iter; + if (pb_field_iter_begin(&submsg_iter, field->submsg_desc, field->pData)) + { + if (!pb_message_set_to_defaults(&submsg_iter)) + PB_RETURN_ERROR(stream, "failed to set defaults"); + } + } + } + *(pb_size_t*)field->pSize = field->tag; + + return decode_basic_field(stream, wire_type, field); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +#ifdef PB_ENABLE_MALLOC +/* Allocate storage for the field and store the pointer at iter->pData. + * array_size is the number of entries to reserve in an array. + * Zero size is not allowed, use pb_free() for releasing. + */ +static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size) +{ + void *ptr = *(void**)pData; + + if (data_size == 0 || array_size == 0) + PB_RETURN_ERROR(stream, "invalid size"); + +#ifdef __AVR__ + /* Workaround for AVR libc bug 53284: http://savannah.nongnu.org/bugs/?53284 + * Realloc to size of 1 byte can cause corruption of the malloc structures. + */ + if (data_size == 1 && array_size == 1) + { + data_size = 2; + } +#endif + + /* Check for multiplication overflows. + * This code avoids the costly division if the sizes are small enough. + * Multiplication is safe as long as only half of bits are set + * in either multiplicand. + */ + { + const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4); + if (data_size >= check_limit || array_size >= check_limit) + { + const size_t size_max = (size_t)-1; + if (size_max / array_size < data_size) + { + PB_RETURN_ERROR(stream, "size too large"); + } + } + } + + /* Allocate new or expand previous allocation */ + /* Note: on failure the old pointer will remain in the structure, + * the message must be freed by caller also on error return. */ + ptr = pb_realloc(ptr, array_size * data_size); + if (ptr == NULL) + PB_RETURN_ERROR(stream, "realloc failed"); + + *(void**)pData = ptr; + return true; +} + +/* Clear a newly allocated item in case it contains a pointer, or is a submessage. */ +static void initialize_pointer_field(void *pItem, pb_field_iter_t *field) +{ + if (PB_LTYPE(field->type) == PB_LTYPE_STRING || + PB_LTYPE(field->type) == PB_LTYPE_BYTES) + { + *(void**)pItem = NULL; + } + else if (PB_LTYPE_IS_SUBMSG(field->type)) + { + /* We memset to zero so that any callbacks are set to NULL. + * Default values will be set by pb_dec_submessage(). */ + memset(pItem, 0, field->data_size); + } +} +#endif + +static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +{ +#ifndef PB_ENABLE_MALLOC + PB_UNUSED(wire_type); + PB_UNUSED(field); + PB_RETURN_ERROR(stream, "no malloc support"); +#else + switch (PB_HTYPE(field->type)) + { + case PB_HTYPE_REQUIRED: + case PB_HTYPE_OPTIONAL: + case PB_HTYPE_ONEOF: + if (PB_LTYPE_IS_SUBMSG(field->type) && *(void**)field->pField != NULL) + { + /* Duplicate field, have to release the old allocation first. */ + /* FIXME: Does this work correctly for oneofs? */ + pb_release_single_field(field); + } + + if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) + { + *(pb_size_t*)field->pSize = field->tag; + } + + if (PB_LTYPE(field->type) == PB_LTYPE_STRING || + PB_LTYPE(field->type) == PB_LTYPE_BYTES) + { + /* pb_dec_string and pb_dec_bytes handle allocation themselves */ + field->pData = field->pField; + return decode_basic_field(stream, wire_type, field); + } + else + { + if (!allocate_field(stream, field->pField, field->data_size, 1)) + return false; + + field->pData = *(void**)field->pField; + initialize_pointer_field(field->pData, field); + return decode_basic_field(stream, wire_type, field); + } + + case PB_HTYPE_REPEATED: + if (wire_type == PB_WT_STRING + && PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) + { + /* Packed array, multiple items come in at once. */ + bool status = true; + pb_size_t *size = (pb_size_t*)field->pSize; + size_t allocated_size = *size; + pb_istream_t substream; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + while (substream.bytes_left) + { + if (*size == PB_SIZE_MAX) + { +#ifndef PB_NO_ERRMSG + stream->errmsg = "too many array entries"; +#endif + status = false; + break; + } + + if ((size_t)*size + 1 > allocated_size) + { + /* Allocate more storage. This tries to guess the + * number of remaining entries. Round the division + * upwards. */ + size_t remain = (substream.bytes_left - 1) / field->data_size + 1; + if (remain < PB_SIZE_MAX - allocated_size) + allocated_size += remain; + else + allocated_size += 1; + + if (!allocate_field(&substream, field->pField, field->data_size, allocated_size)) + { + status = false; + break; + } + } + + /* Decode the array entry */ + field->pData = *(char**)field->pField + field->data_size * (*size); + if (field->pData == NULL) + { + /* Shouldn't happen, but satisfies static analyzers */ + status = false; + break; + } + initialize_pointer_field(field->pData, field); + if (!decode_basic_field(&substream, PB_WT_PACKED, field)) + { + status = false; + break; + } + + (*size)++; + } + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; + } + else + { + /* Normal repeated field, i.e. only one item at a time. */ + pb_size_t *size = (pb_size_t*)field->pSize; + + if (*size == PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "too many array entries"); + + if (!allocate_field(stream, field->pField, field->data_size, (size_t)(*size + 1))) + return false; + + field->pData = *(char**)field->pField + field->data_size * (*size); + (*size)++; + initialize_pointer_field(field->pData, field); + return decode_basic_field(stream, wire_type, field); + } + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +#endif +} + +static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +{ + if (!field->descriptor->field_callback) + return pb_skip_field(stream, wire_type); + + if (wire_type == PB_WT_STRING) + { + pb_istream_t substream; + size_t prev_bytes_left; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + do + { + prev_bytes_left = substream.bytes_left; + if (!field->descriptor->field_callback(&substream, NULL, field)) + { + PB_SET_ERROR(stream, substream.errmsg ? substream.errmsg : "callback failed"); + return false; + } + } while (substream.bytes_left > 0 && substream.bytes_left < prev_bytes_left); + + if (!pb_close_string_substream(stream, &substream)) + return false; + + return true; + } + else + { + /* Copy the single scalar value to stack. + * This is required so that we can limit the stream length, + * which in turn allows to use same callback for packed and + * not-packed fields. */ + pb_istream_t substream; + pb_byte_t buffer[10]; + size_t size = sizeof(buffer); + + if (!read_raw_value(stream, wire_type, buffer, &size)) + return false; + substream = pb_istream_from_buffer(buffer, size); + + return field->descriptor->field_callback(&substream, NULL, field); + } +} + +static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +{ +#ifdef PB_ENABLE_MALLOC + /* When decoding an oneof field, check if there is old data that must be + * released first. */ + if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) + { + if (!pb_release_union_field(stream, field)) + return false; + } +#endif + + switch (PB_ATYPE(field->type)) + { + case PB_ATYPE_STATIC: + return decode_static_field(stream, wire_type, field); + + case PB_ATYPE_POINTER: + return decode_pointer_field(stream, wire_type, field); + + case PB_ATYPE_CALLBACK: + return decode_callback_field(stream, wire_type, field); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +/* Default handler for extension fields. Expects to have a pb_msgdesc_t + * pointer in the extension->type->arg field, pointing to a message with + * only one field in it. */ +static bool checkreturn default_extension_decoder(pb_istream_t *stream, + pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type) +{ + pb_field_iter_t iter; + + if (!pb_field_iter_begin_extension(&iter, extension)) + PB_RETURN_ERROR(stream, "invalid extension"); + + if (iter.tag != tag || !iter.message) + return true; + + extension->found = true; + return decode_field(stream, wire_type, &iter); +} + +/* Try to decode an unknown field as an extension field. Tries each extension + * decoder in turn, until one of them handles the field or loop ends. */ +static bool checkreturn decode_extension(pb_istream_t *stream, + uint32_t tag, pb_wire_type_t wire_type, pb_extension_t *extension) +{ + size_t pos = stream->bytes_left; + + while (extension != NULL && pos == stream->bytes_left) + { + bool status; + if (extension->type->decode) + status = extension->type->decode(stream, extension, tag, wire_type); + else + status = default_extension_decoder(stream, extension, tag, wire_type); + + if (!status) + return false; + + extension = extension->next; + } + + return true; +} + +/* Initialize message fields to default values, recursively */ +static bool pb_field_set_to_default(pb_field_iter_t *field) +{ + pb_type_t type; + type = field->type; + + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) + { + pb_extension_t *ext = *(pb_extension_t* const *)field->pData; + while (ext != NULL) + { + pb_field_iter_t ext_iter; + if (pb_field_iter_begin_extension(&ext_iter, ext)) + { + ext->found = false; + if (!pb_message_set_to_defaults(&ext_iter)) + return false; + } + ext = ext->next; + } + } + else if (PB_ATYPE(type) == PB_ATYPE_STATIC) + { + bool init_data = true; + if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->pSize != NULL) + { + /* Set has_field to false. Still initialize the optional field + * itself also. */ + *(bool*)field->pSize = false; + } + else if (PB_HTYPE(type) == PB_HTYPE_REPEATED || + PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + /* REPEATED: Set array count to 0, no need to initialize contents. + ONEOF: Set which_field to 0. */ + *(pb_size_t*)field->pSize = 0; + init_data = false; + } + + if (init_data) + { + if (PB_LTYPE_IS_SUBMSG(field->type) && + (field->submsg_desc->default_value != NULL || + field->submsg_desc->field_callback != NULL || + field->submsg_desc->submsg_info[0] != NULL)) + { + /* Initialize submessage to defaults. + * Only needed if it has default values + * or callback/submessage fields. */ + pb_field_iter_t submsg_iter; + if (pb_field_iter_begin(&submsg_iter, field->submsg_desc, field->pData)) + { + if (!pb_message_set_to_defaults(&submsg_iter)) + return false; + } + } + else + { + /* Initialize to zeros */ + memset(field->pData, 0, (size_t)field->data_size); + } + } + } + else if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + /* Initialize the pointer to NULL. */ + *(void**)field->pField = NULL; + + /* Initialize array count to 0. */ + if (PB_HTYPE(type) == PB_HTYPE_REPEATED || + PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + *(pb_size_t*)field->pSize = 0; + } + } + else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) + { + /* Don't overwrite callback */ + } + + return true; +} + +static bool pb_message_set_to_defaults(pb_field_iter_t *iter) +{ + pb_istream_t defstream = PB_ISTREAM_EMPTY; + uint32_t tag = 0; + pb_wire_type_t wire_type = PB_WT_VARINT; + bool eof; + + if (iter->descriptor->default_value) + { + defstream = pb_istream_from_buffer(iter->descriptor->default_value, (size_t)-1); + if (!pb_decode_tag(&defstream, &wire_type, &tag, &eof)) + return false; + } + + do + { + if (!pb_field_set_to_default(iter)) + return false; + + if (tag != 0 && iter->tag == tag) + { + /* We have a default value for this field in the defstream */ + if (!decode_field(&defstream, wire_type, iter)) + return false; + if (!pb_decode_tag(&defstream, &wire_type, &tag, &eof)) + return false; + + if (iter->pSize) + *(bool*)iter->pSize = false; + } + } while (pb_field_iter_next(iter)); + + return true; +} + +/********************* + * Decode all fields * + *********************/ + +static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags) +{ + uint32_t extension_range_start = 0; + pb_extension_t *extensions = NULL; + + /* 'fixed_count_field' and 'fixed_count_size' track position of a repeated fixed + * count field. This can only handle _one_ repeated fixed count field that + * is unpacked and unordered among other (non repeated fixed count) fields. + */ + pb_size_t fixed_count_field = PB_SIZE_MAX; + pb_size_t fixed_count_size = 0; + pb_size_t fixed_count_total_size = 0; + + pb_fields_seen_t fields_seen = {{0, 0}}; + const uint32_t allbits = ~(uint32_t)0; + pb_field_iter_t iter; + + if (pb_field_iter_begin(&iter, fields, dest_struct)) + { + if ((flags & PB_DECODE_NOINIT) == 0) + { + if (!pb_message_set_to_defaults(&iter)) + PB_RETURN_ERROR(stream, "failed to set defaults"); + } + } + + while (stream->bytes_left) + { + uint32_t tag; + pb_wire_type_t wire_type; + bool eof; + + if (!pb_decode_tag(stream, &wire_type, &tag, &eof)) + { + if (eof) + break; + else + return false; + } + + if (tag == 0) + { + if (flags & PB_DECODE_NULLTERMINATED) + { + break; + } + else + { + PB_RETURN_ERROR(stream, "zero tag"); + } + } + + if (!pb_field_iter_find(&iter, tag) || PB_LTYPE(iter.type) == PB_LTYPE_EXTENSION) + { + /* No match found, check if it matches an extension. */ + if (extension_range_start == 0) + { + if (pb_field_iter_find_extension(&iter)) + { + extensions = *(pb_extension_t* const *)iter.pData; + extension_range_start = iter.tag; + } + + if (!extensions) + { + extension_range_start = (uint32_t)-1; + } + } + + if (tag >= extension_range_start) + { + size_t pos = stream->bytes_left; + + if (!decode_extension(stream, tag, wire_type, extensions)) + return false; + + if (pos != stream->bytes_left) + { + /* The field was handled */ + continue; + } + } + + /* No match found, skip data */ + if (!pb_skip_field(stream, wire_type)) + return false; + continue; + } + + /* If a repeated fixed count field was found, get size from + * 'fixed_count_field' as there is no counter contained in the struct. + */ + if (PB_HTYPE(iter.type) == PB_HTYPE_REPEATED && iter.pSize == &iter.array_size) + { + if (fixed_count_field != iter.index) { + /* If the new fixed count field does not match the previous one, + * check that the previous one is NULL or that it finished + * receiving all the expected data. + */ + if (fixed_count_field != PB_SIZE_MAX && + fixed_count_size != fixed_count_total_size) + { + PB_RETURN_ERROR(stream, "wrong size for fixed count field"); + } + + fixed_count_field = iter.index; + fixed_count_size = 0; + fixed_count_total_size = iter.array_size; + } + + iter.pSize = &fixed_count_size; + } + + if (PB_HTYPE(iter.type) == PB_HTYPE_REQUIRED + && iter.required_field_index < PB_MAX_REQUIRED_FIELDS) + { + uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31)); + fields_seen.bitfield[iter.required_field_index >> 5] |= tmp; + } + + if (!decode_field(stream, wire_type, &iter)) + return false; + } + + /* Check that all elements of the last decoded fixed count field were present. */ + if (fixed_count_field != PB_SIZE_MAX && + fixed_count_size != fixed_count_total_size) + { + PB_RETURN_ERROR(stream, "wrong size for fixed count field"); + } + + /* Check that all required fields were present. */ + { + pb_size_t req_field_count = iter.descriptor->required_field_count; + + if (req_field_count > 0) + { + pb_size_t i; + + if (req_field_count > PB_MAX_REQUIRED_FIELDS) + req_field_count = PB_MAX_REQUIRED_FIELDS; + + /* Check the whole words */ + for (i = 0; i < (req_field_count >> 5); i++) + { + if (fields_seen.bitfield[i] != allbits) + PB_RETURN_ERROR(stream, "missing required field"); + } + + /* Check the remaining bits (if any) */ + if ((req_field_count & 31) != 0) + { + if (fields_seen.bitfield[req_field_count >> 5] != + (allbits >> (uint_least8_t)(32 - (req_field_count & 31)))) + { + PB_RETURN_ERROR(stream, "missing required field"); + } + } + } + } + + return true; +} + +bool checkreturn pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags) +{ + bool status; + + if ((flags & PB_DECODE_DELIMITED) == 0) + { + status = pb_decode_inner(stream, fields, dest_struct, flags); + } + else + { + pb_istream_t substream; + if (!pb_make_string_substream(stream, &substream)) + return false; + + status = pb_decode_inner(&substream, fields, dest_struct, flags); + + if (!pb_close_string_substream(stream, &substream)) + return false; + } + +#ifdef PB_ENABLE_MALLOC + if (!status) + pb_release(fields, dest_struct); +#endif + + return status; +} + +bool checkreturn pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct) +{ + bool status; + + status = pb_decode_inner(stream, fields, dest_struct, 0); + +#ifdef PB_ENABLE_MALLOC + if (!status) + pb_release(fields, dest_struct); +#endif + + return status; +} + +#ifdef PB_ENABLE_MALLOC +/* Given an oneof field, if there has already been a field inside this oneof, + * release it before overwriting with a different one. */ +static bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *field) +{ + pb_field_iter_t old_field = *field; + pb_size_t old_tag = *(pb_size_t*)field->pSize; /* Previous which_ value */ + pb_size_t new_tag = field->tag; /* New which_ value */ + + if (old_tag == 0) + return true; /* Ok, no old data in union */ + + if (old_tag == new_tag) + return true; /* Ok, old data is of same type => merge */ + + /* Release old data. The find can fail if the message struct contains + * invalid data. */ + if (!pb_field_iter_find(&old_field, old_tag)) + PB_RETURN_ERROR(stream, "invalid union tag"); + + pb_release_single_field(&old_field); + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { + /* Initialize the pointer to NULL to make sure it is valid + * even in case of error return. */ + *(void**)field->pField = NULL; + field->pData = NULL; + } + + return true; +} + +static void pb_release_single_field(pb_field_iter_t *field) +{ + pb_type_t type; + type = field->type; + + if (PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + if (*(pb_size_t*)field->pSize != field->tag) + return; /* This is not the current field in the union */ + } + + /* Release anything contained inside an extension or submsg. + * This has to be done even if the submsg itself is statically + * allocated. */ + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) + { + /* Release fields from all extensions in the linked list */ + pb_extension_t *ext = *(pb_extension_t**)field->pData; + while (ext != NULL) + { + pb_field_iter_t ext_iter; + if (pb_field_iter_begin_extension(&ext_iter, ext)) + { + pb_release_single_field(&ext_iter); + } + ext = ext->next; + } + } + else if (PB_LTYPE_IS_SUBMSG(type) && PB_ATYPE(type) != PB_ATYPE_CALLBACK) + { + /* Release fields in submessage or submsg array */ + pb_size_t count = 1; + + if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + field->pData = *(void**)field->pField; + } + else + { + field->pData = field->pField; + } + + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + { + count = *(pb_size_t*)field->pSize; + + if (PB_ATYPE(type) == PB_ATYPE_STATIC && count > field->array_size) + { + /* Protect against corrupted _count fields */ + count = field->array_size; + } + } + + if (field->pData) + { + for (; count > 0; count--) + { + pb_release(field->submsg_desc, field->pData); + field->pData = (char*)field->pData + field->data_size; + } + } + } + + if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + if (PB_HTYPE(type) == PB_HTYPE_REPEATED && + (PB_LTYPE(type) == PB_LTYPE_STRING || + PB_LTYPE(type) == PB_LTYPE_BYTES)) + { + /* Release entries in repeated string or bytes array */ + void **pItem = *(void***)field->pField; + pb_size_t count = *(pb_size_t*)field->pSize; + for (; count > 0; count--) + { + pb_free(*pItem); + *pItem++ = NULL; + } + } + + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + { + /* We are going to release the array, so set the size to 0 */ + *(pb_size_t*)field->pSize = 0; + } + + /* Release main pointer */ + pb_free(*(void**)field->pField); + *(void**)field->pField = NULL; + } +} + +void pb_release(const pb_msgdesc_t *fields, void *dest_struct) +{ + pb_field_iter_t iter; + + if (!dest_struct) + return; /* Ignore NULL pointers, similar to free() */ + + if (!pb_field_iter_begin(&iter, fields, dest_struct)) + return; /* Empty message type */ + + do + { + pb_release_single_field(&iter); + } while (pb_field_iter_next(&iter)); +} +#else +void pb_release(const pb_msgdesc_t *fields, void *dest_struct) +{ + /* Nothing to release without PB_ENABLE_MALLOC. */ + PB_UNUSED(fields); + PB_UNUSED(dest_struct); +} +#endif + +/* Field decoders */ + +bool pb_decode_bool(pb_istream_t *stream, bool *dest) +{ + uint32_t value; + if (!pb_decode_varint32(stream, &value)) + return false; + + *(bool*)dest = (value != 0); + return true; +} + +bool pb_decode_svarint(pb_istream_t *stream, pb_int64_t *dest) +{ + pb_uint64_t value; + if (!pb_decode_varint(stream, &value)) + return false; + + if (value & 1) + *dest = (pb_int64_t)(~(value >> 1)); + else + *dest = (pb_int64_t)(value >> 1); + + return true; +} + +bool pb_decode_fixed32(pb_istream_t *stream, void *dest) +{ + union { + uint32_t fixed32; + pb_byte_t bytes[4]; + } u; + + if (!pb_read(stream, u.bytes, 4)) + return false; + +#if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 + /* fast path - if we know that we're on little endian, assign directly */ + *(uint32_t*)dest = u.fixed32; +#else + *(uint32_t*)dest = ((uint32_t)u.bytes[0] << 0) | + ((uint32_t)u.bytes[1] << 8) | + ((uint32_t)u.bytes[2] << 16) | + ((uint32_t)u.bytes[3] << 24); +#endif + return true; +} + +#ifndef PB_WITHOUT_64BIT +bool pb_decode_fixed64(pb_istream_t *stream, void *dest) +{ + union { + uint64_t fixed64; + pb_byte_t bytes[8]; + } u; + + if (!pb_read(stream, u.bytes, 8)) + return false; + +#if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 + /* fast path - if we know that we're on little endian, assign directly */ + *(uint64_t*)dest = u.fixed64; +#else + *(uint64_t*)dest = ((uint64_t)u.bytes[0] << 0) | + ((uint64_t)u.bytes[1] << 8) | + ((uint64_t)u.bytes[2] << 16) | + ((uint64_t)u.bytes[3] << 24) | + ((uint64_t)u.bytes[4] << 32) | + ((uint64_t)u.bytes[5] << 40) | + ((uint64_t)u.bytes[6] << 48) | + ((uint64_t)u.bytes[7] << 56); +#endif + return true; +} +#endif + +static bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_iter_t *field) +{ + return pb_decode_bool(stream, (bool*)field->pData); +} + +static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_iter_t *field) +{ + if (PB_LTYPE(field->type) == PB_LTYPE_UVARINT) + { + pb_uint64_t value, clamped; + if (!pb_decode_varint(stream, &value)) + return false; + + /* Cast to the proper field size, while checking for overflows */ + if (field->data_size == sizeof(pb_uint64_t)) + clamped = *(pb_uint64_t*)field->pData = value; + else if (field->data_size == sizeof(uint32_t)) + clamped = *(uint32_t*)field->pData = (uint32_t)value; + else if (field->data_size == sizeof(uint_least16_t)) + clamped = *(uint_least16_t*)field->pData = (uint_least16_t)value; + else if (field->data_size == sizeof(uint_least8_t)) + clamped = *(uint_least8_t*)field->pData = (uint_least8_t)value; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (clamped != value) + PB_RETURN_ERROR(stream, "integer too large"); + + return true; + } + else + { + pb_uint64_t value; + pb_int64_t svalue; + pb_int64_t clamped; + + if (PB_LTYPE(field->type) == PB_LTYPE_SVARINT) + { + if (!pb_decode_svarint(stream, &svalue)) + return false; + } + else + { + if (!pb_decode_varint(stream, &value)) + return false; + + /* See issue 97: Google's C++ protobuf allows negative varint values to + * be cast as int32_t, instead of the int64_t that should be used when + * encoding. Nanopb versions before 0.2.5 had a bug in encoding. In order to + * not break decoding of such messages, we cast <=32 bit fields to + * int32_t first to get the sign correct. + */ + if (field->data_size == sizeof(pb_int64_t)) + svalue = (pb_int64_t)value; + else + svalue = (int32_t)value; + } + + /* Cast to the proper field size, while checking for overflows */ + if (field->data_size == sizeof(pb_int64_t)) + clamped = *(pb_int64_t*)field->pData = svalue; + else if (field->data_size == sizeof(int32_t)) + clamped = *(int32_t*)field->pData = (int32_t)svalue; + else if (field->data_size == sizeof(int_least16_t)) + clamped = *(int_least16_t*)field->pData = (int_least16_t)svalue; + else if (field->data_size == sizeof(int_least8_t)) + clamped = *(int_least8_t*)field->pData = (int_least8_t)svalue; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (clamped != svalue) + PB_RETURN_ERROR(stream, "integer too large"); + + return true; + } +} + +static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_iter_t *field) +{ + uint32_t size; + size_t alloc_size; + pb_bytes_array_t *dest; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size); + if (size > alloc_size) + PB_RETURN_ERROR(stream, "size too large"); + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { +#ifndef PB_ENABLE_MALLOC + PB_RETURN_ERROR(stream, "no malloc support"); +#else + if (stream->bytes_left < size) + PB_RETURN_ERROR(stream, "end-of-stream"); + + if (!allocate_field(stream, field->pData, alloc_size, 1)) + return false; + dest = *(pb_bytes_array_t**)field->pData; +#endif + } + else + { + if (alloc_size > field->data_size) + PB_RETURN_ERROR(stream, "bytes overflow"); + dest = (pb_bytes_array_t*)field->pData; + } + + dest->size = (pb_size_t)size; + return pb_read(stream, dest->bytes, (size_t)size); +} + +static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_iter_t *field) +{ + uint32_t size; + size_t alloc_size; + pb_byte_t *dest = (pb_byte_t*)field->pData; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size == (uint32_t)-1) + PB_RETURN_ERROR(stream, "size too large"); + + /* Space for null terminator */ + alloc_size = (size_t)(size + 1); + + if (alloc_size < size) + PB_RETURN_ERROR(stream, "size too large"); + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { +#ifndef PB_ENABLE_MALLOC + PB_RETURN_ERROR(stream, "no malloc support"); +#else + if (stream->bytes_left < size) + PB_RETURN_ERROR(stream, "end-of-stream"); + + if (!allocate_field(stream, field->pData, alloc_size, 1)) + return false; + dest = *(pb_byte_t**)field->pData; +#endif + } + else + { + if (alloc_size > field->data_size) + PB_RETURN_ERROR(stream, "string overflow"); + } + + dest[size] = 0; + + if (!pb_read(stream, dest, (size_t)size)) + return false; + +#ifdef PB_VALIDATE_UTF8 + if (!pb_validate_utf8((const char*)dest)) + PB_RETURN_ERROR(stream, "invalid utf8"); +#endif + + return true; +} + +static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_iter_t *field) +{ + bool status = true; + bool submsg_consumed = false; + pb_istream_t substream; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + if (field->submsg_desc == NULL) + PB_RETURN_ERROR(stream, "invalid field descriptor"); + + /* Submessages can have a separate message-level callback that is called + * before decoding the message. Typically it is used to set callback fields + * inside oneofs. */ + if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL) + { + /* Message callback is stored right before pSize. */ + pb_callback_t *callback = (pb_callback_t*)field->pSize - 1; + if (callback->funcs.decode) + { + status = callback->funcs.decode(&substream, field, &callback->arg); + + if (substream.bytes_left == 0) + { + submsg_consumed = true; + } + } + } + + /* Now decode the submessage contents */ + if (status && !submsg_consumed) + { + unsigned int flags = 0; + + /* Static required/optional fields are already initialized by top-level + * pb_decode(), no need to initialize them again. */ + if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && + PB_HTYPE(field->type) != PB_HTYPE_REPEATED) + { + flags = PB_DECODE_NOINIT; + } + + status = pb_decode_inner(&substream, field->submsg_desc, field->pData, flags); + } + + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; +} + +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_iter_t *field) +{ + uint32_t size; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + if (size == 0) + { + /* As a special case, treat empty bytes string as all zeros for fixed_length_bytes. */ + memset(field->pData, 0, (size_t)field->data_size); + return true; + } + + if (size != field->data_size) + PB_RETURN_ERROR(stream, "incorrect fixed length bytes size"); + + return pb_read(stream, (pb_byte_t*)field->pData, (size_t)field->data_size); +} + +#ifdef PB_CONVERT_DOUBLE_FLOAT +bool pb_decode_double_as_float(pb_istream_t *stream, float *dest) +{ + uint_least8_t sign; + int exponent; + uint32_t mantissa; + uint64_t value; + union { float f; uint32_t i; } out; + + if (!pb_decode_fixed64(stream, &value)) + return false; + + /* Decompose input value */ + sign = (uint_least8_t)((value >> 63) & 1); + exponent = (int)((value >> 52) & 0x7FF) - 1023; + mantissa = (value >> 28) & 0xFFFFFF; /* Highest 24 bits */ + + /* Figure if value is in range representable by floats. */ + if (exponent == 1024) + { + /* Special value */ + exponent = 128; + mantissa >>= 1; + } + else + { + if (exponent > 127) + { + /* Too large, convert to infinity */ + exponent = 128; + mantissa = 0; + } + else if (exponent < -150) + { + /* Too small, convert to zero */ + exponent = -127; + mantissa = 0; + } + else if (exponent < -126) + { + /* Denormalized */ + mantissa |= 0x1000000; + mantissa >>= (-126 - exponent); + exponent = -127; + } + + /* Round off mantissa */ + mantissa = (mantissa + 1) >> 1; + + /* Check if mantissa went over 2.0 */ + if (mantissa & 0x800000) + { + exponent += 1; + mantissa &= 0x7FFFFF; + mantissa >>= 1; + } + } + + /* Combine fields */ + out.i = mantissa; + out.i |= (uint32_t)(exponent + 127) << 23; + out.i |= (uint32_t)sign << 31; + + *dest = out.f; + return true; +} +#endif diff --git a/src/network/pb_decode.h b/src/network/pb_decode.h new file mode 100644 index 000000000..ae1d3ccf2 --- /dev/null +++ b/src/network/pb_decode.h @@ -0,0 +1,193 @@ +/* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c. + * The main function is pb_decode. You also need an input stream, and the + * field descriptions created by nanopb_generator.py. + */ + +#ifndef PB_DECODE_H_INCLUDED +#define PB_DECODE_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure for defining custom input streams. You will need to provide + * a callback function to read the bytes from your storage, which can be + * for example a file or a network socket. + * + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause decoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer), + * and rely on pb_read to verify that no-body reads past bytes_left. + * 3) Your callback may be used with substreams, in which case bytes_left + * is different than from the main stream. Don't use bytes_left to compute + * any pointers. + */ +struct pb_istream_s +{ +#ifdef PB_BUFFER_ONLY + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + */ + int *callback; +#else + bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count); +#endif + + void *state; /* Free field for use by callback implementation */ + size_t bytes_left; + +#ifndef PB_NO_ERRMSG + const char *errmsg; +#endif +}; + +#ifndef PB_NO_ERRMSG +#define PB_ISTREAM_EMPTY {0,0,0,0} +#else +#define PB_ISTREAM_EMPTY {0,0,0} +#endif + +/*************************** + * Main decoding functions * + ***************************/ + +/* Decode a single protocol buffers message from input stream into a C structure. + * Returns true on success, false on any failure. + * The actual struct pointed to by dest must match the description in fields. + * Callback fields of the destination structure must be initialized by caller. + * All other fields will be initialized by this function. + * + * Example usage: + * MyMessage msg = {}; + * uint8_t buffer[64]; + * pb_istream_t stream; + * + * // ... read some data into buffer ... + * + * stream = pb_istream_from_buffer(buffer, count); + * pb_decode(&stream, MyMessage_fields, &msg); + */ +bool pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct); + +/* Extended version of pb_decode, with several options to control + * the decoding process: + * + * PB_DECODE_NOINIT: Do not initialize the fields to default values. + * This is slightly faster if you do not need the default + * values and instead initialize the structure to 0 using + * e.g. memset(). This can also be used for merging two + * messages, i.e. combine already existing data with new + * values. + * + * PB_DECODE_DELIMITED: Input message starts with the message size as varint. + * Corresponds to parseDelimitedFrom() in Google's + * protobuf API. + * + * PB_DECODE_NULLTERMINATED: Stop reading when field tag is read as 0. This allows + * reading null terminated messages. + * NOTE: Until nanopb-0.4.0, pb_decode() also allows + * null-termination. This behaviour is not supported in + * most other protobuf implementations, so PB_DECODE_DELIMITED + * is a better option for compatibility. + * + * Multiple flags can be combined with bitwise or (| operator) + */ +#define PB_DECODE_NOINIT 0x01U +#define PB_DECODE_DELIMITED 0x02U +#define PB_DECODE_NULLTERMINATED 0x04U +bool pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags); + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define pb_decode_noinit(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_NOINIT) +#define pb_decode_delimited(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_DELIMITED) +#define pb_decode_delimited_noinit(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_DELIMITED | PB_DECODE_NOINIT) +#define pb_decode_nullterminated(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_NULLTERMINATED) + +/* Release any allocated pointer fields. If you use dynamic allocation, you should + * call this for any successfully decoded message when you are done with it. If + * pb_decode() returns with an error, the message is already released. + */ +void pb_release(const pb_msgdesc_t *fields, void *dest_struct); + +/************************************** + * Functions for manipulating streams * + **************************************/ + +/* Create an input stream for reading from a memory buffer. + * + * msglen should be the actual length of the message, not the full size of + * allocated buffer. + * + * Alternatively, you can use a custom stream that reads directly from e.g. + * a file or a network socket. + */ +pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen); + +/* Function to read from a pb_istream_t. You can use this if you need to + * read some custom header data, or to read data in field callbacks. + */ +bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); + + +/************************************************ + * Helper functions for writing field callbacks * + ************************************************/ + +/* Decode the tag for the next field in the stream. Gives the wire type and + * field tag. At end of the message, returns false and sets eof to true. */ +bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof); + +/* Skip the field payload data, given the wire type. */ +bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type); + +/* Decode an integer in the varint format. This works for enum, int32, + * int64, uint32 and uint64 field types. */ +#ifndef PB_WITHOUT_64BIT +bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest); +#else +#define pb_decode_varint pb_decode_varint32 +#endif + +/* Decode an integer in the varint format. This works for enum, int32, + * and uint32 field types. */ +bool pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); + +/* Decode a bool value in varint format. */ +bool pb_decode_bool(pb_istream_t *stream, bool *dest); + +/* Decode an integer in the zig-zagged svarint format. This works for sint32 + * and sint64. */ +#ifndef PB_WITHOUT_64BIT +bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest); +#else +bool pb_decode_svarint(pb_istream_t *stream, int32_t *dest); +#endif + +/* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to + * a 4-byte wide C variable. */ +bool pb_decode_fixed32(pb_istream_t *stream, void *dest); + +#ifndef PB_WITHOUT_64BIT +/* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to + * a 8-byte wide C variable. */ +bool pb_decode_fixed64(pb_istream_t *stream, void *dest); +#endif + +#ifdef PB_CONVERT_DOUBLE_FLOAT +/* Decode a double value into float variable. */ +bool pb_decode_double_as_float(pb_istream_t *stream, float *dest); +#endif + +/* Make a limited-length substream for reading a PB_WT_STRING field. */ +bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream); +bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/network/pb_encode.c b/src/network/pb_encode.c new file mode 100644 index 000000000..7f5620125 --- /dev/null +++ b/src/network/pb_encode.c @@ -0,0 +1,1000 @@ +/* pb_encode.c -- encode a protobuf using minimal resources + * + * 2011 Petteri Aimonen + */ + +#include "pb.h" +#include "pb_encode.h" +#include "pb_common.h" + +/* Use the GCC warn_unused_result attribute to check that all return values + * are propagated correctly. On other compilers and gcc before 3.4.0 just + * ignore the annotation. + */ +#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) + #define checkreturn +#else + #define checkreturn __attribute__((warn_unused_result)) +#endif + +/************************************** + * Declarations internal to this file * + **************************************/ +static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); +static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *field); +static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *field); +static bool checkreturn encode_basic_field(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn encode_field(pb_ostream_t *stream, pb_field_iter_t *field); +static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension); +static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, uint32_t high); +static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_enc_fixed(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_iter_t *field); + +#ifdef PB_WITHOUT_64BIT +#define pb_int64_t int32_t +#define pb_uint64_t uint32_t +#else +#define pb_int64_t int64_t +#define pb_uint64_t uint64_t +#endif + +/******************************* + * pb_ostream_t implementation * + *******************************/ + +static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) +{ + pb_byte_t *dest = (pb_byte_t*)stream->state; + stream->state = dest + count; + + memcpy(dest, buf, count * sizeof(pb_byte_t)); + + return true; +} + +pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize) +{ + pb_ostream_t stream; +#ifdef PB_BUFFER_ONLY + /* In PB_BUFFER_ONLY configuration the callback pointer is just int*. + * NULL pointer marks a sizing field, so put a non-NULL value to mark a buffer stream. + */ + static const int marker = 0; + stream.callback = ▮ +#else + stream.callback = &buf_write; +#endif + stream.state = buf; + stream.max_size = bufsize; + stream.bytes_written = 0; +#ifndef PB_NO_ERRMSG + stream.errmsg = NULL; +#endif + return stream; +} + +bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) +{ + if (count > 0 && stream->callback != NULL) + { + if (stream->bytes_written + count < stream->bytes_written || + stream->bytes_written + count > stream->max_size) + { + PB_RETURN_ERROR(stream, "stream full"); + } + +#ifdef PB_BUFFER_ONLY + if (!buf_write(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#else + if (!stream->callback(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#endif + } + + stream->bytes_written += count; + return true; +} + +/************************* + * Encode a single field * + *************************/ + +/* Read a bool value without causing undefined behavior even if the value + * is invalid. See issue #434 and + * https://stackoverflow.com/questions/27661768/weird-results-for-conditional + */ +static bool safe_read_bool(const void *pSize) +{ + const char *p = (const char *)pSize; + size_t i; + for (i = 0; i < sizeof(bool); i++) + { + if (p[i] != 0) + return true; + } + return false; +} + +/* Encode a static array. Handles the size calculations and possible packing. */ +static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *field) +{ + pb_size_t i; + pb_size_t count; +#ifndef PB_ENCODE_ARRAYS_UNPACKED + size_t size; +#endif + + count = *(pb_size_t*)field->pSize; + + if (count == 0) + return true; + + if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size) + PB_RETURN_ERROR(stream, "array max size exceeded"); + +#ifndef PB_ENCODE_ARRAYS_UNPACKED + /* We always pack arrays if the datatype allows it. */ + if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) + { + if (!pb_encode_tag(stream, PB_WT_STRING, field->tag)) + return false; + + /* Determine the total size of packed array. */ + if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32) + { + size = 4 * (size_t)count; + } + else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64) + { + size = 8 * (size_t)count; + } + else + { + pb_ostream_t sizestream = PB_OSTREAM_SIZING; + void *pData_orig = field->pData; + for (i = 0; i < count; i++) + { + if (!pb_enc_varint(&sizestream, field)) + PB_RETURN_ERROR(stream, PB_GET_ERROR(&sizestream)); + field->pData = (char*)field->pData + field->data_size; + } + field->pData = pData_orig; + size = sizestream.bytes_written; + } + + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + if (stream->callback == NULL) + return pb_write(stream, NULL, size); /* Just sizing.. */ + + /* Write the data */ + for (i = 0; i < count; i++) + { + if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32 || PB_LTYPE(field->type) == PB_LTYPE_FIXED64) + { + if (!pb_enc_fixed(stream, field)) + return false; + } + else + { + if (!pb_enc_varint(stream, field)) + return false; + } + + field->pData = (char*)field->pData + field->data_size; + } + } + else /* Unpacked fields */ +#endif + { + for (i = 0; i < count; i++) + { + /* Normally the data is stored directly in the array entries, but + * for pointer-type string and bytes fields, the array entries are + * actually pointers themselves also. So we have to dereference once + * more to get to the actual data. */ + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER && + (PB_LTYPE(field->type) == PB_LTYPE_STRING || + PB_LTYPE(field->type) == PB_LTYPE_BYTES)) + { + bool status; + void *pData_orig = field->pData; + field->pData = *(void* const*)field->pData; + + if (!field->pData) + { + /* Null pointer in array is treated as empty string / bytes */ + status = pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, 0); + } + else + { + status = encode_basic_field(stream, field); + } + + field->pData = pData_orig; + + if (!status) + return false; + } + else + { + if (!encode_basic_field(stream, field)) + return false; + } + field->pData = (char*)field->pData + field->data_size; + } + } + + return true; +} + +/* In proto3, all fields are optional and are only encoded if their value is "non-zero". + * This function implements the check for the zero value. */ +static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *field) +{ + pb_type_t type = field->type; + + if (PB_ATYPE(type) == PB_ATYPE_STATIC) + { + if (PB_HTYPE(type) == PB_HTYPE_REQUIRED) + { + /* Required proto2 fields inside proto3 submessage, pretty rare case */ + return false; + } + else if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + { + /* Repeated fields inside proto3 submessage: present if count != 0 */ + return *(const pb_size_t*)field->pSize == 0; + } + else if (PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + /* Oneof fields */ + return *(const pb_size_t*)field->pSize == 0; + } + else if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->pSize != NULL) + { + /* Proto2 optional fields inside proto3 message, or proto3 + * submessage fields. */ + return safe_read_bool(field->pSize) == false; + } + else if (field->descriptor->default_value) + { + /* Proto3 messages do not have default values, but proto2 messages + * can contain optional fields without has_fields (generator option 'proto3'). + * In this case they must always be encoded, to make sure that the + * non-zero default value is overwritten. + */ + return false; + } + + /* Rest is proto3 singular fields */ + if (PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) + { + /* Simple integer / float fields */ + pb_size_t i; + const char *p = (const char*)field->pData; + for (i = 0; i < field->data_size; i++) + { + if (p[i] != 0) + { + return false; + } + } + + return true; + } + else if (PB_LTYPE(type) == PB_LTYPE_BYTES) + { + const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)field->pData; + return bytes->size == 0; + } + else if (PB_LTYPE(type) == PB_LTYPE_STRING) + { + return *(const char*)field->pData == '\0'; + } + else if (PB_LTYPE(type) == PB_LTYPE_FIXED_LENGTH_BYTES) + { + /* Fixed length bytes is only empty if its length is fixed + * as 0. Which would be pretty strange, but we can check + * it anyway. */ + return field->data_size == 0; + } + else if (PB_LTYPE_IS_SUBMSG(type)) + { + /* Check all fields in the submessage to find if any of them + * are non-zero. The comparison cannot be done byte-per-byte + * because the C struct may contain padding bytes that must + * be skipped. Note that usually proto3 submessages have + * a separate has_field that is checked earlier in this if. + */ + pb_field_iter_t iter; + if (pb_field_iter_begin(&iter, field->submsg_desc, field->pData)) + { + do + { + if (!pb_check_proto3_default_value(&iter)) + { + return false; + } + } while (pb_field_iter_next(&iter)); + } + return true; + } + } + else if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + return field->pData == NULL; + } + else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) + { + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) + { + const pb_extension_t *extension = *(const pb_extension_t* const *)field->pData; + return extension == NULL; + } + else if (field->descriptor->field_callback == pb_default_field_callback) + { + pb_callback_t *pCallback = (pb_callback_t*)field->pData; + return pCallback->funcs.encode == NULL; + } + else + { + return field->descriptor->field_callback == NULL; + } + } + + return false; /* Not typically reached, safe default for weird special cases. */ +} + +/* Encode a field with static or pointer allocation, i.e. one whose data + * is available to the encoder directly. */ +static bool checkreturn encode_basic_field(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + if (!field->pData) + { + /* Missing pointer field */ + return true; + } + + if (!pb_encode_tag_for_field(stream, field)) + return false; + + switch (PB_LTYPE(field->type)) + { + case PB_LTYPE_BOOL: + return pb_enc_bool(stream, field); + + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + return pb_enc_varint(stream, field); + + case PB_LTYPE_FIXED32: + case PB_LTYPE_FIXED64: + return pb_enc_fixed(stream, field); + + case PB_LTYPE_BYTES: + return pb_enc_bytes(stream, field); + + case PB_LTYPE_STRING: + return pb_enc_string(stream, field); + + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_SUBMSG_W_CB: + return pb_enc_submessage(stream, field); + + case PB_LTYPE_FIXED_LENGTH_BYTES: + return pb_enc_fixed_length_bytes(stream, field); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +/* Encode a field with callback semantics. This means that a user function is + * called to provide and encode the actual data. */ +static bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + if (field->descriptor->field_callback != NULL) + { + if (!field->descriptor->field_callback(NULL, stream, field)) + PB_RETURN_ERROR(stream, "callback error"); + } + return true; +} + +/* Encode a single field of any callback, pointer or static type. */ +static bool checkreturn encode_field(pb_ostream_t *stream, pb_field_iter_t *field) +{ + /* Check field presence */ + if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) + { + if (*(const pb_size_t*)field->pSize != field->tag) + { + /* Different type oneof field */ + return true; + } + } + else if (PB_HTYPE(field->type) == PB_HTYPE_OPTIONAL) + { + if (field->pSize) + { + if (safe_read_bool(field->pSize) == false) + { + /* Missing optional field */ + return true; + } + } + else if (PB_ATYPE(field->type) == PB_ATYPE_STATIC) + { + /* Proto3 singular field */ + if (pb_check_proto3_default_value(field)) + return true; + } + } + + if (!field->pData) + { + if (PB_HTYPE(field->type) == PB_HTYPE_REQUIRED) + PB_RETURN_ERROR(stream, "missing required field"); + + /* Pointer field set to NULL */ + return true; + } + + /* Then encode field contents */ + if (PB_ATYPE(field->type) == PB_ATYPE_CALLBACK) + { + return encode_callback_field(stream, field); + } + else if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED) + { + return encode_array(stream, field); + } + else + { + return encode_basic_field(stream, field); + } +} + +/* Default handler for extension fields. Expects to have a pb_msgdesc_t + * pointer in the extension->type->arg field, pointing to a message with + * only one field in it. */ +static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension) +{ + pb_field_iter_t iter; + + if (!pb_field_iter_begin_extension_const(&iter, extension)) + PB_RETURN_ERROR(stream, "invalid extension"); + + return encode_field(stream, &iter); +} + + +/* Walk through all the registered extensions and give them a chance + * to encode themselves. */ +static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + const pb_extension_t *extension = *(const pb_extension_t* const *)field->pData; + + while (extension) + { + bool status; + if (extension->type->encode) + status = extension->type->encode(stream, extension); + else + status = default_extension_encoder(stream, extension); + + if (!status) + return false; + + extension = extension->next; + } + + return true; +} + +/********************* + * Encode all fields * + *********************/ + +bool checkreturn pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct) +{ + pb_field_iter_t iter; + if (!pb_field_iter_begin_const(&iter, fields, src_struct)) + return true; /* Empty message type */ + + do { + if (PB_LTYPE(iter.type) == PB_LTYPE_EXTENSION) + { + /* Special case for the extension field placeholder */ + if (!encode_extension_field(stream, &iter)) + return false; + } + else + { + /* Regular field */ + if (!encode_field(stream, &iter)) + return false; + } + } while (pb_field_iter_next(&iter)); + + return true; +} + +bool checkreturn pb_encode_ex(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct, unsigned int flags) +{ + if ((flags & PB_ENCODE_DELIMITED) != 0) + { + return pb_encode_submessage(stream, fields, src_struct); + } + else if ((flags & PB_ENCODE_NULLTERMINATED) != 0) + { + const pb_byte_t zero = 0; + + if (!pb_encode(stream, fields, src_struct)) + return false; + + return pb_write(stream, &zero, 1); + } + else + { + return pb_encode(stream, fields, src_struct); + } +} + +bool pb_get_encoded_size(size_t *size, const pb_msgdesc_t *fields, const void *src_struct) +{ + pb_ostream_t stream = PB_OSTREAM_SIZING; + + if (!pb_encode(&stream, fields, src_struct)) + return false; + + *size = stream.bytes_written; + return true; +} + +/******************** + * Helper functions * + ********************/ + +/* This function avoids 64-bit shifts as they are quite slow on many platforms. */ +static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, uint32_t high) +{ + size_t i = 0; + pb_byte_t buffer[10]; + pb_byte_t byte = (pb_byte_t)(low & 0x7F); + low >>= 7; + + while (i < 4 && (low != 0 || high != 0)) + { + byte |= 0x80; + buffer[i++] = byte; + byte = (pb_byte_t)(low & 0x7F); + low >>= 7; + } + + if (high) + { + byte = (pb_byte_t)(byte | ((high & 0x07) << 4)); + high >>= 3; + + while (high) + { + byte |= 0x80; + buffer[i++] = byte; + byte = (pb_byte_t)(high & 0x7F); + high >>= 7; + } + } + + buffer[i++] = byte; + + return pb_write(stream, buffer, i); +} + +bool checkreturn pb_encode_varint(pb_ostream_t *stream, pb_uint64_t value) +{ + if (value <= 0x7F) + { + /* Fast path: single byte */ + pb_byte_t byte = (pb_byte_t)value; + return pb_write(stream, &byte, 1); + } + else + { +#ifdef PB_WITHOUT_64BIT + return pb_encode_varint_32(stream, value, 0); +#else + return pb_encode_varint_32(stream, (uint32_t)value, (uint32_t)(value >> 32)); +#endif + } +} + +bool checkreturn pb_encode_svarint(pb_ostream_t *stream, pb_int64_t value) +{ + pb_uint64_t zigzagged; + pb_uint64_t mask = ((pb_uint64_t)-1) >> 1; /* Satisfy clang -fsanitize=integer */ + if (value < 0) + zigzagged = ~(((pb_uint64_t)value & mask) << 1); + else + zigzagged = (pb_uint64_t)value << 1; + + return pb_encode_varint(stream, zigzagged); +} + +bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value) +{ +#if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 + /* Fast path if we know that we're on little endian */ + return pb_write(stream, (const pb_byte_t*)value, 4); +#else + uint32_t val = *(const uint32_t*)value; + pb_byte_t bytes[4]; + bytes[0] = (pb_byte_t)(val & 0xFF); + bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); + bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); + bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); + return pb_write(stream, bytes, 4); +#endif +} + +#ifndef PB_WITHOUT_64BIT +bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value) +{ +#if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 + /* Fast path if we know that we're on little endian */ + return pb_write(stream, (const pb_byte_t*)value, 8); +#else + uint64_t val = *(const uint64_t*)value; + pb_byte_t bytes[8]; + bytes[0] = (pb_byte_t)(val & 0xFF); + bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); + bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); + bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); + bytes[4] = (pb_byte_t)((val >> 32) & 0xFF); + bytes[5] = (pb_byte_t)((val >> 40) & 0xFF); + bytes[6] = (pb_byte_t)((val >> 48) & 0xFF); + bytes[7] = (pb_byte_t)((val >> 56) & 0xFF); + return pb_write(stream, bytes, 8); +#endif +} +#endif + +bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number) +{ + pb_uint64_t tag = ((pb_uint64_t)field_number << 3) | wiretype; + return pb_encode_varint(stream, tag); +} + +bool pb_encode_tag_for_field ( pb_ostream_t* stream, const pb_field_iter_t* field ) +{ + pb_wire_type_t wiretype; + switch (PB_LTYPE(field->type)) + { + case PB_LTYPE_BOOL: + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + wiretype = PB_WT_VARINT; + break; + + case PB_LTYPE_FIXED32: + wiretype = PB_WT_32BIT; + break; + + case PB_LTYPE_FIXED64: + wiretype = PB_WT_64BIT; + break; + + case PB_LTYPE_BYTES: + case PB_LTYPE_STRING: + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_SUBMSG_W_CB: + case PB_LTYPE_FIXED_LENGTH_BYTES: + wiretype = PB_WT_STRING; + break; + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } + + return pb_encode_tag(stream, wiretype, field->tag); +} + +bool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size) +{ + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + return pb_write(stream, buffer, size); +} + +bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct) +{ + /* First calculate the message size using a non-writing substream. */ + pb_ostream_t substream = PB_OSTREAM_SIZING; + size_t size; + bool status; + + if (!pb_encode(&substream, fields, src_struct)) + { +#ifndef PB_NO_ERRMSG + stream->errmsg = substream.errmsg; +#endif + return false; + } + + size = substream.bytes_written; + + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + if (stream->callback == NULL) + return pb_write(stream, NULL, size); /* Just sizing */ + + if (stream->bytes_written + size > stream->max_size) + PB_RETURN_ERROR(stream, "stream full"); + + /* Use a substream to verify that a callback doesn't write more than + * what it did the first time. */ + substream.callback = stream->callback; + substream.state = stream->state; + substream.max_size = size; + substream.bytes_written = 0; +#ifndef PB_NO_ERRMSG + substream.errmsg = NULL; +#endif + + status = pb_encode(&substream, fields, src_struct); + + stream->bytes_written += substream.bytes_written; + stream->state = substream.state; +#ifndef PB_NO_ERRMSG + stream->errmsg = substream.errmsg; +#endif + + if (substream.bytes_written != size) + PB_RETURN_ERROR(stream, "submsg size changed"); + + return status; +} + +/* Field encoders */ + +static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + uint32_t value = safe_read_bool(field->pData) ? 1 : 0; + PB_UNUSED(field); + return pb_encode_varint(stream, value); +} + +static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + if (PB_LTYPE(field->type) == PB_LTYPE_UVARINT) + { + /* Perform unsigned integer extension */ + pb_uint64_t value = 0; + + if (field->data_size == sizeof(uint_least8_t)) + value = *(const uint_least8_t*)field->pData; + else if (field->data_size == sizeof(uint_least16_t)) + value = *(const uint_least16_t*)field->pData; + else if (field->data_size == sizeof(uint32_t)) + value = *(const uint32_t*)field->pData; + else if (field->data_size == sizeof(pb_uint64_t)) + value = *(const pb_uint64_t*)field->pData; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + return pb_encode_varint(stream, value); + } + else + { + /* Perform signed integer extension */ + pb_int64_t value = 0; + + if (field->data_size == sizeof(int_least8_t)) + value = *(const int_least8_t*)field->pData; + else if (field->data_size == sizeof(int_least16_t)) + value = *(const int_least16_t*)field->pData; + else if (field->data_size == sizeof(int32_t)) + value = *(const int32_t*)field->pData; + else if (field->data_size == sizeof(pb_int64_t)) + value = *(const pb_int64_t*)field->pData; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (PB_LTYPE(field->type) == PB_LTYPE_SVARINT) + return pb_encode_svarint(stream, value); +#ifdef PB_WITHOUT_64BIT + else if (value < 0) + return pb_encode_varint_32(stream, (uint32_t)value, (uint32_t)-1); +#endif + else + return pb_encode_varint(stream, (pb_uint64_t)value); + + } +} + +static bool checkreturn pb_enc_fixed(pb_ostream_t *stream, const pb_field_iter_t *field) +{ +#ifdef PB_CONVERT_DOUBLE_FLOAT + if (field->data_size == sizeof(float) && PB_LTYPE(field->type) == PB_LTYPE_FIXED64) + { + return pb_encode_float_as_double(stream, *(float*)field->pData); + } +#endif + + if (field->data_size == sizeof(uint32_t)) + { + return pb_encode_fixed32(stream, field->pData); + } +#ifndef PB_WITHOUT_64BIT + else if (field->data_size == sizeof(uint64_t)) + { + return pb_encode_fixed64(stream, field->pData); + } +#endif + else + { + PB_RETURN_ERROR(stream, "invalid data_size"); + } +} + +static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + const pb_bytes_array_t *bytes = NULL; + + bytes = (const pb_bytes_array_t*)field->pData; + + if (bytes == NULL) + { + /* Treat null pointer as an empty bytes field */ + return pb_encode_string(stream, NULL, 0); + } + + if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && + bytes->size > field->data_size - offsetof(pb_bytes_array_t, bytes)) + { + PB_RETURN_ERROR(stream, "bytes size exceeded"); + } + + return pb_encode_string(stream, bytes->bytes, (size_t)bytes->size); +} + +static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + size_t size = 0; + size_t max_size = (size_t)field->data_size; + const char *str = (const char*)field->pData; + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { + max_size = (size_t)-1; + } + else + { + /* pb_dec_string() assumes string fields end with a null + * terminator when the type isn't PB_ATYPE_POINTER, so we + * shouldn't allow more than max-1 bytes to be written to + * allow space for the null terminator. + */ + if (max_size == 0) + PB_RETURN_ERROR(stream, "zero-length string"); + + max_size -= 1; + } + + + if (str == NULL) + { + size = 0; /* Treat null pointer as an empty string */ + } + else + { + const char *p = str; + + /* strnlen() is not always available, so just use a loop */ + while (size < max_size && *p != '\0') + { + size++; + p++; + } + + if (*p != '\0') + { + PB_RETURN_ERROR(stream, "unterminated string"); + } + } + +#ifdef PB_VALIDATE_UTF8 + if (!pb_validate_utf8(str)) + PB_RETURN_ERROR(stream, "invalid utf8"); +#endif + + return pb_encode_string(stream, (const pb_byte_t*)str, size); +} + +static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + if (field->submsg_desc == NULL) + PB_RETURN_ERROR(stream, "invalid field descriptor"); + + if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL) + { + /* Message callback is stored right before pSize. */ + pb_callback_t *callback = (pb_callback_t*)field->pSize - 1; + if (callback->funcs.encode) + { + if (!callback->funcs.encode(stream, field, &callback->arg)) + return false; + } + } + + return pb_encode_submessage(stream, field->submsg_desc, field->pData); +} + +static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + return pb_encode_string(stream, (const pb_byte_t*)field->pData, (size_t)field->data_size); +} + +#ifdef PB_CONVERT_DOUBLE_FLOAT +bool pb_encode_float_as_double(pb_ostream_t *stream, float value) +{ + union { float f; uint32_t i; } in; + uint_least8_t sign; + int exponent; + uint64_t mantissa; + + in.f = value; + + /* Decompose input value */ + sign = (uint_least8_t)((in.i >> 31) & 1); + exponent = (int)((in.i >> 23) & 0xFF) - 127; + mantissa = in.i & 0x7FFFFF; + + if (exponent == 128) + { + /* Special value (NaN etc.) */ + exponent = 1024; + } + else if (exponent == -127) + { + if (!mantissa) + { + /* Zero */ + exponent = -1023; + } + else + { + /* Denormalized */ + mantissa <<= 1; + while (!(mantissa & 0x800000)) + { + mantissa <<= 1; + exponent--; + } + mantissa &= 0x7FFFFF; + } + } + + /* Combine fields */ + mantissa <<= 29; + mantissa |= (uint64_t)(exponent + 1023) << 52; + mantissa |= (uint64_t)sign << 63; + + return pb_encode_fixed64(stream, &mantissa); +} +#endif diff --git a/src/network/pb_encode.h b/src/network/pb_encode.h new file mode 100644 index 000000000..891368322 --- /dev/null +++ b/src/network/pb_encode.h @@ -0,0 +1,185 @@ +/* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c. + * The main function is pb_encode. You also need an output stream, and the + * field descriptions created by nanopb_generator.py. + */ + +#ifndef PB_ENCODE_H_INCLUDED +#define PB_ENCODE_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure for defining custom output streams. You will need to provide + * a callback function to write the bytes to your storage, which can be + * for example a file or a network socket. + * + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause encoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer). + * 3) pb_write will update bytes_written after your callback runs. + * 4) Substreams will modify max_size and bytes_written. Don't use them + * to calculate any pointers. + */ +struct pb_ostream_s +{ +#ifdef PB_BUFFER_ONLY + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + * Also, NULL pointer marks a 'sizing stream' that does not + * write anything. + */ + const int *callback; +#else + bool (*callback)(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); +#endif + void *state; /* Free field for use by callback implementation. */ + size_t max_size; /* Limit number of output bytes written (or use SIZE_MAX). */ + size_t bytes_written; /* Number of bytes written so far. */ + +#ifndef PB_NO_ERRMSG + const char *errmsg; +#endif +}; + +/*************************** + * Main encoding functions * + ***************************/ + +/* Encode a single protocol buffers message from C structure into a stream. + * Returns true on success, false on any failure. + * The actual struct pointed to by src_struct must match the description in fields. + * All required fields in the struct are assumed to have been filled in. + * + * Example usage: + * MyMessage msg = {}; + * uint8_t buffer[64]; + * pb_ostream_t stream; + * + * msg.field1 = 42; + * stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + * pb_encode(&stream, MyMessage_fields, &msg); + */ +bool pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct); + +/* Extended version of pb_encode, with several options to control the + * encoding process: + * + * PB_ENCODE_DELIMITED: Prepend the length of message as a varint. + * Corresponds to writeDelimitedTo() in Google's + * protobuf API. + * + * PB_ENCODE_NULLTERMINATED: Append a null byte to the message for termination. + * NOTE: This behaviour is not supported in most other + * protobuf implementations, so PB_ENCODE_DELIMITED + * is a better option for compatibility. + */ +#define PB_ENCODE_DELIMITED 0x02U +#define PB_ENCODE_NULLTERMINATED 0x04U +bool pb_encode_ex(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct, unsigned int flags); + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define pb_encode_delimited(s,f,d) pb_encode_ex(s,f,d, PB_ENCODE_DELIMITED) +#define pb_encode_nullterminated(s,f,d) pb_encode_ex(s,f,d, PB_ENCODE_NULLTERMINATED) + +/* Encode the message to get the size of the encoded data, but do not store + * the data. */ +bool pb_get_encoded_size(size_t *size, const pb_msgdesc_t *fields, const void *src_struct); + +/************************************** + * Functions for manipulating streams * + **************************************/ + +/* Create an output stream for writing into a memory buffer. + * The number of bytes written can be found in stream.bytes_written after + * encoding the message. + * + * Alternatively, you can use a custom stream that writes directly to e.g. + * a file or a network socket. + */ +pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize); + +/* Pseudo-stream for measuring the size of a message without actually storing + * the encoded data. + * + * Example usage: + * MyMessage msg = {}; + * pb_ostream_t stream = PB_OSTREAM_SIZING; + * pb_encode(&stream, MyMessage_fields, &msg); + * printf("Message size is %d\n", stream.bytes_written); + */ +#ifndef PB_NO_ERRMSG +#define PB_OSTREAM_SIZING {0,0,0,0,0} +#else +#define PB_OSTREAM_SIZING {0,0,0,0} +#endif + +/* Function to write into a pb_ostream_t stream. You can use this if you need + * to append or prepend some custom headers to the message. + */ +bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); + + +/************************************************ + * Helper functions for writing field callbacks * + ************************************************/ + +/* Encode field header based on type and field number defined in the field + * structure. Call this from the callback before writing out field contents. */ +bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_iter_t *field); + +/* Encode field header by manually specifying wire type. You need to use this + * if you want to write out packed arrays from a callback field. */ +bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number); + +/* Encode an integer in the varint format. + * This works for bool, enum, int32, int64, uint32 and uint64 field types. */ +#ifndef PB_WITHOUT_64BIT +bool pb_encode_varint(pb_ostream_t *stream, uint64_t value); +#else +bool pb_encode_varint(pb_ostream_t *stream, uint32_t value); +#endif + +/* Encode an integer in the zig-zagged svarint format. + * This works for sint32 and sint64. */ +#ifndef PB_WITHOUT_64BIT +bool pb_encode_svarint(pb_ostream_t *stream, int64_t value); +#else +bool pb_encode_svarint(pb_ostream_t *stream, int32_t value); +#endif + +/* Encode a string or bytes type field. For strings, pass strlen(s) as size. */ +bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size); + +/* Encode a fixed32, sfixed32 or float value. + * You need to pass a pointer to a 4-byte wide C variable. */ +bool pb_encode_fixed32(pb_ostream_t *stream, const void *value); + +#ifndef PB_WITHOUT_64BIT +/* Encode a fixed64, sfixed64 or double value. + * You need to pass a pointer to a 8-byte wide C variable. */ +bool pb_encode_fixed64(pb_ostream_t *stream, const void *value); +#endif + +#ifdef PB_CONVERT_DOUBLE_FLOAT +/* Encode a float value so that it appears like a double in the encoded + * message. */ +bool pb_encode_float_as_double(pb_ostream_t *stream, float value); +#endif + +/* Encode a submessage field. + * You need to pass the pb_field_t array and pointer to struct, just like + * with pb_encode(). This internally encodes the submessage twice, first to + * calculate message size and then to actually write it out. + */ +bool pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/nvr.c b/src/nvr.c index 7f43a76c1..b6bf2a5a5 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -310,18 +310,25 @@ nvr_close(void) void nvr_time_sync(void) { - struct tm *tm; - time_t now; + struct tm tm; + time_t now; /* Get the current time of day, and convert to local time. */ (void) time(&now); - if (time_sync & TIME_SYNC_UTC) - tm = gmtime(&now); - else - tm = localtime(&now); - /* Set the internal clock. */ - nvr_time_set(tm); +#ifdef _WIN32 + if (time_sync & TIME_SYNC_UTC) + gmtime_s(&tm, &now); + else + localtime_s(&tm, &now); +#else + if (time_sync & TIME_SYNC_UTC) + gmtime_r(&now, &tm); + else + localtime_r(&now, &tm); +#endif + + nvr_time_set(&tm); } /* Get current time from internal clock. */ diff --git a/src/nvr_at.c b/src/nvr_at.c index bde80b434..4deda98be 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -296,6 +296,7 @@ #define FLAG_P6RP4_HACK 0x10 #define FLAG_PIIX4 0x20 #define FLAG_MULTI_BANK 0x40 +#define FLAG_MARTIN_HACK 0x80 typedef struct local_t { int8_t stat; @@ -733,6 +734,13 @@ nvr_read(uint16_t addr, void *priv) ret = REGD_VRT; break; + case 0x11: + if (local->flags & FLAG_MARTIN_HACK) + ret = nvr->regs[local->addr[addr_id]] | 0x02; + else + ret = nvr->regs[local->addr[addr_id]]; + break; + case 0x2c: if (!nvr->is_new && (local->flags & FLAG_AMI_1994_HACK)) ret = nvr->regs[local->addr[addr_id]] & 0x7f; @@ -771,6 +779,17 @@ nvr_read(uint16_t addr, void *priv) ret = checksum >> 8; else ret = checksum & 0xff; + } else if (!nvr->is_new && (local->flags & FLAG_MARTIN_HACK)) { + for (i = 0x10; i <= 0x2d; i++) { + if (i == 0x11) + checksum += (nvr->regs[i] | 0x02); + else + checksum += nvr->regs[i]; + } + if (local->addr[addr_id] == 0x2e) + ret = checksum >> 8; + else + ret = checksum & 0xff; } else ret = nvr->regs[local->addr[addr_id]]; break; @@ -1088,9 +1107,10 @@ nvr_at_init(const device_t *info) case 1: /* standard AT */ case 5: /* AMI WinBIOS 1994 */ case 6: /* AMI BIOS 1995 */ - if ((info->local & 0x1f) == 0x11) + if ((info->local & 0x1f) == 0x11) { local->flags |= FLAG_PIIX4; - else { + local->def = 0x00; + } else { local->def = 0x00; if ((info->local & 0x1f) == 0x15) local->flags |= FLAG_AMI_1994_HACK; @@ -1123,9 +1143,11 @@ nvr_at_init(const device_t *info) if (info->local & 0x10) { local->def = 0x00; local->flags |= FLAG_AMI_1992_HACK; - } else if (info->local == 36) + } else if ((info->local == 36) || (info->local == 68)) { local->def = 0x00; - else + if (info->local == 68) + local->flags |= FLAG_MARTIN_HACK; + } else local->def = 0xff; nvr->irq = 8; local->cent = RTC_CENTURY_AT; @@ -1160,6 +1182,9 @@ nvr_at_init(const device_t *info) /* Initialize the generic NVR. */ nvr_init(nvr); + if (nvr->is_new && (local->flags & FLAG_MARTIN_HACK)) + nvr->regs[0x11] = nvr->regs[0x2f] = 0x02; + if (nvr_at_inited == 0) { /* Start the timers. */ timer_add(&local->update_timer, timer_update, nvr, 0); @@ -1426,6 +1451,20 @@ const device_t amstrad_megapc_nvr_device = { .config = NULL }; +const device_t martin_nvr_device = { + .name = "Zeos Martin NVRAM", + .internal_name = "martin_nvr", + .flags = DEVICE_ISA16, + .local = 68, + .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 elt_nvr_device = { .name = "Epson Equity LT NVRAM", .internal_name = "elt_nvr", diff --git a/src/pci.c b/src/pci.c index c3020ca73..94ab9d5f2 100644 --- a/src/pci.c +++ b/src/pci.c @@ -855,10 +855,10 @@ pci_register_card(int pci_card) /* 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_add_bridge(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot) { pci_card_t *card; - uint8_t bridge_slot = agp ? pci_find_slot(PCI_ADD_AGPBRIDGE, 0xff) : last_normal_pci_card_id; + uint8_t bridge_slot = (add_type == PCI_ADD_NORMAL) ? last_normal_pci_card_id : pci_find_slot(add_type, 0xff); if (bridge_slot != PCI_CARD_INVALID) { card = &pci_cards[bridge_slot]; diff --git a/src/pic.c b/src/pic.c index cf17e8205..446ea1361 100644 --- a/src/pic.c +++ b/src/pic.c @@ -638,6 +638,25 @@ pic_reset_hard(void) } } +void +pic_toggle_latch(int is_ps2) +{ + pic_kbd_latch(0x00); + pic_mouse_latch(0x00); + + /* Explicitly reset the latches. */ + kbd_latch = mouse_latch = 0; + latched_irqs = 0x0000; + + /* The situation is as follows: There is a giant mess when it comes to these latches on real hardware, + to the point that there's even boards with board-level latched that get used in place of the latches + on the chipset, therefore, I'm just doing this here for the sake of simplicity. */ + if (is_ps2) { + pic_kbd_latch(0x01); + pic_mouse_latch(0x01); + } +} + void pic_init(void) { @@ -674,6 +693,13 @@ picint_common(uint16_t num, int level, int set, uint8_t *irq_state) uint16_t lines = level ? 0x0000 : num; pic_t *dev; + /* + Do this because some emulated cards will, for whatever reason, attempt to + raise an IRQ at init when the PIC has not yet been properly initialized. + */ + if (update_pending == NULL) + return; + /* Make sure to ignore all slave IRQ's, and in case of AT+, translate IRQ 2 to IRQ 9. */ for (uint8_t i = 0; i < 8; i++) { diff --git a/src/pit.c b/src/pit.c index a283d1205..b99fed799 100644 --- a/src/pit.c +++ b/src/pit.c @@ -247,7 +247,7 @@ ctr_tick(ctr_t *ctr, void *priv) ctr_decrease_count(ctr); } else ctr->count -= (ctr->newcount ? 1 : 2); - if (ctr->count < 0) { + if (ctr->count == 0) { ctr_set_out(ctr, 0, pit); ctr_load_count(ctr); ctr->state = 3; @@ -266,7 +266,7 @@ ctr_tick(ctr_t *ctr, void *priv) ctr_decrease_count(ctr); } else ctr->count -= (ctr->newcount ? 3 : 2); - if (ctr->count < 0) { + if (ctr->count == 0) { ctr_set_out(ctr, 1, pit); ctr_load_count(ctr); ctr->state = 2; @@ -334,7 +334,7 @@ ctr_set_state_1(ctr_t *ctr) { uint8_t mode = (ctr->m & 0x03); int do_reload = !!ctr->incomplete || (mode == 0) || (ctr->state == 0); - + ctr->incomplete = 0; if (do_reload) @@ -358,8 +358,18 @@ ctr_load(ctr_t *ctr) else ctr_set_state_1(ctr); - if (ctr->load_func != NULL) - ctr->load_func(ctr->m, ctr->l ? ctr->l : 0x10000); + if (ctr->load_func != NULL) { + uint32_t count = ctr->l ? ctr->l : 0x10000; + if (ctr->bcd) { + uint32_t bcd_count = (((count >> 16) & 0xf) * 10000) | + (((count >> 12) & 0xf) * 1000 ) | + (((count >> 8 ) & 0xf) * 100 ) | + (((count >> 4 ) & 0xf) * 10 ) | + (count & 0xf); + ctr->load_func(ctr->m, bcd_count); + } else + ctr->load_func(ctr->m, ctr->l ? ctr->l : 0x10000); + } pit_log("Counter loaded, state = %i, gate = %i, latch = %i\n", ctr->state, ctr->gate, ctr->latch); } @@ -540,7 +550,8 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr_t *ctr; if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { - pit_log("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); + pit_log("[%04X:%08X] pit_write(%04X, %02X, %016" PRIX64 ")\n", + CS, cpu_state.pc, addr, val, (uint64_t) (uintptr_t) priv); } switch (addr & 3) { @@ -788,7 +799,8 @@ pit_read(uint16_t addr, void *priv) } if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { - pit_log("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); + pit_log("[%04X:%08X] pit_read(%04X, %016" PRIX64 ") = %02X\n", + CS, cpu_state.pc, addr, (uint64_t) (uintptr_t) priv, ret); } return ret; diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index d0836e5f2..e4f9c81ee 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -57,6 +57,7 @@ #include FT_FREETYPE_H #define HAVE_STDARG_H #include <86box/86box.h> +#include <86box/device.h> #include "cpu.h" #include <86box/machine.h> #include <86box/timer.h> @@ -71,15 +72,18 @@ #include <86box/png_struct.h> #include <86box/printer.h> #include <86box/prt_devs.h> +#include <86box/prt_papersizes.h> /* Default page values (for now.) */ #define COLOR_BLACK 7 << 5 -#define PAGE_WIDTH 8.5 /* standard U.S. Letter */ -#define PAGE_HEIGHT 11.0 +#define PAGE_WIDTH LETTER_PAGE_WIDTH +#define PAGE_HEIGHT LETTER_PAGE_HEIGHT +#if 0 #define PAGE_LMARGIN 0.0 #define PAGE_RMARGIN PAGE_WIDTH #define PAGE_TMARGIN 0.0 #define PAGE_BMARGIN PAGE_HEIGHT +#endif #define PAGE_DPI 360 #define PAGE_CPI 10.0 /* standard 10 cpi */ #define PAGE_LPI 6.0 /* standard 6 lpi */ @@ -1881,6 +1885,46 @@ write_data(uint8_t val, void *priv) dev->data = val; } +static void +autofeed(uint8_t val, void *priv) +{ + escp_t *dev = (escp_t *) priv; + + if (dev == NULL) + return; + + dev->autofeed = ((val & 0x02) > 0); +} + +static void +strobe(uint8_t old, uint8_t val, void *priv) +{ + escp_t *dev = (escp_t *) priv; + + if (dev == NULL) + return; + + /* Data is strobed to the parallel printer on the falling edge of the + strobe bit. */ + if (!(val & 0x01) && (old & 0x01)) { + /* Process incoming character. */ + handle_char(dev, dev->data); + + if (timer_is_enabled(&dev->timeout_timer)) { + timer_disable(&dev->timeout_timer); +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } + /* ACK it, will be read on next READ STATUS. */ + dev->ack = 1; + timer_set_delay_u64(&dev->pulse_timer, ISACONST); + + timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + } +} + static void write_ctrl(uint8_t val, void *priv) { @@ -1907,6 +1951,13 @@ write_ctrl(uint8_t val, void *priv) /* Process incoming character. */ handle_char(dev, dev->data); + if (timer_is_enabled(&dev->timeout_timer)) { + timer_disable(&dev->timeout_timer); +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } /* ACK it, will be read on next READ STATUS. */ dev->ack = 1; timer_set_delay_u64(&dev->pulse_timer, ISACONST); @@ -1919,14 +1970,6 @@ write_ctrl(uint8_t val, void *priv) dev->autofeed = ((val & 0x02) > 0); } -static uint8_t -read_data(void *priv) -{ - const escp_t *dev = (escp_t *) priv; - - return dev->data; -} - static uint8_t read_ctrl(void *priv) { @@ -2053,17 +2096,65 @@ escp_close(void *priv) free(dev->page); } + FT_Done_Face(dev->fontface); free(dev); } -const lpt_device_t lpt_prt_escp_device = { +// clang-format off +#if 0 +static const device_config_t lpt_prt_escp_config[] = { + { + .name = "paper_size", + .description = "Paper Size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Letter", .value = 0 }, + { .description = "A4", .value = 1 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +#endif +// clang-format on + +const device_t prt_escp_device = { .name = "Generic ESC/P Dot-Matrix Printer", .internal_name = "dot_matrix", - .init = escp_init, - .close = escp_close, - .write_data = write_data, - .write_ctrl = write_ctrl, - .read_data = read_data, - .read_status = read_status, - .read_ctrl = read_ctrl + .flags = DEVICE_LPT, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, +#if 0 + .config = lpt_prt_escp_config +#else + .config = NULL +#endif +}; + +const lpt_device_t lpt_prt_escp_device = { + .name = "Generic ESC/P Dot-Matrix Printer", + .internal_name = "dot_matrix", + .init = escp_init, + .close = escp_close, + .write_data = write_data, + .write_ctrl = write_ctrl, + .autofeed = autofeed, + .strobe = strobe, + .read_status = read_status, + .read_ctrl = read_ctrl, + .epp_write_data = NULL, + .epp_request_read = NULL, + .priv = NULL, + .lpt = NULL, + .cfgdevice = (device_t *) &prt_escp_device }; diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 1298018ee..c7183ec3f 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -26,7 +26,9 @@ #include #include #include <86box/86box.h> +#include <86box/device.h> #include <86box/timer.h> +#include <86box/device.h> #include <86box/lpt.h> #include <86box/pit.h> #include <86box/path.h> @@ -34,6 +36,7 @@ #include <86box/plat_dynld.h> #include <86box/ui.h> #include <86box/prt_devs.h> +#include "cpu.h" #ifdef _WIN32 # define GSDLLAPI __stdcall @@ -319,6 +322,43 @@ process_data(ps_t *dev) dev->buffer[dev->buffer_pos] = 0; } +static void +ps_autofeed(uint8_t val, void *priv) +{ + ps_t *dev = (ps_t *) priv; + + if (dev == NULL) + return; + + dev->autofeed = val & 0x02 ? true : false; +} + +static void +ps_strobe(uint8_t old, uint8_t val, void *priv) +{ + ps_t *dev = (ps_t *) priv; + + if (dev == NULL) + return; + + if (!(val & 0x01) && (old & 0x01)) { + process_data(dev); + + if (timer_is_enabled(&dev->timeout_timer)) { + timer_disable(&dev->timeout_timer); +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } + + dev->ack = true; + + timer_set_delay_u64(&dev->pulse_timer, ISACONST); + timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + } +} + static void ps_write_ctrl(uint8_t val, void *priv) { @@ -342,6 +382,14 @@ ps_write_ctrl(uint8_t val, void *priv) if (!(val & 0x01) && (dev->ctrl & 0x01)) { process_data(dev); + if (timer_is_enabled(&dev->timeout_timer)) { + timer_disable(&dev->timeout_timer); +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } + dev->ack = true; timer_set_delay_u64(&dev->pulse_timer, ISACONST); @@ -479,27 +527,37 @@ ps_close(void *priv) } const lpt_device_t lpt_prt_ps_device = { - .name = "Generic PostScript Printer", - .internal_name = "postscript", - .init = ps_init, - .close = ps_close, - .write_data = ps_write_data, - .write_ctrl = ps_write_ctrl, - .read_data = NULL, - .read_status = ps_read_status, - .read_ctrl = NULL + .name = "Generic PostScript Printer", + .internal_name = "postscript", + .init = ps_init, + .close = ps_close, + .write_data = ps_write_data, + .write_ctrl = ps_write_ctrl, + .autofeed = ps_autofeed, + .strobe = ps_strobe, + .read_status = ps_read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL, + .priv = NULL, + .lpt = NULL }; #ifdef USE_PCL const lpt_device_t lpt_prt_pcl_device = { - .name = "Generic PCL5e Printer", - .internal_name = "pcl", - .init = pcl_init, - .close = ps_close, - .write_data = ps_write_data, - .write_ctrl = ps_write_ctrl, - .read_data = NULL, - .read_status = ps_read_status, - .read_ctrl = NULL + .name = "Generic PCL5e Printer", + .internal_name = "pcl", + .init = pcl_init, + .close = ps_close, + .write_data = ps_write_data, + .write_ctrl = ps_write_ctrl, + .autofeed = ps_autofeed, + .strobe = ps_strobe, + .read_status = ps_read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL, + .priv = NULL, + .lpt = NULL }; #endif diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index e04ef9680..a9808845f 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -63,12 +63,14 @@ #include <86box/lpt.h> #include <86box/printer.h> #include <86box/prt_devs.h> +#include "cpu.h" +#include <86box/prt_papersizes.h> #define FULL_PAGE 1 /* set if no top/bot margins */ /* Default page values (for now.) */ -#define PAGE_WIDTH 8.5 /* standard U.S. Letter */ -#define PAGE_HEIGHT 11 +#define PAGE_WIDTH LETTER_PAGE_WIDTH +#define PAGE_HEIGHT LETTER_PAGE_HEIGHT #define PAGE_LMARGIN 0.25 /* 0.25" left and right */ #define PAGE_RMARGIN 0.25 #if FULL_PAGE @@ -367,6 +369,46 @@ write_data(uint8_t val, void *priv) dev->data = val; } +static void +autofeed(uint8_t val, void *priv) +{ + prnt_t *dev = (prnt_t *) priv; + + if (dev == NULL) + return; + + /* set autofeed value */ + dev->autofeed = val & 0x02 ? 1 : 0; +} + +static void +strobe(uint8_t old, uint8_t val, void *priv) +{ + prnt_t *dev = (prnt_t *) priv; + + if (dev == NULL) + return; + + if (!(val & 0x01) && (old & 0x01)) { /* STROBE */ + /* Process incoming character. */ + handle_char(dev); + + if (timer_is_enabled(&dev->timeout_timer)) { + timer_disable(&dev->timeout_timer); +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } + + /* ACK it, will be read on next READ STATUS. */ + dev->ack = 1; + + timer_set_delay_u64(&dev->pulse_timer, ISACONST); + timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + } +} + static void write_ctrl(uint8_t val, void *priv) { @@ -397,6 +439,14 @@ write_ctrl(uint8_t val, void *priv) /* ACK it, will be read on next READ STATUS. */ dev->ack = 1; + if (timer_is_enabled(&dev->timeout_timer)) { + timer_disable(&dev->timeout_timer); +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } + timer_set_delay_u64(&dev->pulse_timer, ISACONST); timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); } @@ -464,14 +514,61 @@ prnt_close(void *priv) free(dev); } -const lpt_device_t lpt_prt_text_device = { +// clang-format off +#if 0 +static const device_config_t lpt_prt_text_config[] = { + { + .name = "paper_size", + .description = "Paper Size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Letter", .value = 0 }, + { .description = "A4", .value = 1 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +#endif +// clang-format on + +const device_t prt_text_device = { .name = "Generic Text Printer", .internal_name = "text_prt", - .init = prnt_init, - .close = prnt_close, - .write_data = write_data, - .write_ctrl = write_ctrl, - .read_data = NULL, - .read_status = read_status, - .read_ctrl = NULL + .flags = DEVICE_LPT, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, +#if 0 + .config = lpt_prt_text_config +#else + .config = NULL +#endif +}; + +const lpt_device_t lpt_prt_text_device = { + .name = "Generic Text Printer", + .internal_name = "text_prt", + .init = prnt_init, + .close = prnt_close, + .write_data = write_data, + .write_ctrl = write_ctrl, + .autofeed = autofeed, + .strobe = strobe, + .read_status = read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL, + .priv = NULL, + .lpt = NULL, + .cfgdevice = (device_t *) &prt_text_device }; diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 4231034d5..1b69635b2 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -85,11 +85,11 @@ add_library(ui STATIC qt_renderercommon.hpp qt_softwarerenderer.cpp qt_softwarerenderer.hpp - qt_hardwarerenderer.cpp - qt_hardwarerenderer.hpp qt_openglrenderer.cpp qt_openglrenderer.hpp qt_glsl_parser.cpp + qt_about.cpp + qt_about.hpp qt_settings.cpp qt_settings.hpp @@ -189,6 +189,41 @@ add_library(ui STATIC qt_mediahistorymanager.cpp qt_mediahistorymanager.hpp + qt_downloader.cpp + qt_downloader.hpp + + qt_vmmanager_clientsocket.cpp + qt_vmmanager_clientsocket.hpp + qt_vmmanager_serversocket.cpp + qt_vmmanager_serversocket.hpp + qt_vmmanager_protocol.cpp + qt_vmmanager_protocol.hpp + qt_vmmanager_details.hpp + qt_vmmanager_details.cpp + qt_vmmanager_details.ui + qt_vmmanager_addmachine.cpp + qt_vmmanager_addmachine.hpp + qt_vmmanager_detailsection.cpp + qt_vmmanager_detailsection.hpp + qt_vmmanager_detailsection.ui + qt_vmmanager_listviewdelegate.hpp + qt_vmmanager_listviewdelegate.cpp + qt_vmmanager_preferences.cpp + qt_vmmanager_preferences.hpp + qt_vmmanager_preferences.ui + qt_vmmanager_main.hpp + qt_vmmanager_main.cpp + qt_vmmanager_main.ui + qt_vmmanager_model.cpp + qt_vmmanager_model.hpp + qt_vmmanager_system.cpp + qt_vmmanager_system.hpp + qt_vmmanager_config.cpp + qt_vmmanager_config.hpp + qt_vmmanager_mainwindow.cpp + qt_vmmanager_mainwindow.hpp + qt_vmmanager_mainwindow.ui + ../qt_resources.qrc ./qdarkstyle/dark/darkstyle.qrc @@ -204,6 +239,23 @@ add_library(ui STATIC qt_iconindicators.cpp ) +if(EMU_BUILD_NUM) + target_sources(ui PRIVATE + qt_updatecheck.cpp + qt_updatecheck.hpp + qt_updatecheckdialog.cpp + qt_updatecheckdialog.hpp + qt_updatecheckdialog.ui + qt_updatedetails.cpp + qt_updatedetails.hpp + qt_updatedetails.ui + ) +endif() + +if(NETSWITCH) + target_compile_definitions(ui PRIVATE USE_NETSWITCH) +endif() + if(RTMIDI) target_compile_definitions(ui PRIVATE USE_RTMIDI) endif() @@ -243,6 +295,15 @@ if(WIN32 AND NOT SDL_JOYSTICK) target_sources(plat PRIVATE win_joystick_rawinput.c) target_link_libraries(86Box hid) else() + find_package(SDL2 REQUIRED) + include_directories(${SDL2_INCLUDE_DIRS}) + if(STATIC_BUILD AND TARGET SDL2::SDL2-static) + target_link_libraries(86Box SDL2::SDL2-static) + elseif(TARGET SDL2::SDL2) + target_link_libraries(86Box SDL2::SDL2) + else() + target_link_libraries(86Box ${SDL2_LIBRARIES}) + endif() target_sources(plat PRIVATE sdl_joystick.c) endif() @@ -414,6 +475,7 @@ endif() if (UNIX AND NOT APPLE AND NOT HAIKU) target_sources(ui PRIVATE x11_util.c) + target_link_libraries(plat PRIVATE ${CMAKE_DL_LIBS}) find_package(X11 REQUIRED) target_link_libraries(ui PRIVATE X11::X11 X11::Xi) @@ -453,6 +515,7 @@ if (UNIX AND NOT APPLE AND NOT HAIKU) set(WL_SOURCE_VAR) ecm_add_wayland_client_protocol(WL_SOURCE_VAR PROTOCOL ${CMAKE_SOURCE_DIR}/wl_protocols/relative-pointer-unstable-v1.xml BASENAME relative-pointer-unstable-v1) ecm_add_wayland_client_protocol(WL_SOURCE_VAR PROTOCOL ${CMAKE_SOURCE_DIR}/wl_protocols/pointer-constraints-unstable-v1.xml BASENAME pointer-constraints-unstable-v1) + ecm_add_wayland_client_protocol(WL_SOURCE_VAR PROTOCOL ${CMAKE_SOURCE_DIR}/wl_protocols/keyboard-shortcuts-inhibit-unstable-v1.xml BASENAME keyboard-shortcuts-inhibit-unstable-v1) target_include_directories(ui PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${Qt${QT_MAJOR}Gui_PRIVATE_INCLUDE_DIRS}) target_sources(ui PRIVATE ${WL_SOURCE_VAR} wl_mouse.cpp) if (XKBCOMMON_FOUND) diff --git a/src/qt/assets/86box-wizard.png b/src/qt/assets/86box-wizard.png new file mode 100644 index 000000000..19ecda8c7 Binary files /dev/null and b/src/qt/assets/86box-wizard.png differ diff --git a/src/qt/assets/systemicons/cpq_deskpro.png b/src/qt/assets/systemicons/cpq_deskpro.png new file mode 100644 index 000000000..1bbca68a3 Binary files /dev/null and b/src/qt/assets/systemicons/cpq_deskpro.png differ diff --git a/src/qt/assets/systemicons/cpq_port_386.png b/src/qt/assets/systemicons/cpq_port_386.png new file mode 100644 index 000000000..4c55b3559 Binary files /dev/null and b/src/qt/assets/systemicons/cpq_port_386.png differ diff --git a/src/qt/assets/systemicons/cpq_port_II.png b/src/qt/assets/systemicons/cpq_port_II.png new file mode 100644 index 000000000..3254d9b5e Binary files /dev/null and b/src/qt/assets/systemicons/cpq_port_II.png differ diff --git a/src/qt/assets/systemicons/cpq_port_III.png b/src/qt/assets/systemicons/cpq_port_III.png new file mode 100644 index 000000000..65d2f714e Binary files /dev/null and b/src/qt/assets/systemicons/cpq_port_III.png differ diff --git a/src/qt/assets/systemicons/cpq_portable.png b/src/qt/assets/systemicons/cpq_portable.png new file mode 100644 index 000000000..d3dc381e4 Binary files /dev/null and b/src/qt/assets/systemicons/cpq_portable.png differ diff --git a/src/qt/assets/systemicons/cpq_pres_2240.png b/src/qt/assets/systemicons/cpq_pres_2240.png new file mode 100644 index 000000000..c50043cdd Binary files /dev/null and b/src/qt/assets/systemicons/cpq_pres_2240.png differ diff --git a/src/qt/assets/systemicons/cpq_pres_4500.png b/src/qt/assets/systemicons/cpq_pres_4500.png new file mode 100644 index 000000000..edd955b5a Binary files /dev/null and b/src/qt/assets/systemicons/cpq_pres_4500.png differ diff --git a/src/qt/assets/systemicons/ibm330.png b/src/qt/assets/systemicons/ibm330.png new file mode 100644 index 000000000..90637dc4c Binary files /dev/null and b/src/qt/assets/systemicons/ibm330.png differ diff --git a/src/qt/assets/systemicons/ibm_at.png b/src/qt/assets/systemicons/ibm_at.png new file mode 100644 index 000000000..e6710180e Binary files /dev/null and b/src/qt/assets/systemicons/ibm_at.png differ diff --git a/src/qt/assets/systemicons/ibm_pc_81.png b/src/qt/assets/systemicons/ibm_pc_81.png new file mode 100644 index 000000000..4f398d468 Binary files /dev/null and b/src/qt/assets/systemicons/ibm_pc_81.png differ diff --git a/src/qt/assets/systemicons/ibm_pc_82.png b/src/qt/assets/systemicons/ibm_pc_82.png new file mode 100644 index 000000000..4f398d468 Binary files /dev/null and b/src/qt/assets/systemicons/ibm_pc_82.png differ diff --git a/src/qt/assets/systemicons/ibm_pcjr.png b/src/qt/assets/systemicons/ibm_pcjr.png new file mode 100644 index 000000000..1f3014bb4 Binary files /dev/null and b/src/qt/assets/systemicons/ibm_pcjr.png differ diff --git a/src/qt/assets/systemicons/ibm_ps2_m70.png b/src/qt/assets/systemicons/ibm_ps2_m70.png new file mode 100644 index 000000000..af433ebb3 Binary files /dev/null and b/src/qt/assets/systemicons/ibm_ps2_m70.png differ diff --git a/src/qt/assets/systemicons/ibm_ps2_m80.png b/src/qt/assets/systemicons/ibm_ps2_m80.png new file mode 100644 index 000000000..9df02adff Binary files /dev/null and b/src/qt/assets/systemicons/ibm_ps2_m80.png differ diff --git a/src/qt/assets/systemicons/ibm_psvp_486.png b/src/qt/assets/systemicons/ibm_psvp_486.png new file mode 100644 index 000000000..af5a95675 Binary files /dev/null and b/src/qt/assets/systemicons/ibm_psvp_486.png differ diff --git a/src/qt/assets/systemicons/ibm_psvp_p60.png b/src/qt/assets/systemicons/ibm_psvp_p60.png new file mode 100644 index 000000000..af5a95675 Binary files /dev/null and b/src/qt/assets/systemicons/ibm_psvp_p60.png differ diff --git a/src/qt/assets/systemicons/ibm_xt_82.png b/src/qt/assets/systemicons/ibm_xt_82.png new file mode 100644 index 000000000..4f398d468 Binary files /dev/null and b/src/qt/assets/systemicons/ibm_xt_82.png differ diff --git a/src/qt/assets/systemicons/ibm_xt_86.png b/src/qt/assets/systemicons/ibm_xt_86.png new file mode 100644 index 000000000..4f398d468 Binary files /dev/null and b/src/qt/assets/systemicons/ibm_xt_86.png differ diff --git a/src/qt/assets/systemicons/olivetti_m19.png b/src/qt/assets/systemicons/olivetti_m19.png new file mode 100644 index 000000000..766e335f7 Binary files /dev/null and b/src/qt/assets/systemicons/olivetti_m19.png differ diff --git a/src/qt/assets/systemicons/olivetti_m21.png b/src/qt/assets/systemicons/olivetti_m21.png new file mode 100644 index 000000000..5e0ee4b52 Binary files /dev/null and b/src/qt/assets/systemicons/olivetti_m21.png differ diff --git a/src/qt/assets/systemicons/olivetti_m24.png b/src/qt/assets/systemicons/olivetti_m24.png new file mode 100644 index 000000000..e48356c32 Binary files /dev/null and b/src/qt/assets/systemicons/olivetti_m24.png differ diff --git a/src/qt/assets/systemicons/olivetti_m24sp.png b/src/qt/assets/systemicons/olivetti_m24sp.png new file mode 100644 index 000000000..e48356c32 Binary files /dev/null and b/src/qt/assets/systemicons/olivetti_m24sp.png differ diff --git a/src/qt/assets/systemicons/os_archlinux_x2.png b/src/qt/assets/systemicons/os_archlinux_x2.png new file mode 100644 index 000000000..1b218a76f Binary files /dev/null and b/src/qt/assets/systemicons/os_archlinux_x2.png differ diff --git a/src/qt/assets/systemicons/os_cloud_x2.png b/src/qt/assets/systemicons/os_cloud_x2.png new file mode 100644 index 000000000..9bd42f9ac Binary files /dev/null and b/src/qt/assets/systemicons/os_cloud_x2.png differ diff --git a/src/qt/assets/systemicons/os_debian_x2.png b/src/qt/assets/systemicons/os_debian_x2.png new file mode 100644 index 000000000..a6644c33d Binary files /dev/null and b/src/qt/assets/systemicons/os_debian_x2.png differ diff --git a/src/qt/assets/systemicons/os_dos_x2.png b/src/qt/assets/systemicons/os_dos_x2.png new file mode 100644 index 000000000..b6df56ef5 Binary files /dev/null and b/src/qt/assets/systemicons/os_dos_x2.png differ diff --git a/src/qt/assets/systemicons/os_fedora_x2.png b/src/qt/assets/systemicons/os_fedora_x2.png new file mode 100644 index 000000000..120d247a8 Binary files /dev/null and b/src/qt/assets/systemicons/os_fedora_x2.png differ diff --git a/src/qt/assets/systemicons/os_freebsd_x2.png b/src/qt/assets/systemicons/os_freebsd_x2.png new file mode 100644 index 000000000..dd6f88d41 Binary files /dev/null and b/src/qt/assets/systemicons/os_freebsd_x2.png differ diff --git a/src/qt/assets/systemicons/os_gentoo_x2.png b/src/qt/assets/systemicons/os_gentoo_x2.png new file mode 100644 index 000000000..f27afa5fc Binary files /dev/null and b/src/qt/assets/systemicons/os_gentoo_x2.png differ diff --git a/src/qt/assets/systemicons/os_jrockitve_x2.png b/src/qt/assets/systemicons/os_jrockitve_x2.png new file mode 100644 index 000000000..4283cad5e Binary files /dev/null and b/src/qt/assets/systemicons/os_jrockitve_x2.png differ diff --git a/src/qt/assets/systemicons/os_l4_x2.png b/src/qt/assets/systemicons/os_l4_x2.png new file mode 100644 index 000000000..9fbbaa183 Binary files /dev/null and b/src/qt/assets/systemicons/os_l4_x2.png differ diff --git a/src/qt/assets/systemicons/os_linux22_x2.png b/src/qt/assets/systemicons/os_linux22_x2.png new file mode 100644 index 000000000..0de56653a Binary files /dev/null and b/src/qt/assets/systemicons/os_linux22_x2.png differ diff --git a/src/qt/assets/systemicons/os_linux24_x2.png b/src/qt/assets/systemicons/os_linux24_x2.png new file mode 100644 index 000000000..b3df83b7f Binary files /dev/null and b/src/qt/assets/systemicons/os_linux24_x2.png differ diff --git a/src/qt/assets/systemicons/os_linux26_x2.png b/src/qt/assets/systemicons/os_linux26_x2.png new file mode 100644 index 000000000..8fdf52df7 Binary files /dev/null and b/src/qt/assets/systemicons/os_linux26_x2.png differ diff --git a/src/qt/assets/systemicons/os_linux_x2.png b/src/qt/assets/systemicons/os_linux_x2.png new file mode 100644 index 000000000..d4c2eeebe Binary files /dev/null and b/src/qt/assets/systemicons/os_linux_x2.png differ diff --git a/src/qt/assets/systemicons/os_macosx_x2.png b/src/qt/assets/systemicons/os_macosx_x2.png new file mode 100644 index 000000000..38eb2e5a7 Binary files /dev/null and b/src/qt/assets/systemicons/os_macosx_x2.png differ diff --git a/src/qt/assets/systemicons/os_mandriva_x2.png b/src/qt/assets/systemicons/os_mandriva_x2.png new file mode 100644 index 000000000..a09e9c170 Binary files /dev/null and b/src/qt/assets/systemicons/os_mandriva_x2.png differ diff --git a/src/qt/assets/systemicons/os_netbsd_x2.png b/src/qt/assets/systemicons/os_netbsd_x2.png new file mode 100644 index 000000000..9fa38a7a6 Binary files /dev/null and b/src/qt/assets/systemicons/os_netbsd_x2.png differ diff --git a/src/qt/assets/systemicons/os_netware_x2.png b/src/qt/assets/systemicons/os_netware_x2.png new file mode 100644 index 000000000..4bcc96521 Binary files /dev/null and b/src/qt/assets/systemicons/os_netware_x2.png differ diff --git a/src/qt/assets/systemicons/os_openbsd_x2.png b/src/qt/assets/systemicons/os_openbsd_x2.png new file mode 100644 index 000000000..13ae3a0db Binary files /dev/null and b/src/qt/assets/systemicons/os_openbsd_x2.png differ diff --git a/src/qt/assets/systemicons/os_opensuse_x2.png b/src/qt/assets/systemicons/os_opensuse_x2.png new file mode 100644 index 000000000..4d1696d9b Binary files /dev/null and b/src/qt/assets/systemicons/os_opensuse_x2.png differ diff --git a/src/qt/assets/systemicons/os_oracle_x2.png b/src/qt/assets/systemicons/os_oracle_x2.png new file mode 100644 index 000000000..545e885cb Binary files /dev/null and b/src/qt/assets/systemicons/os_oracle_x2.png differ diff --git a/src/qt/assets/systemicons/os_oraclesolaris_x2.png b/src/qt/assets/systemicons/os_oraclesolaris_x2.png new file mode 100644 index 000000000..8db66abe3 Binary files /dev/null and b/src/qt/assets/systemicons/os_oraclesolaris_x2.png differ diff --git a/src/qt/assets/systemicons/os_os2_other_x2.png b/src/qt/assets/systemicons/os_os2_other_x2.png new file mode 100644 index 000000000..2d37846a0 Binary files /dev/null and b/src/qt/assets/systemicons/os_os2_other_x2.png differ diff --git a/src/qt/assets/systemicons/os_os2ecs_x2.png b/src/qt/assets/systemicons/os_os2ecs_x2.png new file mode 100644 index 000000000..261f9f56c Binary files /dev/null and b/src/qt/assets/systemicons/os_os2ecs_x2.png differ diff --git a/src/qt/assets/systemicons/os_os2warp3_x2.png b/src/qt/assets/systemicons/os_os2warp3_x2.png new file mode 100644 index 000000000..1be5a696c Binary files /dev/null and b/src/qt/assets/systemicons/os_os2warp3_x2.png differ diff --git a/src/qt/assets/systemicons/os_os2warp45_x2.png b/src/qt/assets/systemicons/os_os2warp45_x2.png new file mode 100644 index 000000000..d1a4df0c2 Binary files /dev/null and b/src/qt/assets/systemicons/os_os2warp45_x2.png differ diff --git a/src/qt/assets/systemicons/os_os2warp4_x2.png b/src/qt/assets/systemicons/os_os2warp4_x2.png new file mode 100644 index 000000000..0a81c8759 Binary files /dev/null and b/src/qt/assets/systemicons/os_os2warp4_x2.png differ diff --git a/src/qt/assets/systemicons/os_other_x2.png b/src/qt/assets/systemicons/os_other_x2.png new file mode 100644 index 000000000..9602353c0 Binary files /dev/null and b/src/qt/assets/systemicons/os_other_x2.png differ diff --git a/src/qt/assets/systemicons/os_qnx_x2.png b/src/qt/assets/systemicons/os_qnx_x2.png new file mode 100644 index 000000000..b124cfa6e Binary files /dev/null and b/src/qt/assets/systemicons/os_qnx_x2.png differ diff --git a/src/qt/assets/systemicons/os_redhat_x2.png b/src/qt/assets/systemicons/os_redhat_x2.png new file mode 100644 index 000000000..a756e8aac Binary files /dev/null and b/src/qt/assets/systemicons/os_redhat_x2.png differ diff --git a/src/qt/assets/systemicons/os_solaris_x2.png b/src/qt/assets/systemicons/os_solaris_x2.png new file mode 100644 index 000000000..2dfd2ac74 Binary files /dev/null and b/src/qt/assets/systemicons/os_solaris_x2.png differ diff --git a/src/qt/assets/systemicons/os_turbolinux_x2.png b/src/qt/assets/systemicons/os_turbolinux_x2.png new file mode 100644 index 000000000..4d5ee4ab1 Binary files /dev/null and b/src/qt/assets/systemicons/os_turbolinux_x2.png differ diff --git a/src/qt/assets/systemicons/os_ubuntu_x2.png b/src/qt/assets/systemicons/os_ubuntu_x2.png new file mode 100644 index 000000000..9b6302b37 Binary files /dev/null and b/src/qt/assets/systemicons/os_ubuntu_x2.png differ diff --git a/src/qt/assets/systemicons/os_win10_x2.png b/src/qt/assets/systemicons/os_win10_x2.png new file mode 100644 index 000000000..1d6e81392 Binary files /dev/null and b/src/qt/assets/systemicons/os_win10_x2.png differ diff --git a/src/qt/assets/systemicons/os_win2k3_x2.png b/src/qt/assets/systemicons/os_win2k3_x2.png new file mode 100644 index 000000000..45bec005d Binary files /dev/null and b/src/qt/assets/systemicons/os_win2k3_x2.png differ diff --git a/src/qt/assets/systemicons/os_win2k8_x2.png b/src/qt/assets/systemicons/os_win2k8_x2.png new file mode 100644 index 000000000..d97a2789d Binary files /dev/null and b/src/qt/assets/systemicons/os_win2k8_x2.png differ diff --git a/src/qt/assets/systemicons/os_win2k_x2.png b/src/qt/assets/systemicons/os_win2k_x2.png new file mode 100644 index 000000000..a773288ed Binary files /dev/null and b/src/qt/assets/systemicons/os_win2k_x2.png differ diff --git a/src/qt/assets/systemicons/os_win31_x2.png b/src/qt/assets/systemicons/os_win31_x2.png new file mode 100644 index 000000000..5ca2005d6 Binary files /dev/null and b/src/qt/assets/systemicons/os_win31_x2.png differ diff --git a/src/qt/assets/systemicons/os_win7_x2.png b/src/qt/assets/systemicons/os_win7_x2.png new file mode 100644 index 000000000..c8ce57a2b Binary files /dev/null and b/src/qt/assets/systemicons/os_win7_x2.png differ diff --git a/src/qt/assets/systemicons/os_win81_x2.png b/src/qt/assets/systemicons/os_win81_x2.png new file mode 100644 index 000000000..07131ed6c Binary files /dev/null and b/src/qt/assets/systemicons/os_win81_x2.png differ diff --git a/src/qt/assets/systemicons/os_win8_x2.png b/src/qt/assets/systemicons/os_win8_x2.png new file mode 100644 index 000000000..ff94c2dd1 Binary files /dev/null and b/src/qt/assets/systemicons/os_win8_x2.png differ diff --git a/src/qt/assets/systemicons/os_win95_x2.png b/src/qt/assets/systemicons/os_win95_x2.png new file mode 100644 index 000000000..efd62799e Binary files /dev/null and b/src/qt/assets/systemicons/os_win95_x2.png differ diff --git a/src/qt/assets/systemicons/os_win98_x2.png b/src/qt/assets/systemicons/os_win98_x2.png new file mode 100644 index 000000000..c8fa4e7bb Binary files /dev/null and b/src/qt/assets/systemicons/os_win98_x2.png differ diff --git a/src/qt/assets/systemicons/os_win_other_x2.png b/src/qt/assets/systemicons/os_win_other_x2.png new file mode 100644 index 000000000..fac95889f Binary files /dev/null and b/src/qt/assets/systemicons/os_win_other_x2.png differ diff --git a/src/qt/assets/systemicons/os_winme_x2.png b/src/qt/assets/systemicons/os_winme_x2.png new file mode 100644 index 000000000..1c268c84b Binary files /dev/null and b/src/qt/assets/systemicons/os_winme_x2.png differ diff --git a/src/qt/assets/systemicons/os_winnt4_x2.png b/src/qt/assets/systemicons/os_winnt4_x2.png new file mode 100644 index 000000000..c3352abcd Binary files /dev/null and b/src/qt/assets/systemicons/os_winnt4_x2.png differ diff --git a/src/qt/assets/systemicons/os_winvista_x2.png b/src/qt/assets/systemicons/os_winvista_x2.png new file mode 100644 index 000000000..7b633b79f Binary files /dev/null and b/src/qt/assets/systemicons/os_winvista_x2.png differ diff --git a/src/qt/assets/systemicons/os_winxp_x2.png b/src/qt/assets/systemicons/os_winxp_x2.png new file mode 100644 index 000000000..b97e6b51d Binary files /dev/null and b/src/qt/assets/systemicons/os_winxp_x2.png differ diff --git a/src/qt/assets/systemicons/os_xandros_x2.png b/src/qt/assets/systemicons/os_xandros_x2.png new file mode 100644 index 000000000..23de5ca91 Binary files /dev/null and b/src/qt/assets/systemicons/os_xandros_x2.png differ diff --git a/src/qt/assets/systemicons/pb_bora_pro.png b/src/qt/assets/systemicons/pb_bora_pro.png new file mode 100644 index 000000000..6aaaf9d26 Binary files /dev/null and b/src/qt/assets/systemicons/pb_bora_pro.png differ diff --git a/src/qt/assets/systemicons/pb_pb410.png b/src/qt/assets/systemicons/pb_pb410.png new file mode 100644 index 000000000..c78c0496b Binary files /dev/null and b/src/qt/assets/systemicons/pb_pb410.png differ diff --git a/src/qt/assets/systemicons/pb_pb640.png b/src/qt/assets/systemicons/pb_pb640.png new file mode 100644 index 000000000..d0be550f1 Binary files /dev/null and b/src/qt/assets/systemicons/pb_pb640.png differ diff --git a/src/qt/assets/systemicons/pb_pb680.png b/src/qt/assets/systemicons/pb_pb680.png new file mode 100644 index 000000000..a697d5dd0 Binary files /dev/null and b/src/qt/assets/systemicons/pb_pb680.png differ diff --git a/src/qt/assets/systemicons/tandy_1000.png b/src/qt/assets/systemicons/tandy_1000.png new file mode 100644 index 000000000..b50f2c1e6 Binary files /dev/null and b/src/qt/assets/systemicons/tandy_1000.png differ diff --git a/src/qt/assets/systemicons/tandy_1000_hx.png b/src/qt/assets/systemicons/tandy_1000_hx.png new file mode 100644 index 000000000..b770a6b7c Binary files /dev/null and b/src/qt/assets/systemicons/tandy_1000_hx.png differ diff --git a/src/qt/assets/systemicons/tandy_1000_sl2.png b/src/qt/assets/systemicons/tandy_1000_sl2.png new file mode 100644 index 000000000..b7feae92a Binary files /dev/null and b/src/qt/assets/systemicons/tandy_1000_sl2.png differ diff --git a/src/qt/assets/systemicons/toshiba_t1000.png b/src/qt/assets/systemicons/toshiba_t1000.png new file mode 100644 index 000000000..a2dbfc382 Binary files /dev/null and b/src/qt/assets/systemicons/toshiba_t1000.png differ diff --git a/src/qt/assets/systemicons/toshiba_t1200.png b/src/qt/assets/systemicons/toshiba_t1200.png new file mode 100644 index 000000000..8c3cf0c37 Binary files /dev/null and b/src/qt/assets/systemicons/toshiba_t1200.png differ diff --git a/src/qt/assets/systemicons/toshiba_t1200_hdd.png b/src/qt/assets/systemicons/toshiba_t1200_hdd.png new file mode 100644 index 000000000..8c3cf0c37 Binary files /dev/null and b/src/qt/assets/systemicons/toshiba_t1200_hdd.png differ diff --git a/src/qt/dummy_cdrom_ioctl.c b/src/qt/dummy_cdrom_ioctl.c index bddfabb5b..8dffc6758 100644 --- a/src/qt/dummy_cdrom_ioctl.c +++ b/src/qt/dummy_cdrom_ioctl.c @@ -162,6 +162,7 @@ ioctl_is_empty(const void *local) return 1; } +#if 0 static int ioctl_ext_medium_changed(UNUSED(void *local)) { @@ -174,6 +175,7 @@ ioctl_ext_medium_changed(UNUSED(void *local)) return ret; } +#endif static void ioctl_close(void *local) diff --git a/src/qt/icons/browse.ico b/src/qt/icons/browse.ico new file mode 100644 index 000000000..8a947ae9d Binary files /dev/null and b/src/qt/icons/browse.ico differ diff --git a/src/qt/icons/caps_lock_off.ico b/src/qt/icons/caps_lock_off.ico new file mode 100644 index 000000000..6895c735c Binary files /dev/null and b/src/qt/icons/caps_lock_off.ico differ diff --git a/src/qt/icons/caps_lock_on.ico b/src/qt/icons/caps_lock_on.ico new file mode 100644 index 000000000..2cfd48aad Binary files /dev/null and b/src/qt/icons/caps_lock_on.ico differ diff --git a/src/qt/icons/cartridge_image.ico b/src/qt/icons/cartridge_image.ico new file mode 100644 index 000000000..4f01aa1a9 Binary files /dev/null and b/src/qt/icons/cartridge_image.ico differ diff --git a/src/qt/icons/cassette_image.ico b/src/qt/icons/cassette_image.ico new file mode 100644 index 000000000..fa6358050 Binary files /dev/null and b/src/qt/icons/cassette_image.ico differ diff --git a/src/qt/icons/cdrom_nomedia.ico b/src/qt/icons/cdrom_nomedia.ico new file mode 100644 index 000000000..ca3c58920 Binary files /dev/null and b/src/qt/icons/cdrom_nomedia.ico differ diff --git a/src/qt/icons/eject.ico b/src/qt/icons/eject.ico new file mode 100644 index 000000000..1bfead4d6 Binary files /dev/null and b/src/qt/icons/eject.ico differ diff --git a/src/qt/icons/export.ico b/src/qt/icons/export.ico new file mode 100644 index 000000000..5076182dc Binary files /dev/null and b/src/qt/icons/export.ico differ diff --git a/src/qt/icons/fast_forward.ico b/src/qt/icons/fast_forward.ico new file mode 100644 index 000000000..6bc5eeaff Binary files /dev/null and b/src/qt/icons/fast_forward.ico differ diff --git a/src/qt/icons/floppy_35_image.ico b/src/qt/icons/floppy_35_image.ico new file mode 100644 index 000000000..d27b4be02 Binary files /dev/null and b/src/qt/icons/floppy_35_image.ico differ diff --git a/src/qt/icons/floppy_525_image.ico b/src/qt/icons/floppy_525_image.ico new file mode 100644 index 000000000..ae3a4d8a4 Binary files /dev/null and b/src/qt/icons/floppy_525_image.ico differ diff --git a/src/qt/icons/green-square-16.png b/src/qt/icons/green-square-16.png new file mode 100644 index 000000000..cb42c38eb Binary files /dev/null and b/src/qt/icons/green-square-16.png differ diff --git a/src/qt/icons/kana_lock_off.ico b/src/qt/icons/kana_lock_off.ico new file mode 100644 index 000000000..27c9b88c2 Binary files /dev/null and b/src/qt/icons/kana_lock_off.ico differ diff --git a/src/qt/icons/kana_lock_on.ico b/src/qt/icons/kana_lock_on.ico new file mode 100644 index 000000000..ec171b52b Binary files /dev/null and b/src/qt/icons/kana_lock_on.ico differ diff --git a/src/qt/icons/mo_image.ico b/src/qt/icons/mo_image.ico new file mode 100644 index 000000000..c445ce385 Binary files /dev/null and b/src/qt/icons/mo_image.ico differ diff --git a/src/qt/icons/new.ico b/src/qt/icons/new.ico new file mode 100644 index 000000000..b3e0c16b0 Binary files /dev/null and b/src/qt/icons/new.ico differ diff --git a/src/qt/icons/num_lock_off.ico b/src/qt/icons/num_lock_off.ico new file mode 100644 index 000000000..5b14da1d4 Binary files /dev/null and b/src/qt/icons/num_lock_off.ico differ diff --git a/src/qt/icons/num_lock_on.ico b/src/qt/icons/num_lock_on.ico new file mode 100644 index 000000000..0dd08d7ae Binary files /dev/null and b/src/qt/icons/num_lock_on.ico differ diff --git a/src/qt/icons/pause-16.png b/src/qt/icons/pause-16.png new file mode 100644 index 000000000..375780232 Binary files /dev/null and b/src/qt/icons/pause-16.png differ diff --git a/src/qt/icons/play-16.png b/src/qt/icons/play-16.png new file mode 100644 index 000000000..bde40f503 Binary files /dev/null and b/src/qt/icons/play-16.png differ diff --git a/src/qt/icons/zip.ico b/src/qt/icons/rdisk.ico similarity index 100% rename from src/qt/icons/zip.ico rename to src/qt/icons/rdisk.ico diff --git a/src/qt/icons/zip_disabled.ico b/src/qt/icons/rdisk_disabled.ico similarity index 100% rename from src/qt/icons/zip_disabled.ico rename to src/qt/icons/rdisk_disabled.ico diff --git a/src/qt/icons/rdisk_image.ico b/src/qt/icons/rdisk_image.ico new file mode 100644 index 000000000..82fd868fd Binary files /dev/null and b/src/qt/icons/rdisk_image.ico differ diff --git a/src/qt/icons/record.ico b/src/qt/icons/record.ico new file mode 100644 index 000000000..357563594 Binary files /dev/null and b/src/qt/icons/record.ico differ diff --git a/src/qt/icons/red-power-16.png b/src/qt/icons/red-power-16.png new file mode 100644 index 000000000..c90ef491f Binary files /dev/null and b/src/qt/icons/red-power-16.png differ diff --git a/src/qt/icons/red-square-16.png b/src/qt/icons/red-square-16.png new file mode 100644 index 000000000..32faa7cdc Binary files /dev/null and b/src/qt/icons/red-square-16.png differ diff --git a/src/qt/icons/rewind.ico b/src/qt/icons/rewind.ico new file mode 100644 index 000000000..b18c1a66d Binary files /dev/null and b/src/qt/icons/rewind.ico differ diff --git a/src/qt/icons/run.ico b/src/qt/icons/run.ico index 90a7f2886..c088eb59d 100644 Binary files a/src/qt/icons/run.ico and b/src/qt/icons/run.ico differ diff --git a/src/qt/icons/scroll_lock_off.ico b/src/qt/icons/scroll_lock_off.ico new file mode 100644 index 000000000..85cb09ec6 Binary files /dev/null and b/src/qt/icons/scroll_lock_off.ico differ diff --git a/src/qt/icons/scroll_lock_on.ico b/src/qt/icons/scroll_lock_on.ico new file mode 100644 index 000000000..33476406a Binary files /dev/null and b/src/qt/icons/scroll_lock_on.ico differ diff --git a/src/qt/icons/stop-16.png b/src/qt/icons/stop-16.png new file mode 100644 index 000000000..d73cad140 Binary files /dev/null and b/src/qt/icons/stop-16.png differ diff --git a/src/qt/icons/superdisk.ico b/src/qt/icons/superdisk.ico new file mode 100644 index 000000000..ac5cc5fb0 Binary files /dev/null and b/src/qt/icons/superdisk.ico differ diff --git a/src/qt/icons/superdisk_disabled.ico b/src/qt/icons/superdisk_disabled.ico new file mode 100644 index 000000000..e4fa80370 Binary files /dev/null and b/src/qt/icons/superdisk_disabled.ico differ diff --git a/src/qt/icons/superdisk_image.ico b/src/qt/icons/superdisk_image.ico new file mode 100644 index 000000000..b8c854fd2 Binary files /dev/null and b/src/qt/icons/superdisk_image.ico differ diff --git a/src/qt/icons/write_protected.ico b/src/qt/icons/write_protected.ico new file mode 100644 index 000000000..f4ba2aa7a Binary files /dev/null and b/src/qt/icons/write_protected.ico differ diff --git a/src/qt/icons/yellow-square-16.png b/src/qt/icons/yellow-square-16.png new file mode 100644 index 000000000..197cf394e Binary files /dev/null and b/src/qt/icons/yellow-square-16.png differ diff --git a/src/qt/languages/86box.pot b/src/qt/languages/86box.pot index 6e6dd3fc3..030ee3af8 100644 --- a/src/qt/languages/86box.pot +++ b/src/qt/languages/86box.pot @@ -27,7 +27,10 @@ msgstr "" msgid "&Pause" msgstr "" -msgid "E&xit..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" msgstr "" msgid "&View" @@ -60,7 +63,7 @@ msgstr "" msgid "&VNC" msgstr "" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "" msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "" msgid "&8x" msgstr "" -msgid "Filter method" +msgid "Fi<er method" msgstr "" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "" msgid "RGB &Color" msgstr "" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "" @@ -384,6 +393,15 @@ msgstr "" msgid "Dynamic Recompiler" msgstr "" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "" @@ -399,6 +417,9 @@ msgstr "" msgid "XGA Graphics" msgstr "" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "" @@ -498,10 +519,10 @@ msgstr "" msgid "Parallel port 4" msgstr "" -msgid "HD Controller:" +msgid "FD Controller:" msgstr "" -msgid "FD Controller:" +msgid "CD-ROM Controller:" msgstr "" msgid "Tertiary IDE Controller" @@ -510,6 +531,9 @@ msgstr "" msgid "Quaternary IDE Controller" msgstr "" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "" @@ -531,6 +555,9 @@ msgstr "" msgid "Hard disks:" msgstr "" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "" @@ -588,7 +615,7 @@ msgstr "" msgid "MO drives:" msgstr "" -msgid "ZIP drives:" +msgid "Removable disk drives:" msgstr "" msgid "ZIP 250" @@ -600,6 +627,9 @@ msgstr "" msgid "ISA Memory Expansion" msgstr "" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "" @@ -612,6 +642,15 @@ msgstr "" msgid "Card 4:" msgstr "" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "" @@ -630,16 +669,19 @@ msgstr "" msgid " - PAUSED" msgstr "" -msgid "Press Ctrl+Alt+PgDn to return to windowed mode." -msgstr "" - msgid "Speed" msgstr "" -msgid "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" msgstr "" -msgid "ZIP images" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." @@ -780,12 +822,39 @@ msgstr "" msgid "CH Flightstick Pro" msgstr "" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "" msgid "Thrustmaster Flight Control System" msgstr "" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "" @@ -795,6 +864,9 @@ msgstr "" msgid "Floppy %1 (%2): %3" msgstr "" +msgid "&Floppy %1 (%2): %3" +msgstr "" + msgid "Advanced sector images" msgstr "" @@ -816,6 +888,9 @@ msgstr "" msgid "MO %1 (%2): %3" msgstr "" +msgid "&MO %1 (%2): %3" +msgstr "" + msgid "MO images" msgstr "" @@ -864,9 +939,6 @@ msgstr "" msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "" -msgid "Entering fullscreen mode" -msgstr "" - msgid "Don't show this message again" msgstr "" @@ -903,12 +975,18 @@ msgstr "" msgid "Cassette: %1" msgstr "" +msgid "C&assette: %1" +msgstr "" + msgid "Cassette images" msgstr "" msgid "Cartridge %1: %2" msgstr "" +msgid "Car&tridge %1: %2" +msgstr "" + msgid "Cartridge images" msgstr "" @@ -930,6 +1008,9 @@ msgstr "" msgid "ACPI shutdown" msgstr "" +msgid "ACP&I shutdown" +msgstr "" + msgid "Hard disk (%1)" msgstr "" @@ -1077,6 +1158,9 @@ msgstr "" msgid "CD-ROM %1 (%2): %3" msgstr "" +msgid "&CD-ROM %1 (%2): %3" +msgstr "" + msgid "160 KB" msgstr "" @@ -1215,40 +1299,40 @@ msgstr "" msgid "List of MCA devices:" msgstr "" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "" msgid "Qt (OpenGL &ES)" msgstr "" -msgid "About Qt" +msgid "About &Qt" msgstr "" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "" -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "" -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "" -msgid "Cursor/Puck" +msgid "&Cursor/Puck" msgstr "" -msgid "Pen" +msgid "&Pen" msgstr "" -msgid "Host CD/DVD Drive (%1:)" +msgid "&Host CD/DVD Drive (%1:)" msgstr "" msgid "&Connected" msgstr "" -msgid "Clear image history" +msgid "Clear image &history" msgstr "" msgid "Create..." @@ -1266,6 +1350,9 @@ msgstr "" msgid "NIC %1 (%2) %3" msgstr "" +msgid "&NIC %1 (%2) %3" +msgstr "" + msgid "Render behavior" msgstr "" @@ -1305,7 +1392,7 @@ msgstr "" msgid "\nFalling back to software rendering." msgstr "" -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" msgstr "" msgid "This machine might have been moved or copied." @@ -1371,7 +1458,25 @@ msgstr "" msgid "Serial port passthrough 4" msgstr "" -msgid "Renderer options..." +msgid "Renderer &options..." +msgstr "" + +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" msgstr "" msgid "Logitech/Microsoft Bus Mouse" @@ -1383,18 +1488,30 @@ msgstr "" msgid "Mouse Systems Serial Mouse" msgstr "" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "" msgid "PS/2 Mouse" msgstr "" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "" @@ -1419,12 +1536,54 @@ msgstr "" msgid "MIDI Input Device" msgstr "" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" +msgstr "" + +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" msgstr "" msgid "Enable BIOS extension ROM Writes" msgstr "" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "" @@ -1434,6 +1593,18 @@ msgstr "" msgid "BIOS Revision" msgstr "" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "" @@ -1449,6 +1620,18 @@ msgstr "" msgid "BIOS size" msgstr "" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "" @@ -1524,6 +1707,9 @@ msgstr "" msgid "Interpolation Method" msgstr "" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "" @@ -1611,6 +1797,12 @@ msgstr "" msgid "Enable Game port" msgstr "" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "" @@ -1623,6 +1815,9 @@ msgstr "" msgid "SB Address" msgstr "" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "" @@ -1707,9 +1902,15 @@ msgstr "" msgid "Blend" msgstr "" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "" @@ -1752,6 +1953,33 @@ msgstr "" msgid "EMS mode" msgstr "" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "" @@ -1770,10 +1998,10 @@ msgstr "" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "" -msgid "64 kB starting from F0000" +msgid "64 KB starting from F0000" msgstr "" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" msgstr "" msgid "Sine" @@ -1908,6 +2136,15 @@ msgstr "" msgid "Linear interpolation" msgstr "" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "" @@ -1941,6 +2178,9 @@ msgstr "" msgid "Gray" msgstr "" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "" @@ -1956,6 +2196,12 @@ msgstr "" msgid "Bochs latest" msgstr "" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "" @@ -2037,6 +2283,9 @@ msgstr "" msgid "Named Pipe (Server)" msgstr "" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "" @@ -2112,9 +2361,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2162,3 +2408,75 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 4851106cd..8faeead0e 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Pausa" -msgid "E&xit..." -msgstr "&Sortir ..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "&Sortir" msgid "&View" msgstr "&Vista" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "E&specificar dimensions ..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "&Mètode de filtrat" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "&Tipus de pantalla VGA" msgid "RGB &Color" msgstr "RGB &Color" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "RGB &Grisos" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "Monitor & Ambre" @@ -384,6 +393,15 @@ msgstr "Activat (UTC)" msgid "Dynamic Recompiler" msgstr "Recopilador Dinàmic" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Vídeo:" @@ -399,6 +417,9 @@ msgstr "Gràfics IBM 8514/A" msgid "XGA Graphics" msgstr "Gràfics XGA" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Ratolí:" @@ -498,18 +519,21 @@ 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 "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "Controlador IDE terciari" msgid "Quaternary IDE Controller" msgstr "Controlador IDE quaternari" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Casset" msgid "Hard disks:" msgstr "Discs durs:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "&Nou ..." @@ -588,8 +615,8 @@ msgstr "Unitats de CD-ROM:" msgid "MO drives:" msgstr "Unitats MO:" -msgid "ZIP drives:" -msgstr "Unitats ZIP:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA RTC:" msgid "ISA Memory Expansion" msgstr "Expansió de memòria ISA" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Targeta 1:" @@ -612,6 +642,15 @@ msgstr "Targeta 3:" msgid "Card 4:" msgstr "Targeta 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "Dispositiu ISABugger" @@ -630,17 +669,20 @@ msgstr "Error fatal" msgid " - PAUSED" msgstr " - EN PAUSA" -msgid "Press %s to return to windowed mode." -msgstr "Premeu %s per tornar al mode de finestra." - msgid "Speed" msgstr "Velocitat" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "Imatges ZIP" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" 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\"." @@ -717,11 +759,11 @@ msgstr "Altres perifèrics" msgid "Click to capture mouse" msgstr "Feu clic per capturar el ratolí" -msgid "Press %s to release mouse" -msgstr "Premeu %s per alliberar el ratolí" +msgid "Press %1 to release mouse" +msgstr "Premeu %1 per alliberar el ratolí" -msgid "Press %s or middle button to release mouse" -msgstr "Premeu %s o el botó central per alliberar el ratolí" +msgid "Press %1 or middle button to release mouse" +msgstr "Premeu %1 o el botó central per alliberar el ratolí" msgid "Bus" msgstr "Bus" @@ -780,12 +822,39 @@ msgstr "Joystick de 4 eixes, 4 botons" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Cap" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Disquet %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Disquet %1 (%2): %3" + msgid "Advanced sector images" msgstr "Imatges avançates del sector" @@ -816,6 +888,9 @@ msgstr "No es pot inicialitzar GhostPCL" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "Imatges MO" @@ -864,9 +939,6 @@ msgstr "%1 és necessària per a la conversió automàtica de fitxers PostScript msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 és necessària per a la conversió automàtica de fitxers PCL a PDF.\n\nQualsevol document enviat a la impressora genèrica PCL es desarà com a fitxer Printer Command Language (.pcl)." -msgid "Entering fullscreen mode" -msgstr "Entrant en mode pantalla completa" - msgid "Don't show this message again" msgstr "No mostreu més aquest missatge" @@ -903,12 +975,18 @@ msgstr "Continuar" msgid "Cassette: %1" msgstr "Casset: %1" +msgid "C&assette: %1" +msgstr "C&asset: %1" + msgid "Cassette images" msgstr "Imatges de casset" msgid "Cartridge %1: %2" msgstr "Cartutx %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Car&tutx %1: %2" + msgid "Cartridge images" msgstr "Imatges de cartutx" @@ -930,6 +1008,9 @@ msgstr "Reinicialització completa" msgid "ACPI shutdown" msgstr "Apagada ACPI" +msgid "ACP&I shutdown" +msgstr "Apagada ACP&I" + msgid "Hard disk (%1)" msgstr "Disc dur (%1)" @@ -1077,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 KB" @@ -1215,41 +1299,41 @@ msgstr "Dispositius MCA" msgid "List of MCA devices:" msgstr "Lista de dispositius MCA:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Eina de tauleta" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "Quant a Qt" +msgid "About &Qt" +msgstr "Quant a &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "Dispositius MCA ..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Mostrar monitors no primaris" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Obrir la carpeta de captures de pantalla ..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Apliqueu el mode d’estirament de pantalla completa en màxima" -msgid "Cursor/Puck" -msgstr "Cursor/Puck" +msgid "&Cursor/Puck" +msgstr "&Cursor/Puck" -msgid "Pen" -msgstr "Ploma" +msgid "&Pen" +msgstr "&Ploma" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Unitat CD/DVD d'amfitrió (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Unitat CD/DVD d'amfitrió (%1:)" msgid "&Connected" msgstr "&Connectat" -msgid "Clear image history" -msgstr "Esborrar la història de imatges" +msgid "Clear image &history" +msgstr "Esborrar la &història de imatges" msgid "Create..." msgstr "Crear ..." @@ -1266,6 +1350,9 @@ msgstr "Controlador nul" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "Comportament del renderitzador" @@ -1305,8 +1392,8 @@ msgstr "Error en inicialitzar OpenGL" msgid "\nFalling back to software rendering." msgstr "\nTornant al renderitzador software." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Quan seleccioneu imatges de suports (CD-ROM, disquet, etc.), el diàleg obert s’iniciarà al mateix directori que el fitxer de configuració 86Box. Aquesta configuració només farà una diferència en les macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Quan seleccioneu imatges de suports (CD-ROM, disquet, etc.), el diàleg obert s’iniciarà al mateix directori que el fitxer de configuració 86Box. Aquesta configuració només farà una diferència en les macOS.

" msgid "This machine might have been moved or copied." msgstr "Aquesta màquina podria haver estat moguda o copiada." @@ -1371,9 +1458,27 @@ msgstr "Pas del port sèrie 3" msgid "Serial port passthrough 4" msgstr "Pas del port sèrie 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Opcions del renderitzador ..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Ratolí bus Logitech/Microsoft" @@ -1383,18 +1488,30 @@ msgstr "Ratolí bus Microsoft (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Ratolí sèrie Mouse Systems" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Ratolí sèrie Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Ratolí sèrie Logitech" msgid "PS/2 Mouse" msgstr "Ratolí PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (sèrie)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Mòdem estàndard, complint els Hayes" @@ -1419,12 +1536,54 @@ msgstr "MIDI de sistema" msgid "MIDI Input Device" msgstr "Dispositiu d'entrada MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "Adreça de BIOS" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "Activar les escrits a la ROM extensor de BIOS" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Adreça" @@ -1434,6 +1593,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "Revisió de la BIOS" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Traduir 26 -> 17" @@ -1449,6 +1620,18 @@ msgstr "Colors invertits" msgid "BIOS size" msgstr "Grandària de la BIOS" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "Mapa C0000-C7FFF com UMB" @@ -1524,6 +1707,9 @@ msgstr "Nivell de reverberació" msgid "Interpolation Method" msgstr "Mètode d'interpolació" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Guany de sortida de reverberació" @@ -1611,6 +1797,12 @@ msgstr "DMA baix" msgid "Enable Game port" msgstr "Activar port de joc" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Mòdul Surround" @@ -1623,6 +1815,9 @@ msgstr "Activar la interrupció del codec en la configuració del CODEC (necessa msgid "SB Address" msgstr "Adreça de SB" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "IRQ de WSS" @@ -1707,9 +1902,15 @@ msgstr "Tipus de RAMDAC" msgid "Blend" msgstr "Barrejar" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Filtratge bilineal" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Dithering" @@ -1752,6 +1953,33 @@ msgstr "Velocitat de transferència" msgid "EMS mode" msgstr "Mode EMS" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Adreça per a > 2 MB" @@ -1770,11 +1998,11 @@ msgstr "Sempre a la velocitat seleccionada" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Configuració de la BIOS + Hotkeys (desactivat durant el POST)" -msgid "64 kB starting from F0000" -msgstr "64 kB a partir de F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB a partir de F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB a partir de E0000 (MSB de adreça invertit, els darrers 64KB primer)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB a partir de E0000 (MSB de adreça invertit, els darrers 64 KB primer)" msgid "Sine" msgstr "Sinusoidal" @@ -1840,7 +2068,7 @@ msgid "2 MB" msgstr "2 MB" msgid "8 MB" -msgstr " 8 MB" +msgstr "8 MB" msgid "28 MB" msgstr "28 MB" @@ -1908,6 +2136,15 @@ msgstr "Interpolació sRGB" msgid "Linear interpolation" msgstr "Interpolació lineal" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2178,9 @@ msgstr "Ambre" msgid "Gray" msgstr "Gris" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Color" @@ -1956,6 +2196,12 @@ msgstr "Altres idiomes" msgid "Bochs latest" msgstr "Bochs més recent" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Monocrom no interlat" @@ -2037,6 +2283,9 @@ msgstr "Taxa de baud de pas" msgid "Named Pipe (Server)" msgstr "Pipe anomenat (servidor)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "Pas del port sèrie amfitrió" @@ -2082,6 +2331,12 @@ msgstr "Clon IBM 8514/A (ISA)" msgid "Vendor" msgstr "Frabricant" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "Expansió de memòria genèrica PC/XT" @@ -2106,9 +2361,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2156,3 +2408,87 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Controlador de HD:" + +#~ msgid "ZIP drives:" +#~ msgstr "Unitats ZIP:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "Imatges ZIP" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 352fafc31..4f26da1cd 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -27,7 +27,10 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "P&ozastavit" -msgid "E&xit..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" msgstr "&Ukončit" msgid "&View" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "&Zadat velikost..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "Metoda &filtrování" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "&Typ VGA monitoru" msgid "RGB &Color" msgstr "RGB &barevný" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "&Odstíny šedi" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "&Jantarová obrazovka" @@ -384,6 +393,15 @@ msgstr "Zapnuta (UTC)" msgid "Dynamic Recompiler" msgstr "Dynamický překladač" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Grafika:" @@ -399,6 +417,9 @@ msgstr "Grafika IBM 8514/A" msgid "XGA Graphics" msgstr "Grafika XGA" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Myš:" @@ -498,18 +519,21 @@ msgstr "Povolit port LPT3" msgid "Parallel port 4" msgstr "Povolit port LPT4" -msgid "HD Controller:" -msgstr "Řadič disku:" - msgid "FD Controller:" msgstr "Disketový řadič:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "Třetí řadič IDE" msgid "Quaternary IDE Controller" msgstr "Čtvrtý řadič IDE" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Kazeta" msgid "Hard disks:" msgstr "Pevné disky:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "&Nový..." @@ -588,8 +615,8 @@ msgstr "Mechaniky CD-ROM:" msgid "MO drives:" msgstr "Magnetooptické mechaniky:" -msgid "ZIP drives:" -msgstr "Mechaniky ZIP:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA hodiny:" msgid "ISA Memory Expansion" msgstr "ISA rozšíření paměti" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Karta 1:" @@ -612,6 +642,15 @@ msgstr "Karta 3:" msgid "Card 4:" msgstr "Karta 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "Zařízení ISABugger" @@ -630,17 +669,20 @@ msgstr "Kritická chyba" msgid " - PAUSED" msgstr " - POZASTAVENO" -msgid "Press %s to return to windowed mode." -msgstr "Stiskněte %s pro návrat z režimu celé obrazovky." - msgid "Speed" msgstr "Rychlost" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "Obrazy ZIP disků" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "86Box nenalezl žádné použitelné image pamětí ROM.\n\nStáhněte sadu obrazů ROM a extrahujte ji do složky \"roms\"." @@ -717,11 +759,11 @@ msgstr "Jiné příslušenství" msgid "Click to capture mouse" msgstr "Klikněte pro zabraní myši" -msgid "Press %s to release mouse" -msgstr "Stiskněte %s pro uvolnění myši" +msgid "Press %1 to release mouse" +msgstr "Stiskněte %1 pro uvolnění myši" -msgid "Press %s or middle button to release mouse" -msgstr "Stiskněte %s nebo prostřední tlačítko pro uvolnění myši" +msgid "Press %1 or middle button to release mouse" +msgstr "Stiskněte %1 nebo prostřední tlačítko pro uvolnění myši" msgid "Bus" msgstr "Sběrnice" @@ -780,12 +822,39 @@ msgstr "4osový, 4tlačítkový joystick" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Žadné" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Disketová mechanika %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Disketová mechanika %1 (%2): %3" + msgid "Advanced sector images" msgstr "Rozšířené sektorové obrazy" @@ -816,6 +888,9 @@ msgstr "Nastala chyba při inicializaci knihovny GhostPCL" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "Obrazy MO" @@ -864,9 +939,6 @@ msgstr "%1 je potřeba pro automatický převod PostScript dokumentů do PDF.\n\ msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 je potřeba pro automatický převod PCL dokumentů do PDF.\n\nJakékoliv dokumenty vytisknuté přes obecnou PCL-ovou tiskárnu budou uloženy jako Printer Command Language (.pcl) soubory." -msgid "Entering fullscreen mode" -msgstr "Vstup do režimu celé obrazovky" - msgid "Don't show this message again" msgstr "Nezobrazovat dále tuto zprávu" @@ -903,12 +975,18 @@ msgstr "Pokračovat" msgid "Cassette: %1" msgstr "Kazeta: %1" +msgid "C&assette: %1" +msgstr "K&azeta: %1" + msgid "Cassette images" msgstr "Kazetové nahrávky" msgid "Cartridge %1: %2" msgstr "Cartridge %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Car&tridge %1: %2" + msgid "Cartridge images" msgstr "Obrazy cartridge" @@ -930,6 +1008,9 @@ msgstr "Resetovat" msgid "ACPI shutdown" msgstr "Vypnout skrze rozhraní ACPI" +msgid "ACP&I shutdown" +msgstr "Vypnout skrze rozhraní ACP&I" + msgid "Hard disk (%1)" msgstr "Pevný disk (%1)" @@ -1077,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 KB" @@ -1215,41 +1299,41 @@ msgstr "Zařízení MCA" msgid "List of MCA devices:" msgstr "Seznam zařízení MCA:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Nástroj pro tablety" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "O programu Qt" +msgid "About &Qt" +msgstr "O programu &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "Zařízení MCA ..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Zobrazit neprimární monitory" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Otevři složku screenshots..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Použití režimu roztá&hnutí při celé obrazovce při maximalizaci" -msgid "Cursor/Puck" -msgstr "Kurzor/Puk" +msgid "&Cursor/Puck" +msgstr "&Kurzor/Puk" -msgid "Pen" -msgstr "Pero" +msgid "&Pen" +msgstr "&Pero" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Jednotka CD/DVD hostitele (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Jednotka CD/DVD hostitele (%1:)" msgid "&Connected" msgstr "&Připojeno" -msgid "Clear image history" -msgstr "Vymaž historie snímků" +msgid "Clear image &history" +msgstr "Vymaž &historie snímků" msgid "Create..." msgstr "Vytvoř..." @@ -1266,6 +1350,9 @@ msgstr "Nulový ovladač" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "Chování vykreslování" @@ -1305,8 +1392,8 @@ msgstr "Chyba při inicializaci OpenGL" msgid "\nFalling back to software rendering." msgstr "\nNávrat k softwarovému vykreslování." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Při výběru obrazů médií (CD-ROM, disketa atd.) se otevřené dialogové okno spustí ve stejném adresáři jako konfigurační soubor 86Box. Toto nastavení bude mít pravděpodobně význam pouze v systému MacOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Při výběru obrazů médií (CD-ROM, disketa atd.) se otevřené dialogové okno spustí ve stejném adresáři jako konfigurační soubor 86Box. Toto nastavení bude mít pravděpodobně význam pouze v systému MacOS.

" msgid "This machine might have been moved or copied." msgstr "Tento počítač mohl být přemístěn nebo zkopírován." @@ -1371,9 +1458,27 @@ msgstr "Průchod sériového portu 3" msgid "Serial port passthrough 4" msgstr "Průchod sériového portu 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Možnosti vykreslovače..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Sběrnicová myš Logitech/Microsoft" @@ -1383,18 +1488,30 @@ msgstr "Sběrnicová myš Microsoft (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Sériová myš Mouse Systems" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Sériová myš Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Sériová myš Logitech" msgid "PS/2 Mouse" msgstr "Myš PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (sériová)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Modem kompatibilní se standardem Hayes" @@ -1419,12 +1536,54 @@ msgstr "Systémové MIDI" msgid "MIDI Input Device" msgstr "Vstupní zařízení MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "Adresa BIOSu" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "Povolení zápisu do rozšiřující paměti ROM systému BIOS" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Adresa" @@ -1434,6 +1593,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "Revize BIOSu" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Přeložit 26 -> 17" @@ -1449,6 +1620,18 @@ msgstr "Invertování barev" msgid "BIOS size" msgstr "Velikost BIOSu" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "Mapovat C0000-C7FFF jako UMB" @@ -1524,6 +1707,9 @@ msgstr "Úroveň dozvuku" msgid "Interpolation Method" msgstr "Metoda interpolace" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Zesílení výstupu dozvuku" @@ -1611,6 +1797,12 @@ msgstr "Nízký DMA" msgid "Enable Game port" msgstr "Povolit herní port" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Modul Surround" @@ -1623,6 +1815,9 @@ msgstr "Vyvolání přerušení CODEC při nastavení CODEC (potřebují někter msgid "SB Address" msgstr "Adresa SB" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "IRQ WSS" @@ -1707,9 +1902,15 @@ msgstr "Typ RAMDACu" msgid "Blend" msgstr "Směs" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Bilineární filtrování" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Dithering" @@ -1752,6 +1953,33 @@ msgstr "Rychlost přenosu" msgid "EMS mode" msgstr "Režím EMS" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Adresa pro > 2 MB" @@ -1770,11 +1998,11 @@ msgstr "Vždy při zvolené rychlosti" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Nastavení BIOS + klávesové zkratky (vypnuto během POST)" -msgid "64 kB starting from F0000" -msgstr "64 kB od F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB od F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB od E0000 (invertovaný MSB adresy, nejprve posledních 64 kB)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB od E0000 (invertovaný MSB adresy, nejprve posledních 64 KB)" msgid "Sine" msgstr "Sinusový" @@ -1840,7 +2068,7 @@ msgid "2 MB" msgstr "2 MB" msgid "8 MB" -msgstr " 8 MB" +msgstr "8 MB" msgid "28 MB" msgstr "28 MB" @@ -1908,6 +2136,15 @@ msgstr "Interpolace sRGB" msgid "Linear interpolation" msgstr "Lineární interpolace" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2178,9 @@ msgstr "Jantarový" msgid "Gray" msgstr "Šedý" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Barevný" @@ -1956,6 +2196,12 @@ msgstr "Ostatní jazyky" msgid "Bochs latest" msgstr "Bochs nejnovější" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Monochromatický bez prokládání" @@ -2037,6 +2283,9 @@ msgstr "Přenosová rychlost průchodu" msgid "Named Pipe (Server)" msgstr "Pojmenované potrubí (server)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "Průchod sériového portu hostitele" @@ -2082,6 +2331,12 @@ msgstr "Klon IBM 8514/A (ISA)" msgid "Vendor" msgstr "Výrobce" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "Obecné rozšíření paměti PC/XT" @@ -2106,9 +2361,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2156,3 +2408,87 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Řadič disku:" + +#~ msgid "ZIP drives:" +#~ msgstr "Mechaniky ZIP:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "Obrazy ZIP disků" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index ce7d52d55..d4c7fcb82 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -27,8 +27,11 @@ msgstr "Strg+Alt+&Esc" msgid "&Pause" msgstr "&Pause" -msgid "E&xit..." -msgstr "Be&enden..." +msgid "Re&sume" +msgstr "&Fortsetzen" + +msgid "E&xit" +msgstr "Be&enden" msgid "&View" msgstr "&Ansicht" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0-Kern)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "Fenstergröße einstellen..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "Filterungsmethode" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "&VGA-Bildschirmtyp" msgid "RGB &Color" msgstr "&RGB-Farbe" +msgid "RGB (no brown)" +msgstr "RGB (ohne Braun)" + msgid "&RGB Grayscale" msgstr "&RGB-Graustufen" +msgid "Generic RGBI color monitor" +msgstr "Generischer RGBI-Farbmonitor" + msgid "&Amber monitor" msgstr "&Bernstein-Monitor" @@ -384,6 +393,15 @@ msgstr "Eingeschaltet (UTC)" msgid "Dynamic Recompiler" msgstr "Dynamischer Recompiler" +msgid "CPU frame size" +msgstr "CPU-Framegröße" + +msgid "Larger frames (less smooth)" +msgstr "Größere Frames (weniger flüssig)" + +msgid "Smaller frames (smoother)" +msgstr "Kleinere Frames (flüssiger)" + msgid "Video:" msgstr "Videokarte:" @@ -399,6 +417,9 @@ msgstr "IBM 8514/A-Grafik" msgid "XGA Graphics" msgstr "XGA-Grafik" +msgid "Keyboard:" +msgstr "Tastatur:" + msgid "Mouse:" msgstr "Maus:" @@ -498,18 +519,21 @@ msgstr "Parallelport 3" msgid "Parallel port 4" msgstr "Parallelport 4" -msgid "HD Controller:" -msgstr "HDD-Controller:" - msgid "FD Controller:" msgstr "FD-Controller:" +msgid "CD-ROM Controller:" +msgstr "CD-ROM-Controller:" + msgid "Tertiary IDE Controller" msgstr "Tertiärer IDE-Controller" msgid "Quaternary IDE Controller" msgstr "Quartärer IDE-Controller" +msgid "Hard disk" +msgstr "Festplatte" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Kassette" msgid "Hard disks:" msgstr "Festplatten:" +msgid "Firmware Version" +msgstr "Firmware-Version" + msgid "&New..." msgstr "&Neu..." @@ -588,8 +615,8 @@ msgstr "CD-ROM-Laufwerke:" msgid "MO drives:" msgstr "MO-Laufwerke:" -msgid "ZIP drives:" -msgstr "ZIP-Laufwerke:" +msgid "Removable disk drives:" +msgstr "Wechseldatenträger:" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA-Echtzeituhr:" msgid "ISA Memory Expansion" msgstr "ISA-Speichererweiterung:" +msgid "ISA ROM Cards" +msgstr "ISA-ROM-Karte" + msgid "Card 1:" msgstr "Steckkarte 1:" @@ -612,6 +642,15 @@ msgstr "Steckkarte 3:" msgid "Card 4:" msgstr "Steckkarte 4:" +msgid "Generic ISA ROM Board" +msgstr "Generische ISA-ROM-Platine" + +msgid "Generic Dual ISA ROM Board" +msgstr "Generische Dual-ISA-ROM-Platine" + +msgid "Generic Quad ISA ROM Board" +msgstr "Generische Quad-ISA-ROM-Platine" + msgid "ISABugger device" msgstr "ISABugger-Gerät" @@ -630,17 +669,20 @@ msgstr "Fataler Fehler" msgid " - PAUSED" msgstr " - PAUSIERT" -msgid "Press %s to return to windowed mode." -msgstr "%s ab, zur Rückkehr in den Fenstermodus." - msgid "Speed" msgstr "Geschwindigkeit" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "Wechseldatenträger %1 (%2): %3" -msgid "ZIP images" -msgstr "ZIP-Abbilder" +msgid "&Removable disk %1 (%2): %3" +msgstr "&Wechseldatenträger %1 (%2): %3" + +msgid "Removable disk images" +msgstr "Wechseldatenträgerabbilder" + +msgid "Image %1" +msgstr "Abbild %1" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "86Box konnte keine nutzbaren ROM-Dateien finden.\n\nBitte besuchen Sie download, laden ein ROM-Set herunter und extrahieren dies in das \"roms\"-Verzeichnis." @@ -717,14 +759,11 @@ msgstr "Andere Peripheriegeräte" msgid "Click to capture mouse" msgstr "Klicken zum Einfangen des Mauszeigers" -msgid "Press %s to release mouse" -msgstr "Drücke %s zur Mausfreigabe" +msgid "Press %1 to release mouse" +msgstr "Drücke %1 zur Mausfreigabe" -msgid "Press %s or middle button to release mouse" -msgstr "Drücke %s oder die mittlere Maustaste zur Mausfreigabe" - -msgid "Ctrl+End" -msgstr "Strg+Ende" +msgid "Press %1 or middle button to release mouse" +msgstr "Drücke %1 oder die mittlere Maustaste zur Mausfreigabe" msgid "Bus" msgstr "Bus" @@ -783,12 +822,39 @@ msgstr "4-Achsen-, 4-Tasten-Joystick" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "2-Tasten-Gamepad(s)" + +msgid "2-button flight yoke" +msgstr "2-Tasten-Steuerhorn" + +msgid "4-button gamepad" +msgstr "4-Tasten-Gamepad" + +msgid "4-button flight yoke" +msgstr "4-Tasten-Steuerhorn" + +msgid "2-button flight yoke with throttle" +msgstr "2-Tasten-Steuerhorn mit Schubregler" + +msgid "4-button flight yoke with throttle" +msgstr "4-Tasten-Steuerhorn mit Schubregler" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "Win95 Lenkrad (3-Achsen, 4-Tasten)" + msgid "None" msgstr "Ohne" @@ -798,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Diskette %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Diskette %1 (%2): %3" + msgid "Advanced sector images" msgstr "Fortgeschrittene Sektorabbilder" @@ -819,6 +888,9 @@ msgstr "GhostPCL konnte nicht initialisiert werden" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "MO-Abbilder" @@ -867,9 +939,6 @@ msgstr "%1 wird zur automatischen Konvertierung von PostScript-Dateien ins PDF-F msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 wird zur automatischen Konvertierung von PCL-Dateien ins PDF-Format benötigt.\n\nSämtliche an den generischen PCL-Drucker gesendete Dateien werden als Printer Command Language (*.pcl) Dateien gesichert." -msgid "Entering fullscreen mode" -msgstr "Vollbildmodus wird aktiviert" - msgid "Don't show this message again" msgstr "Diese Nachricht nicht mehr anzeigen" @@ -906,12 +975,18 @@ msgstr "Fortfahren" msgid "Cassette: %1" msgstr "Kassette: %1" +msgid "C&assette: %1" +msgstr "K&assette: %1" + msgid "Cassette images" msgstr "Kassettenabbilder" msgid "Cartridge %1: %2" msgstr "Cartridge %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Car&tridge %1: %2" + msgid "Cartridge images" msgstr "Cartridgeabbilder" @@ -933,6 +1008,9 @@ msgstr "Kaltstart" msgid "ACPI shutdown" msgstr "ACPI basiertes Herunterfahren" +msgid "ACP&I shutdown" +msgstr "ACP&I basiertes Herunterfahren" + msgid "Hard disk (%1)" msgstr "Festplatte (%1)" @@ -1080,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 KB" @@ -1218,41 +1299,41 @@ msgstr "MCA-Geräte" msgid "List of MCA devices:" msgstr "Liste die MCA-Geräte:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Tablet-Werkzeug" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "Über Qt" +msgid "About &Qt" +msgstr "Über &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "MCA-Geräte..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Nicht-primäre Monitore anzeigen" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Ordner „screenshots“ öffnen..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Vollbild-Streckmodus aktivieren, wenn das Fenster maximiert ist" -msgid "Cursor/Puck" -msgstr "Mauszeiger/Puck" +msgid "&Cursor/Puck" +msgstr "&Mauszeiger/Puck" -msgid "Pen" -msgstr "Stift" +msgid "&Pen" +msgstr "&Stift" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Host-CD/DVD-Laufwerk (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Host-CD/DVD-Laufwerk (%1:)" msgid "&Connected" msgstr "&Verbunden" -msgid "Clear image history" -msgstr "Abbildverlauf löschen" +msgid "Clear image &history" +msgstr "&Abbildverlauf löschen" msgid "Create..." msgstr "Erstellen..." @@ -1269,6 +1350,9 @@ msgstr "Nulltreiber" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "Rendering-Verhalten" @@ -1308,8 +1392,8 @@ msgstr "Fehler beim Initialisieren von OpenGL" msgid "\nFalling back to software rendering." msgstr "\nRückgriff auf Software-Rendering." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Bei der Auswahl von Medien-Abbildern (CD-ROM, Diskette usw.) wird der Öffnungsdialog im selben Verzeichnis wie die 86Box-Konfigurationsdatei gestartet. Diese Einstellung macht wahrscheinlich nur unter macOS einen Unterschied.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Bei der Auswahl von Medien-Abbildern (CD-ROM, Diskette usw.) wird der Öffnungsdialog im selben Verzeichnis wie die 86Box-Konfigurationsdatei gestartet. Diese Einstellung macht wahrscheinlich nur unter macOS einen Unterschied.

" msgid "This machine might have been moved or copied." msgstr "Dieses System wurde möglicherweise verschoben oder kopiert." @@ -1374,9 +1458,27 @@ msgstr "Durchreichung der Serielle Schnittstelle 3" msgid "Serial port passthrough 4" msgstr "Durchreichung der Serielle Schnittstelle 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Renderer-Optionen..." +msgid "PC/XT Keyboard" +msgstr "PC/XT-Tastatur" + +msgid "AT Keyboard" +msgstr "AT-Tastatur" + +msgid "AX Keyboard" +msgstr "AX-Tastatur" + +msgid "PS/2 Keyboard" +msgstr "PS/2-Tastatur" + +msgid "PS/55 Keyboard" +msgstr "PS/55-Tastatur" + +msgid "Keys" +msgstr "Tasten" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Logitech/Microsoft Bus-Maus" @@ -1386,18 +1488,30 @@ msgstr "Microsoft Bus-Maus (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Mouse Systems Serielle Maus" +msgid "Mouse Systems Bus Mouse" +msgstr "Mouse Systems Bus-Maus" + msgid "Microsoft Serial Mouse" msgstr "Microsoft Serielle Maus" +msgid "Microsoft Serial BallPoint" +msgstr "Microsoft Serial BallPoint" + msgid "Logitech Serial Mouse" msgstr "Logitech Serielle Maus" msgid "PS/2 Mouse" msgstr "PS/2-Maus" +msgid "PS/2 QuickPort Mouse" +msgstr "PS/2-QuickPort-Maus" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (Seriell)" +msgid "Default Baud rate" +msgstr "Standard-Baudrate" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Standard Hayes-kompatibles Modem" @@ -1422,12 +1536,54 @@ msgstr "System MIDI" msgid "MIDI Input Device" msgstr "MIDI-Eingabegerät" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "BIOS-Datei" + +msgid "BIOS file (ROM #1)" +msgstr "BIOS-Datei (ROM #1)" + +msgid "BIOS file (ROM #2)" +msgstr "BIOS-Datei (ROM #2)" + +msgid "BIOS file (ROM #3)" +msgstr "BIOS-Datei (ROM #3)" + +msgid "BIOS file (ROM #4)" +msgstr "BIOS-Datei (ROM #4)" + +msgid "BIOS address" msgstr "BIOS-Adresse" +msgid "BIOS address (ROM #1)" +msgstr "BIOS-Adresse (ROM #1)" + +msgid "BIOS address (ROM #2)" +msgstr "BIOS-Adresse (ROM #2)" + +msgid "BIOS address (ROM #3)" +msgstr "BIOS-Adresse (ROM #3)" + +msgid "BIOS address (ROM #4)" +msgstr "BIOS-Adresse (ROM #4)" + msgid "Enable BIOS extension ROM Writes" msgstr "Schreiben in BIOS Erweiterungs ROMs zulassen" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "Schreiben in BIOS-Erweiterungs-ROMs (ROM #1) zulassen" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "Schreiben in BIOS-Erweiterungs-ROMs (ROM #2) zulassen" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "Schreiben in BIOS-Erweiterungs-ROMs (ROM #3) zulassen" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "Schreiben in BIOS-Erweiterungs-ROMs (ROM #4) zulassen" + +msgid "Linear framebuffer base" +msgstr "Lineare Framebuffer-Basis" + msgid "Address" msgstr "Adresse" @@ -1437,6 +1593,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "BIOS-Revision" +msgid "BIOS Version" +msgstr "BIOS-Version" + +msgid "BIOS Language" +msgstr "BIOS-Sprache" + +msgid "IBM 5161 Expansion Unit" +msgstr "IBM 5161 Erweiterungseinheit" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Übersetzen 26 -> 17" @@ -1452,6 +1620,18 @@ msgstr "Farben invertieren" msgid "BIOS size" msgstr "BIOS-Größe" +msgid "BIOS size (ROM #1)" +msgstr "BIOS-Größe (ROM #1)" + +msgid "BIOS size (ROM #2)" +msgstr "BIOS-Größe (ROM #2)" + +msgid "BIOS size (ROM #3)" +msgstr "BIOS-Größe (ROM #3)" + +msgid "BIOS size (ROM #4)" +msgstr "BIOS-Größe (ROM #4)" + msgid "Map C0000-C7FFF as UMB" msgstr "C0000-C7FFF als UMB zuordnen" @@ -1527,6 +1707,9 @@ msgstr "Nachhall-Pegel" msgid "Interpolation Method" msgstr "Interpolationsmethode" +msgid "Dynamic Sample Loading" +msgstr "Dynamisches Sample-Laden" + msgid "Reverb Output Gain" msgstr "Nachhall-Ausgangsverstärkung" @@ -1614,6 +1797,12 @@ msgstr "Niedrige DMA" msgid "Enable Game port" msgstr "Game-Port einschalten" +msgid "SID Model" +msgstr "SID-Modell" + +msgid "SID Filter Strength" +msgstr "SID-Filterstärke" + msgid "Surround module" msgstr "Surround-Modul" @@ -1626,6 +1815,9 @@ msgstr "CODEC-Interrupt bei CODEC-Einrichtung auslösen (wird von einigen Treibe msgid "SB Address" msgstr "SB-Adresse" +msgid "Use EEPROM setting" +msgstr "EEPROM-Einstellung verwenden" + msgid "WSS IRQ" msgstr "WSS-IRQ" @@ -1710,9 +1902,15 @@ msgstr "RAMDAC-Typ" msgid "Blend" msgstr "Mischung" +msgid "Font" +msgstr "Schriftart" + msgid "Bilinear filtering" msgstr "Bilineare Filterung" +msgid "Video chroma-keying" +msgstr "Video-Chroma-Keying" + msgid "Dithering" msgstr "Dithering" @@ -1755,6 +1953,33 @@ msgstr "Übertragungsgeschwindigkeit" msgid "EMS mode" msgstr "EMS-Modus" +msgid "EMS Address" +msgstr "EMS-Adresse" + +msgid "EMS 1 Address" +msgstr "EMS 1-Adresse" + +msgid "EMS 2 Address" +msgstr "EMS 2-Adresse" + +msgid "EMS Memory Size" +msgstr "EMS-Speichergröße" + +msgid "EMS 1 Memory Size" +msgstr "EMS 1-Speichergröße" + +msgid "EMS 2 Memory Size" +msgstr "EMS 2-Speichergröße" + +msgid "Enable EMS" +msgstr "EMS einschalten" + +msgid "Enable EMS 1" +msgstr "EMS 1 einschalten" + +msgid "Enable EMS 2" +msgstr "EMS 2 einschalten" + msgid "Address for > 2 MB" msgstr "Adresse für > 2 MB" @@ -1773,11 +1998,11 @@ msgstr "Immer mit der gewählten Geschwindigkeit" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "BIOS-Einstellung + Hotkeys (aus während POST)" -msgid "64 kB starting from F0000" -msgstr "64 kB ab F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB ab F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB ab E0000 (MSB der Adresse invertiert, letzte 64KB zuerst)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB ab E0000 (MSB der Adresse invertiert, letzte 64 KB zuerst)" msgid "Sine" msgstr "Sinus" @@ -1813,7 +2038,7 @@ msgid "Five + Wheel" msgstr "Fünf + Rad" msgid "Five + 2 Wheels" -msgstr "" +msgstr "Fünf + 2 Räder" msgid "A3 - SMT2 Serial / SMT3(R)V" msgstr "A3 - SMT2 Seriell / SMT3(R)V" @@ -1843,7 +2068,7 @@ msgid "2 MB" msgstr "2 MB" msgid "8 MB" -msgstr " 8 MB" +msgstr "8 MB" msgid "28 MB" msgstr "28 MB" @@ -1911,6 +2136,15 @@ msgstr "sRGB-Interpolation" msgid "Linear interpolation" msgstr "Lineare Interpolation" +msgid "Has secondary 8x8 character set" +msgstr "Hat sekundären 8x8-Zeichensatz" + +msgid "Has Quadcolor II daughter board" +msgstr "Hat Quadcolor II-Tochterplatine" + +msgid "Alternate monochrome contrast" +msgstr "Alternativer Monochrom-Kontrast" + msgid "128 KB" msgstr "128 KB" @@ -1944,6 +2178,9 @@ msgstr "Bernsteinfarben" msgid "Gray" msgstr "Graues" +msgid "Grayscale" +msgstr "Graustufen" + msgid "Color" msgstr "Farbe" @@ -1959,6 +2196,12 @@ msgstr "Andere Sprachen" msgid "Bochs latest" msgstr "Bochs neueste" +msgid "Apply overscan deltas" +msgstr "Overscan-Deltas anwenden" + +msgid "Mono Interlaced" +msgstr "Monochrom (Mit Zeilensprungverfahren)" + msgid "Mono Non-Interlaced" msgstr "Monochrom (Kein Zeilensprungverfahren)" @@ -2040,6 +2283,9 @@ msgstr "Baudrate der Durchreichung" msgid "Named Pipe (Server)" msgstr "Benanntes Pipe (Server)" +msgid "Named Pipe (Client)" +msgstr "Benanntes Pipe (Client)" + msgid "Host Serial Passthrough" msgstr "Durchreichung der seriellen Schnittstelle des Hosts" @@ -2059,25 +2305,25 @@ msgid "[Generic] RAM Disk (max. speed)" msgstr "[Generic] RAM-Diskette (maximale Geschwindigkeit)" msgid "[Generic] 1989 (3500 RPM)" -msgstr "" +msgstr "[Generisch] 1989 (3500 U/min)" msgid "[Generic] 1992 (3600 RPM)" -msgstr "" +msgstr "[Generisch] 1992 (3600 U/min)" msgid "[Generic] 1994 (4500 RPM)" -msgstr "" +msgstr "[Generisch] 1994 (4500 U/min)" msgid "[Generic] 1996 (5400 RPM)" -msgstr "" +msgstr "[Generisch] 1996 (5400 U/min)" msgid "[Generic] 1997 (5400 RPM)" -msgstr "" +msgstr "[Generisch] 1997 (5400 U/min)" msgid "[Generic] 1998 (5400 RPM)" -msgstr "" +msgstr "[Generisch] 1998 (5400 U/min)" msgid "[Generic] 2000 (7200 RPM)" -msgstr "" +msgstr "[Generisch] 2000 (7200 U/min)" msgid "IBM 8514/A clone (ISA)" msgstr "IBM 8514/A-Klon (ISA)" @@ -2085,6 +2331,12 @@ msgstr "IBM 8514/A-Klon (ISA)" msgid "Vendor" msgstr "Hersteller" +msgid "30 Hz (JMP2 = 1)" +msgstr "30 Hz (JMP2 = 1)" + +msgid "60 Hz (JMP2 = 2)" +msgstr "60 Hz (JMP2 = 2)" + msgid "Generic PC/XT Memory Expansion" msgstr "Generische PC/XT-Speichererweiterung" @@ -2098,64 +2350,145 @@ msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for t msgstr "TrueType-Schriften in das \"roms/printer/fonts\"-Verzeichnis sind für die Allgemeines ESC/P Nadel-Druckers erforderlich." msgid "Inhibit multimedia keys" -msgstr "" +msgstr "Multimedia-Tasten unterdrücken" msgid "Ask for confirmation before saving settings" -msgstr "" +msgstr "Vor dem Speichern der Einstellungen um Bestätigung bitten" msgid "Ask for confirmation before hard resetting" -msgstr "" +msgstr "Vor dem Kaltstart um Bestätigung bitten" msgid "Ask for confirmation before quitting" -msgstr "" - -msgid "Display hotkey message when entering full-screen mode" -msgstr "" +msgstr "Vor dem Beenden um Bestätigung bitten" msgid "Options" -msgstr "" +msgstr "Optionen" msgid "Model" -msgstr "" +msgstr "Modell" msgid "Model:" -msgstr "" +msgstr "Modell:" msgid "Failed to initialize Vulkan renderer." -msgstr "" +msgstr "Fehler bei der Initialisierung des Vulkan-Renderers." msgid "GLSL Error" -msgstr "" +msgstr "GLSL-Fehler" msgid "Could not load shader: %1" -msgstr "" +msgstr "Shader konnte nicht geladen werden: %1" msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "" +msgstr "OpenGL-Version 3.0 oder höher ist erforderlich. Die aktuelle GLSL-Version ist %1.%2" msgid "Could not load texture: %1" -msgstr "" +msgstr "Textur konnte nicht geladen werden: %1" msgid "Could not compile shader:\n\n%1" -msgstr "" +msgstr "Shader konnte nicht kompiliert werden:\n\n%1" msgid "Program not linked:\n\n%1" -msgstr "" +msgstr "Programm nicht verknüpft:\n\n%1" msgid "Shader Manager" -msgstr "" +msgstr "Shader-Manager" msgid "Shader Configuration" -msgstr "" +msgstr "Shader-Konfiguration" msgid "Add" -msgstr "" +msgstr "Hinzufügen" msgid "Move up" -msgstr "" +msgstr "Nach oben verschieben" msgid "Move down" -msgstr "" +msgstr "Nach unten verschieben" msgid "Could not load file %1" -msgstr "" +msgstr "Datei %1 konnte nicht geladen werden" + +msgid "Key Bindings:" +msgstr "Tastenbelegungen:" + +msgid "Action" +msgstr "Aktion" + +msgid "Keybind" +msgstr "Tastenbelegung" + +msgid "Clear binding" +msgstr "Belegung löschen" + +msgid "Bind" +msgstr "Belegen" + +msgid "Bind Key" +msgstr "Taste belegen" + +msgid "Enter key combo:" +msgstr "Tastenkombination eingeben:" + +msgid "Bind conflict" +msgstr "Belegungskonflikt" + +msgid "This key combo is already in use." +msgstr "Diese Tastenkombination wird bereits verwendet." + +msgid "Send Control+Alt+Del" +msgstr "Strg+Alt+Entf senden" + +msgid "Send Control+Alt+Escape" +msgstr "Strg+Alt+Esc senden" + +msgid "Toggle fullscreen" +msgstr "Vollbild umschalten" + +msgid "Screenshot" +msgstr "Screensho" + +msgid "Release mouse pointer" +msgstr "Mauszeiger freigeben" + +msgid "Toggle pause" +msgstr "Pause umschalten" + +msgid "Toggle mute" +msgstr "Stummschaltung umschalten" + +msgid "Text files" +msgstr "Textdateien" + +msgid "ROM files" +msgstr "ROM-Dateien" + +msgid "SoundFont files" +msgstr "SoundFont-Dateien" + +msgid "Local Switch" +msgstr "Lokaler Schalter" + +msgid "Remote Switch" +msgstr "Entfernter Schalter" + +msgid "Switch:" +msgstr "Schalter:" + +msgid "Hub Mode" +msgstr "Hub-Modus" + +msgid "Hostname:" +msgstr "Hostname:" + +#~ msgid "HD Controller:" +#~ msgstr "HDD-Controller:" + +#~ msgid "ZIP drives:" +#~ msgstr "ZIP-Laufwerke:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "ZIP-Abbilder" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index 8cc29a71a..9802d06f9 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -24,8 +24,8 @@ msgstr "Unable to initialise GhostPCL" msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behaviour will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." -msgid "Apply fullscreen stretch mode when maximized" -msgstr "Apply fullscreen stretch mode when maximised" +msgid "Appl&y fullscreen stretch mode when maximized" +msgstr "Appl&y fullscreen stretch mode when maximised" msgid "Failed to initialize network driver" msgstr "Failed to initialise network driver" @@ -39,8 +39,8 @@ msgstr "Synchronise with video" msgid "Error initializing OpenGL" msgstr "Error initialising OpenGL" -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialogue will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

When selecting media images (CD-ROM, floppy, etc.) the open dialogue will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" msgid "Color (generic)" msgstr "Colour (generic)" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 177d08d18..a8b1555b9 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Pausa" -msgid "E&xit..." -msgstr "&Salir..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "&Salir" msgid "&View" msgstr "&Vista" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "E&specificar dimensiones..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "&Método de filtrado" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "&Tipo de pantalla VGA" msgid "RGB &Color" msgstr "RGB &Color" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "RGB &Grises" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "Monitor &Ámbar" @@ -384,6 +393,15 @@ msgstr "Habilitado (UTC)" msgid "Dynamic Recompiler" msgstr "Recompilador Dinámico" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Vídeo:" @@ -399,6 +417,9 @@ msgstr "Gráficos IBM 8514/A" msgid "XGA Graphics" msgstr "Gráficos XGA" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Ratón:" @@ -498,18 +519,21 @@ msgstr "Puerto paralelo 3" msgid "Parallel port 4" msgstr "Puerto paralelo 4" -msgid "HD Controller:" -msgstr "Controladora HD:" - msgid "FD Controller:" msgstr "Controladora FD:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "Tercera controladora IDE" msgid "Quaternary IDE Controller" msgstr "Cuarta controladora IDE" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Cassette" msgid "Hard disks:" msgstr "Discos duros:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "&Nuevo..." @@ -588,8 +615,8 @@ msgstr "Unidades de CD-ROM:" msgid "MO drives:" msgstr "Unidades MO:" -msgid "ZIP drives:" -msgstr "Unidades ZIP:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA RTC:" msgid "ISA Memory Expansion" msgstr "Expansión de Memoria ISA" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Tarjeta 1:" @@ -612,6 +642,15 @@ msgstr "Tarjeta 3:" msgid "Card 4:" msgstr "Tarjeta 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "Dispositivo ISABugger" @@ -630,17 +669,20 @@ msgstr "Error fatal" msgid " - PAUSED" msgstr " - EN PAUSA" -msgid "Press %s to return to windowed mode." -msgstr "Pulsa %s para volver a modo ventana." - msgid "Speed" msgstr "Velocidad" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "Imagenes ZIP" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" 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 descargue un conjunte de ROMs y extráigalo en el directorio \"roms\"." @@ -717,11 +759,11 @@ msgstr "Otros periféricos" msgid "Click to capture mouse" msgstr "Haga click para capturar el ratón" -msgid "Press %s to release mouse" -msgstr "Pulse %s para liberar el ratón" +msgid "Press %1 to release mouse" +msgstr "Pulse %1 para liberar el ratón" -msgid "Press %s or middle button to release mouse" -msgstr "Pulse %s o el botón central para liberar el ratón" +msgid "Press %1 or middle button to release mouse" +msgstr "Pulse %1 o el botón central para liberar el ratón" msgid "Bus" msgstr "Bus" @@ -780,12 +822,39 @@ msgstr "Mando de 4 ejes, 4 botones" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Ninguno" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Disquete %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Disquete %1 (%2): %3" + msgid "Advanced sector images" msgstr "Imágenes avanzadas de sector" @@ -816,6 +888,9 @@ msgstr "No fué posible inicializar GhostPCL" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "Imágenes de MO" @@ -864,9 +939,6 @@ msgstr "%1 es necesaria para la conversión automática de archivos PostScript a msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 es necesaria para la conversión automática de archivos PCL a PDF.\n\nCualquier documento enviado a la impresora genérica PCL se guardará como archivo Printer Command Language (.pcl)." -msgid "Entering fullscreen mode" -msgstr "Entrando en modo pantalla completa" - msgid "Don't show this message again" msgstr "No mostrar más este mensaje" @@ -903,12 +975,18 @@ msgstr "Continuar" msgid "Cassette: %1" msgstr "Cassette: %1" +msgid "C&assette: %1" +msgstr "C&assette: %1" + msgid "Cassette images" msgstr "Imágenes de Cassette" msgid "Cartridge %1: %2" msgstr "Cartucho %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Car&tucho %1: %2" + msgid "Cartridge images" msgstr "Imágenes de Cartucho" @@ -930,6 +1008,9 @@ msgstr "Hard reset" msgid "ACPI shutdown" msgstr "Parada ACPI" +msgid "ACP&I shutdown" +msgstr "Parada ACP&I" + msgid "Hard disk (%1)" msgstr "Disco duro (%1)" @@ -1077,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 KB" @@ -1193,6 +1277,7 @@ msgstr "WinBox ya no recibe soporte" msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." msgstr "El desarrollo del gestor WinBox se detuvo en 2022 debido a la falta de mantenedores. Como dirigimos nuestros esfuerzos a hacer 86Box aún mejor, hemos tomado la decisión de dejar de dar soporte a WinBox como gestor.\n\nNo se proporcionarán más actualizaciones a través de WinBox, y puede encontrar un comportamiento incorrecto si continúa usándolo con versiones más nuevas de 86Box. Cualquier informe de error relacionado con el comportamiento de WinBox será cerrado como inválido.\n\nVaya a 86box.net para una lista de otros gestores que puede utilizar." + msgid "Generate" msgstr "Vytvoř" @@ -1214,41 +1299,41 @@ msgstr "Dispositivos MCA" msgid "List of MCA devices:" msgstr "Lista de dispositivos MCA:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Herramienta de tableta" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "Acerca de Qt" +msgid "About &Qt" +msgstr "Acerca de &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "Dispositivos MCA ..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Mostrar monitores no primarios" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Abrir la carpeta screenshots..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Usar escalado pantalla completa en modalidad maximizada" -msgid "Cursor/Puck" -msgstr "Cursor/Puck" +msgid "&Cursor/Puck" +msgstr "&Cursor/Puck" -msgid "Pen" -msgstr "Bolígrafo" +msgid "&Pen" +msgstr "&Bolígrafo" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Unidad de CD/DVD anfitriona (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Unidad de CD/DVD anfitriona (%1:)" msgid "&Connected" msgstr "&Conectrado" -msgid "Clear image history" -msgstr "Eliminar historia de imágenes" +msgid "Clear image &history" +msgstr "Eliminar &historia de imágenes" msgid "Create..." msgstr "Crear..." @@ -1265,6 +1350,9 @@ msgstr "Controlador nulo" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "Comportamiento del renderizador" @@ -1304,8 +1392,8 @@ msgstr "Error al inicializar OpenGL" msgid "\nFalling back to software rendering." msgstr "\nRecurrir al renderizado por software." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Al seleccionar imágenes multimedia (CD-ROM, disquete, etc.), el diálogo de apertura se iniciará en el mismo directorio que el archivo de configuración de 86Box. Es probable que este ajuste sólo suponga una diferencia en macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Al seleccionar imágenes multimedia (CD-ROM, disquete, etc.), el diálogo de apertura se iniciará en el mismo directorio que el archivo de configuración de 86Box. Es probable que este ajuste sólo suponga una diferencia en macOS.

" msgid "This machine might have been moved or copied." msgstr "Esta máquina puede haber sido movida o copiado." @@ -1370,9 +1458,27 @@ msgstr "Paso de puerto serie 3" msgid "Serial port passthrough 4" msgstr "Paso de puerto serie 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Opciones del renderizador..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Ratón de bus Logitech/Microsoft" @@ -1382,18 +1488,30 @@ msgstr "Ratón de bus Microsoft (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Ratón serie Mouse Systems" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Ratón serie Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Ratón serie Logitech" msgid "PS/2 Mouse" msgstr "Ratón PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (serie)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Módem estándar compatible con Hayes" @@ -1418,12 +1536,54 @@ msgstr "MIDI del sistema" msgid "MIDI Input Device" msgstr "Dispositivo de entrada MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "Dirección de BIOS" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "Habilitar escrituras para el ROM de extensión de BIOS" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Dirección" @@ -1433,6 +1593,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "Revisión de BIOS" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Traducir 26 -> 17" @@ -1448,6 +1620,18 @@ msgstr "Invertir colores" msgid "BIOS size" msgstr "Tamaño de BIOS" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "Mapear a C0000-C7FFF como UMB" @@ -1523,6 +1707,9 @@ msgstr "Nível de reverberación" msgid "Interpolation Method" msgstr "Método de interpolación" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Ganancia de salida de reverberación" @@ -1610,6 +1797,12 @@ msgstr "DMA bajo" msgid "Enable Game port" msgstr "Habilitar puerto de juegos" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Módulo Surround" @@ -1622,6 +1815,9 @@ msgstr "Activar la interrupción CODEC en la configuración CODEC (necesario par msgid "SB Address" msgstr "Dirección del SB" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "IRQ de WSS" @@ -1706,9 +1902,15 @@ msgstr "Tipo de RAMDAC" msgid "Blend" msgstr "Mezclar" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Filtrado bilineal" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Dithering" @@ -1751,6 +1953,33 @@ msgstr "Velocidad de transferencia" msgid "EMS mode" msgstr "Modo EMS" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Dirección para > 2 MB" @@ -1769,11 +1998,11 @@ msgstr "Siempre a la velocidad seleccionada" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Configuración de la BIOS + Teclas de acceso rápido (desactivadas durante la POST)" -msgid "64 kB starting from F0000" -msgstr "64 kB desde F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB desde F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB desde E0000 (MSB de dirección invertido, últimas 64KB primero)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB desde E0000 (MSB de dirección invertido, últimas 64 KB primero)" msgid "Sine" msgstr "Sinusoidal" @@ -1839,7 +2068,7 @@ msgid "2 MB" msgstr "2 MB" msgid "8 MB" -msgstr " 8 MB" +msgstr "8 MB" msgid "28 MB" msgstr "28 MB" @@ -1907,6 +2136,15 @@ msgstr "Interpolación sRGB" msgid "Linear interpolation" msgstr "Interpolación lineare" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1940,6 +2178,9 @@ msgstr "Ámbar" msgid "Gray" msgstr "Gris" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Color" @@ -1955,6 +2196,12 @@ msgstr "Otros idiomas" msgid "Bochs latest" msgstr "Bochs más nuevo" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Monocromo no entrelazado" @@ -2036,6 +2283,9 @@ msgstr "Tasa de baudios de paso" msgid "Named Pipe (Server)" msgstr "Tubería con nombre (servidor)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "Paso del puerto serie del host" @@ -2081,6 +2331,12 @@ msgstr "Clon IBM 8514/A (ISA)" msgid "Vendor" msgstr "Fabricante" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "Expansión de Memoria Generica PC/XT" @@ -2105,9 +2361,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2155,3 +2408,87 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Controladora HD:" + +#~ msgid "ZIP drives:" +#~ msgstr "Unidades ZIP:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "Imagenes ZIP" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index a77b3f6ef..e5e1b210e 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Tauko" -msgid "E&xit..." -msgstr "&Poistu..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "&Poistu" msgid "&View" msgstr "&Näytä" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "&Määritä koko..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "&Suodatusmetodi" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "VGA-näytön &tyyppi" msgid "RGB &Color" msgstr "RGB, &värit" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "&RGB, harmaasävy" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "&Meripihkanvärinen" @@ -384,6 +393,15 @@ msgstr "Käytössä (UTC)" msgid "Dynamic Recompiler" msgstr "Dynaaminen uudelleenkääntäjä" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Näytönohjain:" @@ -399,6 +417,9 @@ msgstr "IBM 8514/A-grafiikkasuoritin" msgid "XGA Graphics" msgstr "XGA-grafiikkasuoritin" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Hiiri:" @@ -498,18 +519,21 @@ msgstr "Rinnakkaisportti 3" msgid "Parallel port 4" msgstr "Rinnakkaisportti 4" -msgid "HD Controller:" -msgstr "Kiintolevyohjain:" - msgid "FD Controller:" msgstr "Levykeohjain:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "Kolmas IDE-ohjain" msgid "Quaternary IDE Controller" msgstr "Neljäs IDE-ohjain" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Kasettiasema" msgid "Hard disks:" msgstr "Kiintolevyt:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "&Uusi..." @@ -588,8 +615,8 @@ msgstr "CD-ROM-asemat:" msgid "MO drives:" msgstr "Magneettisoptiset asemat (MO):" -msgid "ZIP drives:" -msgstr "ZIP-asemat:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA-RTC (kello):" msgid "ISA Memory Expansion" msgstr "ISA-muistilaajennus" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Kortti 1:" @@ -612,6 +642,15 @@ msgstr "Kortti 3:" msgid "Card 4:" msgstr "Kortti 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "ISABugger-laite" @@ -630,17 +669,20 @@ msgstr "Vakava virhe" msgid " - PAUSED" msgstr " - TAUKO" -msgid "Press %s to return to windowed mode." -msgstr "Paina %s palataksesi ikkunoituun tilaan." - msgid "Speed" msgstr "Nopeus" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "ZIP-levykuvat" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "86Box ei löytänyt käyttökelpoisia ROM-tiedostoja.\n\nVoit ladata ROM-paketin ja purkaa sen \"roms\"-hakemistoon." @@ -675,7 +717,7 @@ msgstr "Konetta \"%hs\" ei voi käyttää, koska roms/machines-hakemistosta puut msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "Näytönohjainta \"%hs\" ei voi käyttää, koska roms/machines-hakemistosta puuttuvien ROM-tiedostojen vuoksi. Vaihdetaan käyttökelpoiseen näytönohjaimeen." -msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." msgstr "Näytönohjainta 2 \"%hs\" ei voi käyttää, koska roms/machines-hakemistosta puuttuvien ROM-tiedostojen vuoksi. Toisen näytönohjaimen poistaminen käytöstä." msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." @@ -717,11 +759,11 @@ msgstr "Muut oheislaitteet" msgid "Click to capture mouse" msgstr "Kaappaa hiiri klikkaamalla" -msgid "Press %s to release mouse" -msgstr "Paina %s vapauttaaksesi hiiren" +msgid "Press %1 to release mouse" +msgstr "Paina %1 vapauttaaksesi hiiren" -msgid "Press %s or middle button to release mouse" -msgstr "Paina %s tai keskipainiketta vapauttaaksesi hiiren" +msgid "Press %1 or middle button to release mouse" +msgstr "Paina %1 tai keskipainiketta vapauttaaksesi hiiren" msgid "Bus" msgstr "Väylä" @@ -780,12 +822,39 @@ msgstr "4-akselinen 4-painikkeinen peliohjain" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Ei mikään" @@ -795,6 +864,9 @@ msgstr "%1 Mt (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Levyke %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Levyke %1 (%2): %3" + msgid "Advanced sector images" msgstr "Kehittyneet sektorilevykuvat" @@ -816,6 +888,9 @@ msgstr "GhostPCLin alustus epäonnistui" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "MO-levykuvat" @@ -864,9 +939,6 @@ msgstr "%1 vaaditaan PostScript-tiedostojen automaattiseen muuntamiseen PDF-tied msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 vaaditaan PCL-tiedostojen automaattiseen muuntamiseen PDF-tiedostoiksi.\n\nKaikki geneeriselle PCL-tulostimelle lähetetyt asiakirjat tallennetaan Printer Command Language (.ps) -tiedostoina." -msgid "Entering fullscreen mode" -msgstr "Siirrytään koko näytön tilaan" - msgid "Don't show this message again" msgstr "Älä näytä tätä viestiä uudelleen" @@ -903,12 +975,18 @@ msgstr "Jatka" msgid "Cassette: %1" msgstr "Kasetti: %1" +msgid "C&assette: %1" +msgstr "K&asetti: %1" + msgid "Cassette images" msgstr "Kasettitiedostot" msgid "Cartridge %1: %2" msgstr "ROM-moduuli %1: %2" +msgid "Car&tridge %1: %2" +msgstr "R&OM-moduuli %1: %2" + msgid "Cartridge images" msgstr "ROM-moduulikuvat" @@ -930,6 +1008,9 @@ msgstr "Kylmä uudelleenkäynnistys" msgid "ACPI shutdown" msgstr "ACPI-sammutus" +msgid "ACP&I shutdown" +msgstr "ACP&I-sammutus" + msgid "Hard disk (%1)" msgstr "Kiintolevy (%1)" @@ -1077,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 Kt" @@ -1215,41 +1299,41 @@ msgstr "MCA-laitteet" msgid "List of MCA devices:" msgstr "Luettelo MCA-laitteista:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Tablettityökalu" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "Tietoja Qt:sta" +msgid "About &Qt" +msgstr "Tietoja &Qt:sta" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "MCA-laitteet..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Näytä muut kuin ensisijaiset monitorit" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Avaa kuvakaappaukset-kansio..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Sovelletaan koko näytön venytystilaa maksimoidessa" -msgid "Cursor/Puck" -msgstr "Kursori/Kiekko" +msgid "&Cursor/Puck" +msgstr "&Kursori/Kiekko" -msgid "Pen" -msgstr "Kynä" +msgid "&Pen" +msgstr "K&ynä" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Isäntä CD/DVD-asema (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Isäntä CD/DVD-asema (%1:)" msgid "&Connected" msgstr "&Yhdistetty" -msgid "Clear image history" -msgstr "Tyhjennä kuvahistoria" +msgid "Clear image &history" +msgstr "Tyhjennä kuva&historia" msgid "Create..." msgstr "Luo..." @@ -1266,6 +1350,9 @@ msgstr "Nolla-ajuri" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "Renderöintikäyttäytyminen" @@ -1287,9 +1374,6 @@ msgstr "Varjostinohjelmat" msgid "Remove" msgstr "Poista" -msgid "No shader selected" -msgstr "Ei valittu varjostinohjelmatta" - msgid "Browse..." msgstr "Selaa..." @@ -1308,8 +1392,8 @@ msgstr "Virhe OpenGL:n alustamisessa" msgid "\nFalling back to software rendering." msgstr "\nPaluu ohjelmistoalustusöintiin." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Kun valitset mediakuvia (CD-ROM, levykkeet jne.), avausikkuna käynnistyy samaan hakemistoon kuin 86Boxin konfigurointitiedosto. Tällä asetuksella on todennäköisesti merkitystä vain macOS-käyttöjärjestelmässä.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Kun valitset mediakuvia (CD-ROM, levykkeet jne.), avausikkuna käynnistyy samaan hakemistoon kuin 86Boxin konfigurointitiedosto. Tällä asetuksella on todennäköisesti merkitystä vain macOS-käyttöjärjestelmässä.

" msgid "This machine might have been moved or copied." msgstr "Kone on saatettu siirtää tai kopioida." @@ -1374,9 +1458,27 @@ msgstr "Sarjaportin läpivienti 3" msgid "Serial port passthrough 4" msgstr "Sarjaportin läpivienti 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Alustusasetukset..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Logitech/Microsoft-väylähiiri" @@ -1386,18 +1488,30 @@ msgstr "Microsoft-väylähiiri (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Mouse Systems-sarjahiiri" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Microsoft-sarjahiiri" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Logitech-sarjahiiri" msgid "PS/2 Mouse" msgstr "PS/2 hiiri" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (sarja)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Tavallinen Hayes-yhteensopiva modeemi" @@ -1422,12 +1536,54 @@ msgstr "Järjestelmän MIDI" msgid "MIDI Input Device" msgstr "MIDI-syöttölaite" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "BIOS-osoite" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "Käytä BIOS-laajennuksen ROM-kirjoitusten" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Osoite" @@ -1437,6 +1593,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "BIOS-tarkistus" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Käännä 26 -> 17" @@ -1452,6 +1620,18 @@ msgstr "Käännä värit" msgid "BIOS size" msgstr "BIOS-koko" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "Kartta C0000-C7FFF UMB:nä" @@ -1527,6 +1707,9 @@ msgstr "Jälkikaiunnan taso" msgid "Interpolation Method" msgstr "Interpolointimenetelmä" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Jälkikaiunta lähtötaso" @@ -1614,6 +1797,12 @@ msgstr "Matala DMA" msgid "Enable Game port" msgstr "Käytä peliporttita" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Surround-moduuli" @@ -1626,6 +1815,9 @@ msgstr "CODEC-keskeytyksen nostaminen CODEC-asennuksen yhteydessä (jotkut ohjai msgid "SB Address" msgstr "SB-osoite" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "WSS-IRQ" @@ -1710,9 +1902,15 @@ msgstr "RAMDAC-tyyppi" msgid "Blend" msgstr "Sekoitus" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Bilineaarinen suodatus" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Dithering" @@ -1755,6 +1953,33 @@ msgstr "Siirtonopeus" msgid "EMS mode" msgstr "EMS-tila" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Osoite > 2 Mt" @@ -1773,11 +1998,11 @@ msgstr "Aina valitulla nopeudella" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "BIOS-asetus + pikanäppäimet (pois päältä POSTin aikana)" -msgid "64 kB starting from F0000" -msgstr "64 kB alkaen F0000:sta" +msgid "64 KB starting from F0000" +msgstr "64 Kt alkaen F0000:sta" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB alkaen E0000:sta (osoitteen käänteinen MSB, viimeiset 64 kB ensin)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 Kt alkaen E0000:sta (osoitteen käänteinen MSB, viimeiset 64 Kt ensin)" msgid "Sine" msgstr "Sini" @@ -1843,7 +2068,7 @@ msgid "2 MB" msgstr "2 Mt" msgid "8 MB" -msgstr " 8 Mt" +msgstr "8 Mt" msgid "28 MB" msgstr "28 Mt" @@ -1911,6 +2136,15 @@ msgstr "sRGB-interpolointi" msgid "Linear interpolation" msgstr "Lineaarinen interpolointi" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 Kt" @@ -1944,6 +2178,9 @@ msgstr "Keltainen" msgid "Gray" msgstr "Harmaa" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Väri" @@ -1959,6 +2196,12 @@ msgstr "Muut kielet" msgid "Bochs latest" msgstr "Bochs uusin" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Yksivärinen ei-välitetyt" @@ -2040,6 +2283,9 @@ msgstr "Läpiviennin baudinopeus" msgid "Named Pipe (Server)" msgstr "Nimetty putki (palvelin)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "Isännän sarjaportin läpivienti" @@ -2085,6 +2331,12 @@ msgstr "IBM 8514/A-klooni (ISA)" msgid "Vendor" msgstr "Valmistaja" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "Yleinen PC/XT-muistilaajennus" @@ -2109,9 +2361,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2159,3 +2408,87 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Kiintolevyohjain:" + +#~ msgid "ZIP drives:" +#~ msgstr "ZIP-asemat:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "ZIP-levykuvat" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index fe3dc4bb4..105dfc4bc 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Pause" -msgid "E&xit..." -msgstr "&Quitter..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "&Quitter" msgid "&View" msgstr "&Vue" @@ -40,7 +43,7 @@ msgid "Hide &toolbar" msgstr "Masquer la &barre d'outils" msgid "&Resizeable window" -msgstr "Fenêtre &Redimensionnable" +msgstr "Fenêtre &redimensionnable" msgid "R&emember size && position" msgstr "S&auvegarder taille && position" @@ -60,14 +63,14 @@ msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "Spécifier dimensions..." msgid "F&orce 4:3 display ratio" -msgstr "F&orcer 4:3" +msgstr "F&orcer le ratio 4:3" msgid "&Window scale factor" -msgstr "&Echelle facteur" +msgstr "&Echelle de facteur" msgid "&0.5x" msgstr "&0.5x" @@ -99,8 +102,8 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" -msgstr "Méthode Filtre" +msgid "Fi<er method" +msgstr "Méthode de Filtre" msgid "&Nearest" msgstr "&Plus proche" @@ -112,10 +115,10 @@ msgid "Hi&DPI scaling" msgstr "Mise à l'échelle Hi&DPI" msgid "&Fullscreen" -msgstr "&Plein Ecran" +msgstr "&Plein écran" msgid "Fullscreen &stretch mode" -msgstr "Mode &Elargi plein écran" +msgstr "Mode plein écran &étiré" msgid "&Full screen stretch" msgstr "&Plein écran étiré" @@ -124,13 +127,13 @@ msgid "&4:3" msgstr "&4:3" msgid "&Square pixels (Keep ratio)" -msgstr "Pixels &carrés (Keep ratio)" +msgstr "Pixels &carrés (Conserver le ratio)" msgid "&Integer scale" -msgstr "Echelle &Entière" +msgstr "&Echelle entière" msgid "4:&3 Integer scale" -msgstr "Echelle Entière 4:&3" +msgstr "Echelle entière 4:&3" msgid "E&GA/(S)VGA settings" msgstr "Réglages E&GA/(S)VGA" @@ -139,13 +142,19 @@ msgid "&Inverted VGA monitor" msgstr "Moniteur VGA &Inversé" msgid "VGA screen &type" -msgstr "&Type Ecran VGA" +msgstr "&Type d'écran VGA" msgid "RGB &Color" -msgstr "RGB &Couleur" +msgstr "&Couleurs RGB" + +msgid "RGB (no brown)" +msgstr "" msgid "&RGB Grayscale" -msgstr "&RGB Ton de Gris" +msgstr "Niveau de Gris &RGB " + +msgid "Generic RGBI color monitor" +msgstr "" msgid "&Amber monitor" msgstr "Moniteur &Ambre" @@ -157,7 +166,7 @@ msgid "&White monitor" msgstr "Moniteur &Blanc" msgid "Grayscale &conversion type" -msgstr "Mode &Conversion tons de gris" +msgstr "Type de &conversion du niveau de Gris" msgid "BT&601 (NTSC/PAL)" msgstr "BT&601 (NTSC/PAL)" @@ -166,16 +175,16 @@ msgid "BT&709 (HDTV)" msgstr "BT&709 (HDTV)" msgid "&Average" -msgstr "&Moyenne" +msgstr "&Moyen" msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" -msgstr "Overscan CGA/PCjr/Tandy/E&GA/(S)VGA" +msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" msgid "Change contrast for &monochrome display" -msgstr "Modifier contraste affichage &monochrome" +msgstr "Modifier le contraste de l'affichage &monochrome" msgid "&Media" -msgstr "&Media" +msgstr "&Média" msgid "&Tools" msgstr "Ou&tils" @@ -187,7 +196,7 @@ msgid "&Update status bar icons" msgstr "Mettre à jour la barre de stat&us" msgid "Take s&creenshot" -msgstr "Copie &Ecran" +msgstr "Copie &d'écran" msgid "S&ound" msgstr "S&on" @@ -196,7 +205,7 @@ msgid "&Preferences..." msgstr "&Préférences..." msgid "Enable &Discord integration" -msgstr "Activer intégration &Discord" +msgstr "Activer l'intégration &Discord" msgid "Sound &gain..." msgstr "&Gain Son..." @@ -235,7 +244,7 @@ msgid "&Rewind to the beginning" msgstr "&Revenir au debut" msgid "&Fast forward to the end" -msgstr "Aller à la &Fin" +msgstr "Avance rapide jusqu'à la &Fin" msgid "E&ject" msgstr "É&jecter" @@ -244,13 +253,13 @@ msgid "&Image..." msgstr "&Image..." msgid "E&xport to 86F..." -msgstr "E&xporter vers 86F..." +msgstr "E&xport vers 86F..." msgid "&Mute" msgstr "&Couper" msgid "E&mpty" -msgstr "E&jecter" +msgstr "V&ide" msgid "Reload previous image" msgstr "Recharger image précedente" @@ -328,7 +337,7 @@ msgid "RPM mode:" msgstr "Mode RPM:" msgid "Progress:" -msgstr "Progrès:" +msgstr "Progression:" msgid "Width:" msgstr "Largeur:" @@ -384,6 +393,15 @@ msgstr "Activé (UTC)" msgid "Dynamic Recompiler" msgstr "Recompilateur dynamique" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Vidéo:" @@ -399,6 +417,9 @@ msgstr "Graphique IBM 8514/A" msgid "XGA Graphics" msgstr "Graphique XGA" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Souris:" @@ -498,17 +519,20 @@ msgstr "Port parallèle 3" msgid "Parallel port 4" msgstr "Port parallèle 4" -msgid "HD Controller:" -msgstr "Contrôleur HD:" - msgid "FD Controller:" msgstr "Contrôleur FD:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" -msgstr "Contrôleur IDE tertiaire" +msgstr "Troisième contrôleur IDE" msgid "Quaternary IDE Controller" -msgstr "Contrôleur IDE quaternair" +msgstr "Quatrième contrôleur IDE" + +msgid "Hard disk" +msgstr "" msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Cassette" msgid "Hard disks:" msgstr "Disques durs:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "&Nouveau..." @@ -583,13 +610,13 @@ msgid "Check BPB" msgstr "Vérifier BPB" msgid "CD-ROM drives:" -msgstr "Lecterus CD-ROM:" +msgstr "Lecteurs CD-ROM:" msgid "MO drives:" msgstr "Lecteurs magnéto-optiques:" -msgid "ZIP drives:" -msgstr "Lecteurs ZIP:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -598,7 +625,10 @@ msgid "ISA RTC:" msgstr "Horloge temps réel ISA:" msgid "ISA Memory Expansion" -msgstr "Extension de mémoire ISA" +msgstr "Extension de la mémoire ISA" + +msgid "ISA ROM Cards" +msgstr "" msgid "Card 1:" msgstr "Carte 1:" @@ -612,6 +642,15 @@ msgstr "Carte 3:" msgid "Card 4:" msgstr "Carte 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "Dispositif ISABugger" @@ -630,17 +669,20 @@ msgstr "Erreur fatale" msgid " - PAUSED" msgstr " - EN PAUSE" -msgid "Press %s to return to windowed mode." -msgstr "Appuyez sur %s pour revenir au mode fenêtré." - msgid "Speed" msgstr "Vitesse" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "Images ZIP" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "86Box n'a pas pu trouver d'images ROM utilisables.\n\nS'il vous plait, téléchargez un ensemble ROM et extrayez-le dans le répertoire \"roms\"." @@ -664,7 +706,7 @@ msgid "All images" msgstr "Toutes les images" msgid "Basic sector images" -msgstr "Images basiques du secteur" +msgstr "Images secteur basique" msgid "Surface images" msgstr "Images de la surface" @@ -712,22 +754,22 @@ msgid "Other removable devices" msgstr "Autres dispositifs amovibles" msgid "Other peripherals" -msgstr "Autres périfériques" +msgstr "Autres périphériques" msgid "Click to capture mouse" msgstr "Cliquer pour capturer la souris" -msgid "Press %s to release mouse" -msgstr "Appuyer sur %s pour libérer la souris" +msgid "Press %1 to release mouse" +msgstr "Appuyer sur %1 pour libérer la souris" -msgid "Press %s or middle button to release mouse" -msgstr "Appuyer sur %s ou le bouton central pour libérer la souris" +msgid "Press %1 or middle button to release mouse" +msgstr "Appuyer sur %1 ou le bouton central pour libérer la souris" msgid "Bus" msgstr "Bus" msgid "File" -msgstr "File" +msgstr "Fichier" msgid "C" msgstr "C" @@ -754,7 +796,7 @@ msgid "No PCap devices found" msgstr "Aucun dispositif PCap trouvé" msgid "Invalid PCap device" -msgstr "Dispositif PCap non valide" +msgstr "Dispositif PCap invalide" msgid "2-axis, 2-button joystick(s)" msgstr "Manette(s) avec 2 axes, 2 boutons" @@ -780,12 +822,39 @@ msgstr "Manette avec 4 axes, 4 boutons" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Système de contrôle de vol Thrustmaster" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Aucun" @@ -795,11 +864,14 @@ msgstr "%1 Mo (CTS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Disquette %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Disquette %1 (%2): %3" + msgid "Advanced sector images" -msgstr "Images du secteur avancés" +msgstr "Images secteur avancé" msgid "Flux images" -msgstr "Images du flux" +msgstr "Images Flux" msgid "Are you sure you want to hard reset the emulated machine?" msgstr "Etes-vous sûr de vouloir réinitialiser la machine émulée ?" @@ -816,6 +888,9 @@ msgstr "Impossible d'initialiser GhostPCL" msgid "MO %1 (%2): %3" msgstr "Magnéto-optique %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&Magnéto-optique %1 (%2): %3" + msgid "MO images" msgstr "Images magnéto-optiques" @@ -847,7 +922,7 @@ 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 é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\nAvec les contributions de Sarah Walker, leilei, JohnElliott, greatpsycho et d'autres.\n\nLibéré sous la licence GNU General Public License version 2 ou ultérieure. Pour plus d'informations, voir le fichier LICENSE." +msgstr "Un émulateur d'ordinateurs du passé\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\nAvec les contributions de Sarah Walker, leilei, JohnElliott, greatpsycho et d'autres.\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" @@ -856,7 +931,7 @@ msgid "Make sure %1 is installed and that you are on a %1-compatible network con msgstr "Assurez-vous que %1 est installé et que vous utilisez une connexion réseau compatible avec %1." msgid "Invalid configuration" -msgstr "Configuration non valide" +msgstr "Configuration invalide" msgid "%1 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 "%1 est nécessaire pour la conversion automatique des fichiers PostScript en PDF.\n\nTous les documents envoyés à l'imprimante générique PostScript seront sauvés en tant que fichiers PostScript (.ps)." @@ -864,9 +939,6 @@ msgstr "%1 est nécessaire pour la conversion automatique des fichiers PostScrip msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 est nécessaire pour la conversion automatique des fichiers PCL en PDF.\n\nTous les documents envoyés à l'imprimante générique PCL seront sauvés en tant quefichiers Printer Command Language (.pcl)." -msgid "Entering fullscreen mode" -msgstr "Entrer en mode plein écran" - msgid "Don't show this message again" msgstr "Ne pas montrer ce message à nouveau" @@ -895,7 +967,7 @@ msgid "You are loading an unsupported configuration" msgstr "Vous chargez une configuration non prise en charge" 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 "Le filtrage du type du processeur sur la base de la machine sélectionnée est désactivé pur cette machine émulée.\n\nCela permet de sélectionner un processeur qui est sinon incompatible avec la machine sélectionné. Cependant, il pourrait y avoir des incompatibilités avec le BIOS de la machine ou autres logiciels.\n\nL'activation de cette configuration non officiellement prise en charge implique que tout rapport de bogue peut être fermé comme étant invalide." +msgstr "Le filtre du type du processeur basé par rapport à la machine sélectionnée est désactivé pour cette machine émulée.\n\nCela permet de sélectionner un processeur qui est de base incompatible avec la machine sélectionné. Cependant, il pourrait y avoir des incompatibilités avec le BIOS de la machine ou autres logiciels.\n\nL'activation de cette configuration non officiellement prise en charge implique que tout rapport de bogue peut être fermé étant considéré comme invalide." msgid "Continue" msgstr "Continuer" @@ -903,12 +975,18 @@ msgstr "Continuer" msgid "Cassette: %1" msgstr "Cassette: %1" +msgid "C&assette: %1" +msgstr "C&assette: %1" + msgid "Cassette images" msgstr "Images cassette" msgid "Cartridge %1: %2" msgstr "Cartouche %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Car&touche %1: %2" + msgid "Cartridge images" msgstr "Images cartouche" @@ -930,6 +1008,9 @@ msgstr "Hard reset" msgid "ACPI shutdown" msgstr "Arrêt ACPI" +msgid "ACP&I shutdown" +msgstr "Arrêt ACP&I" + msgid "Hard disk (%1)" msgstr "Disque dur (%1)" @@ -988,7 +1069,7 @@ msgid "Remember to partition and format the newly-created drive." msgstr "N'oubliez pas de partitionner et de formater le nouveau disque créé." msgid "The selected file will be overwritten. Are you sure you want to use it?" -msgstr "Le fichier sélectionné sera écrasé. Etes-vous sûr de vouloir l'utiliser?" +msgstr "Le fichier sélectionné sera écrasé. Etes-vous sûr de vouloir l'utiliser ?" msgid "Unsupported disk image" msgstr "Image disque non prise en charge" @@ -1009,13 +1090,13 @@ msgid "HDX image" msgstr "Image HDX" msgid "Fixed-size VHD" -msgstr "VHD à taille fixe" +msgstr "VHD de taille fixe" msgid "Dynamic-size VHD" -msgstr "VHD à taille dynamique" +msgstr "VHD de taille dynamique" msgid "Differencing VHD" -msgstr "VHD à différenciation" +msgstr "VHD différentiel" msgid "(N/A)" msgstr "(N.D.)" @@ -1030,13 +1111,13 @@ msgid "HDX image (.hdx)" msgstr "Image HDX (.hdx)" msgid "Fixed-size VHD (.vhd)" -msgstr "VHD à taille fixe (.vhd)" +msgstr "VHD de taille fixe (.vhd)" msgid "Dynamic-size VHD (.vhd)" -msgstr "VHD à taille dynamique (.vhd)" +msgstr "VHD de taille dynamique (.vhd)" msgid "Differencing VHD (.vhd)" -msgstr "VHD à différenciation (.vhd)" +msgstr "VHD différentiel (.vhd)" msgid "Large blocks (2 MB)" msgstr "Grands Blocs (2 Mo)" @@ -1051,7 +1132,7 @@ msgid "Select the parent VHD" msgstr "Sélectionnez le VHD parent" 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 "Il est possible que l'image parente ai été modifiée après la création de l'image à différenciation.\n\nIl est même possible que les fichiers de l’image ont été déplacés ou copiés ou il existe un bogue dans le programme qui a créé ce disque.\n\nVoulez-vous réparer l'horodatage?" +msgstr "Il est possible que l'image parente ai été modifiée après la création de l'image différentielle.\n\nIl est même possible que les fichiers de l’image ont été déplacés ou copiés ou il existe un bogue dans le programme qui a créé ce disque.\n\nVoulez-vous réparer l'horodatage ?" msgid "Parent and child disk timestamps do not match" msgstr "Les horodatages des disques parents et enfants ne correspondent pas" @@ -1077,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 Ko" @@ -1192,7 +1276,7 @@ msgid "WinBox is no longer supported" msgstr "WinBox n'est plus pris en charge" msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." -msgstr "Le développement du gestionnaire WinBox s'est arrêté en 2022 en raison d'un manque de mainteneurs. Comme nous concentrons nos efforts sur l'amélioration de 86Box, nous avons pris la décision de ne plus supporter WinBox en tant que gestionnaire.\n\nAucune mise à jour ne sera fournie par WinBox, et vous pourriez rencontrer des comportements incorrects si vous continuez à l'utiliser avec des versions plus récentes de 86Box. Tous les rapports de bogues relatifs au comportement de WinBox seront classés comme non valides.\n\nAllez sur 86box.net pour une liste d'autres gestionnaires que vous pouvez utiliser." +msgstr "Le développement du gestionnaire WinBox s'est arrêté en 2022 en raison d'un manque de mainteneurs. Comme nous concentrons nos efforts sur l'amélioration de 86Box, nous avons pris la décision de ne plus supporter WinBox en tant que gestionnaire.\n\nAucune mise à jour ne sera fournie par WinBox et vous pourriez rencontrer des comportements incorrects si vous continuez à l'utiliser avec des versions plus récentes de 86Box. Tous les rapports de bogues relatifs au comportement de WinBox seront classés comme non valides.\n\nAllez sur 86box.net pour une liste d'autres gestionnaires que vous pouvez utiliser." msgid "Generate" msgstr "Générer" @@ -1215,41 +1299,41 @@ msgstr "Dispositifs MCA" msgid "List of MCA devices:" msgstr "Liste des dispositifs MCA :" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Outil Tablette" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "A propos de Qt" +msgid "About &Qt" +msgstr "A propos de &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "Dispositifs MCA..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Afficher les moniteurs non primaires" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Ouvrir le dossier des captures d'écran..." -msgid "Apply fullscreen stretch mode when maximized" -msgstr "Appliquer le mode elargi plein écran lorsque l'écran est maximisé" +msgid "Appl&y fullscreen stretch mode when maximized" +msgstr "Appliquer le mode élargi plein écran lorsque la fenêtre est maximisée" -msgid "Cursor/Puck" -msgstr "Curseur/Palette" +msgid "&Cursor/Puck" +msgstr "&Curseur/Palette" -msgid "Pen" -msgstr "Stylo" +msgid "&Pen" +msgstr "&Stylo" msgid "Host CD/DVD Drive (%1:)" -msgstr "Lecteur CD/DVD hôte (%1:)" +msgstr "&Lecteur CD/DVD hôte (%1:)" msgid "&Connected" msgstr "&Connecté" -msgid "Clear image history" -msgstr "Effacer l'historique de l'image" +msgid "Clear image &history" +msgstr "Effacer l'&historique de l'image" msgid "Create..." msgstr "Créer..." @@ -1266,8 +1350,11 @@ msgstr "Pilote NULL" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" -msgstr "Comportement de rendu" +msgstr "Comportement du rendu" msgid "Use target framerate:" msgstr "Utiliser le taux de rafraîchissement cible:" @@ -1303,10 +1390,10 @@ msgid "Error initializing OpenGL" msgstr "Erreur d'initialisation d'OpenGL" msgid "\nFalling back to software rendering." -msgstr "\nSe rabattre sur le rendu logiciel." +msgstr "\nRevenir au rendu logiciel." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Lors de la sélection d'images multimédia (CD-ROM, disquette, etc.), la boîte de dialogue d'ouverture démarrera dans le même répertoire que le fichier de configuration de 86Box. Ce paramètre ne fera probablement une différence que sur macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Lors de la sélection d'images multimédia (CD-ROM, disquette, etc.), la boîte de dialogue d'ouverture démarrera dans le même répertoire que le fichier de configuration de 86Box. Ce paramètre ne fera probablement une différence que sur macOS.

" msgid "This machine might have been moved or copied." msgstr "Cette machine peut avoir été déplacée ou copiée." @@ -1360,19 +1447,37 @@ msgid "Novell NetWare 2.x Key Card" msgstr "Carte clé Novell NetWare 2.x" msgid "Serial port passthrough 1" -msgstr "Passage du port série 1" +msgstr "Transfert du port série 1" msgid "Serial port passthrough 2" -msgstr "Passage du port série 2" +msgstr "Transfert du port série 2" msgid "Serial port passthrough 3" -msgstr "Passage du port série 3" +msgstr "Transfert du port série 3" msgid "Serial port passthrough 4" -msgstr "Passage du port série 4" +msgstr "Transfert du port série 4" -msgid "Renderer options..." -msgstr "Options de rendu..." +msgid "Renderer &options..." +msgstr "Options du rendu..." + +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" msgid "Logitech/Microsoft Bus Mouse" msgstr "Souris bus Logitech/Microsoft" @@ -1383,18 +1488,30 @@ msgstr "Souris bus Microsoft (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Souris série Mouse Systems" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Souris série Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Souris série Logitech" msgid "PS/2 Mouse" msgstr "Souris PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (série)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Modem standard conforme à la norme Hayes" @@ -1414,17 +1531,59 @@ msgid "OPL4-ML Daughterboard" msgstr "Carte fille OPL4-ML" msgid "System MIDI" -msgstr "MIDI de système" +msgstr "Système MIDI" msgid "MIDI Input Device" msgstr "Dispositif d'entrée MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "Adresse BIOS" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "Activer les écritures au ROM d'extension du BIOS" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Adresse" @@ -1434,11 +1593,23 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "Révision BIOS" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Traduire 26 -> 17" msgid "Language" -msgstr "Language" +msgstr "Langage" msgid "Enable backlight" msgstr "Activer le rétro-éclairage" @@ -1449,6 +1620,18 @@ msgstr "Inversion des couleurs" msgid "BIOS size" msgstr "Taille du BIOS" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "Mapper C0000-C7FFF en tant qu'UMB" @@ -1477,7 +1660,7 @@ msgid "MIDI Real time" msgstr "MIDI en temps réel" msgid "MIDI Thru" -msgstr "Passage de la entrée MIDI" +msgstr "Transfert MIDI" msgid "MIDI Clockout" msgstr "Horloge MIDI" @@ -1492,10 +1675,10 @@ msgid "Chorus" msgstr "Chœur" msgid "Chorus Voices" -msgstr "Voix de chœur" +msgstr "Voix du chœur" msgid "Chorus Level" -msgstr "Niveau de chœur" +msgstr "Niveau du chœur" msgid "Chorus Speed" msgstr "Vitesse du chœur" @@ -1524,8 +1707,11 @@ msgstr "Niveau de réverbération" msgid "Interpolation Method" msgstr "Méthode d'interpolation" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" -msgstr "Gain de sortie de réverbération" +msgstr "Gain de sortie réverbération" msgid "Reversed stereo" msgstr "Stéréo inversée" @@ -1561,7 +1747,7 @@ msgid "MAC Address" msgstr "Adresse MAC" msgid "MAC Address OUI" -msgstr "OUI de adresse MAC" +msgstr "Adresse MAC OUI" msgid "Enable BIOS" msgstr "Activer BIOS" @@ -1573,7 +1759,7 @@ msgid "TCP/IP listening port" msgstr "Port d'écoute TCP/IP" msgid "Phonebook File" -msgstr "Fichier de répertoire" +msgstr "Fichier d'annuaire" msgid "Telnet emulation" msgstr "Émulation de Telnet" @@ -1611,6 +1797,12 @@ msgstr "DMA bas" msgid "Enable Game port" msgstr "Activer le port de jeu" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Module Surround" @@ -1623,6 +1815,9 @@ msgstr "Lever l'interruption CODEC lors de la configuration du CODEC (nécessair msgid "SB Address" msgstr "Adresse SB" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "IRQ WSS" @@ -1651,10 +1846,10 @@ msgid "High DMA" msgstr "DMA haut" msgid "Control PC speaker" -msgstr "Contrôler l'haut-parleur du PC" +msgstr "Contrôler le haut-parleur du PC" msgid "Memory size" -msgstr "Taille de mémoire" +msgstr "Taille mémoire" msgid "EMU8000 Address" msgstr "Adresse EMU8000" @@ -1707,9 +1902,15 @@ msgstr "Type de RAMDAC" msgid "Blend" msgstr "Mélanger" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Filtrage bilinéaire" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Tramage" @@ -1720,10 +1921,10 @@ msgid "Voodoo type" msgstr "Type de Voodoo" msgid "Framebuffer memory size" -msgstr "Taille de la mémoire du tampon d'images" +msgstr "Taille mémoire du tampon d'images" msgid "Texture memory size" -msgstr "Taille de la mémoire des textures" +msgstr "Taille mémoire des textures" msgid "Dither subtraction" msgstr "Soustraction de tramage" @@ -1732,7 +1933,7 @@ msgid "Screen Filter" msgstr "Filtre d'écran" msgid "Render threads" -msgstr "Fils de rendu" +msgstr "Tâches du rendu" msgid "SLI" msgstr "SLI" @@ -1752,6 +1953,33 @@ msgstr "Vitesse de transfert" msgid "EMS mode" msgstr "Mode EMS" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Adresse pour > 2 MB" @@ -1770,11 +1998,11 @@ msgstr "Toujours à la vitesse sélectionnée" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Paramètres du BIOS + touches de raccourci (désactivées pendant le POST)" -msgid "64 kB starting from F0000" -msgstr "64 ko à partir de F0000" +msgid "64 KB starting from F0000" +msgstr "64 Ko à partir de F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 ko à partir de E0000 (adresse MSB inversée, derniers 64KB en premier)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 Ko à partir de E0000 (adresse MSB inversée, derniers 64 Ko en premier)" msgid "Sine" msgstr "Sinusoïdale" @@ -1786,10 +2014,10 @@ msgid "Linear" msgstr "Linéaire" msgid "4th Order" -msgstr "Du 4e ordre" +msgstr "4e ordre" msgid "7th Order" -msgstr "Du 7e ordre" +msgstr "7e ordre" msgid "Non-timed (original)" msgstr "Non temporisé (original)" @@ -1810,7 +2038,7 @@ msgid "Five + Wheel" msgstr "Cinq + molette" msgid "Five + 2 Wheels" -msgstr "" +msgstr "Cinq + 2 molettes" msgid "A3 - SMT2 Serial / SMT3(R)V" msgstr "A3 - SMT2 série / SMT3(R)V" @@ -1906,7 +2134,16 @@ msgid "sRGB interpolation" msgstr "Interpolation sRVB" msgid "Linear interpolation" -msgstr "Interpolation linéairee" +msgstr "Interpolation linéaire" + +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" msgid "128 KB" msgstr "128 Ko" @@ -1921,7 +2158,7 @@ msgid "Monochrome (5151/MDA) (amber)" msgstr "Monochrome (5151/MDA) (ambre)" msgid "Color 40x25 (5153/CGA)" -msgstr "Couler 40x25 (5153/CGA)" +msgstr "Couleur 40x25 (5153/CGA)" msgid "Color 80x25 (5153/CGA)" msgstr "Couleur 80x25 (5153/CGA)" @@ -1941,6 +2178,9 @@ msgstr "Ambre" msgid "Gray" msgstr "Gris" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Couleur" @@ -1956,14 +2196,20 @@ msgstr "Autres langues" msgid "Bochs latest" msgstr "Bochs dernière" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Monochrome non entrelacé" msgid "Color Interlaced" -msgstr "Couler entrelacé" +msgstr "Couleur entrelacée" msgid "Color Non-Interlaced" -msgstr "Couleur non entrelacé" +msgstr "Couleur non entrelacée" msgid "3Dfx Voodoo Graphics" msgstr "Graphique 3dfx Voodoo" @@ -1996,7 +2242,7 @@ msgid "Stereo LPT DAC" msgstr "Convertisseur numérique stéréo LPT" msgid "Generic Text Printer" -msgstr "Imprimante Texte générique" +msgstr "Imprimante texte générique" msgid "Generic ESC/P Dot-Matrix Printer" msgstr "Imprimante matricielle générique ESC/P" @@ -2014,16 +2260,16 @@ msgid "Protection Dongle for Savage Quest" msgstr "Clé de protection pour Savage Quest" msgid "Serial Passthrough Device" -msgstr "Dispositif de passage du port série" +msgstr "Dispositif de transfert du port série" msgid "Passthrough Mode" -msgstr "Mode de passage" +msgstr "Mode de transfert" msgid "Host Serial Device" -msgstr "Dispositif sériel de l'hôte" +msgstr "Dispositif série de l'hôte" msgid "Name of pipe" -msgstr "Nom du tuyau" +msgstr "Nom du pipeline" msgid "Data bits" msgstr "Bits de données" @@ -2032,13 +2278,16 @@ msgid "Stop bits" msgstr "Bits d'arrêt" msgid "Baud Rate of Passthrough" -msgstr "Taux de bauds du passage" +msgstr "Taux de bauds du transfert" msgid "Named Pipe (Server)" -msgstr "Tuyau nommé (serveur)" +msgstr "Pipeline nommé (serveur)" + +msgid "Named Pipe (Client)" +msgstr "" msgid "Host Serial Passthrough" -msgstr "Passage du port série de l'hôte" +msgstr "Transfert du port série de l'hôte" msgid "E&ject %1" msgstr "É&jecter %1" @@ -2082,14 +2331,20 @@ msgstr "Clone IBM 8514/A (ISA)" msgid "Vendor" msgstr "Fabricant" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" -msgstr "Extension de mémoire générique PC/XT" +msgstr "Extension mémoire générique PC/XT" msgid "Generic PC/AT Memory Expansion" -msgstr "Extension de mémoire générique PC/AT" +msgstr "Extension mémoire générique PC/AT" msgid "Unable to find Dot-Matrix fonts" -msgstr "Impossible de trouver les polices matricielles" +msgstr "Impossible de trouver les polices matricielles." msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for the emulation of the Generic ESC/P Dot-Matrix Printer." msgstr "Les polices TrueType dans le répertoire \"roms/printer/fonts\" sont nécessaires à l'émulation de l'imprimante générique ESC/P matricielle." @@ -2106,14 +2361,11 @@ msgstr "Demander confirmation avant Hard Reset" msgid "Ask for confirmation before quitting" msgstr "Demander confirmation avant de quitter" -msgid "Display hotkey message when entering full-screen mode" -msgstr "Afficher Raccourcis Clavier avant de passer en plein écran" - msgid "Options" msgstr "Options" msgid "Model" -msgstr "Modèle" +msgstr "" msgid "Model:" msgstr "Modèle:" @@ -2125,10 +2377,10 @@ msgid "GLSL Error" msgstr "Erreur GLSL" msgid "Could not load shader: %1" -msgstr "Impossible de charger le shaker %1" +msgstr "Impossible de charger le shader %1" msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "OpenGL version 3.0 ou supérieur requis. Version installée: %1.%2" +msgstr "OpenGL version 3.0 ou supérieure requis. Version installée: %1.%2" msgid "Could not load texture: %1" msgstr "Impossible de charger la texture %1" @@ -2156,3 +2408,87 @@ msgstr "Descendre" msgid "Could not load file %1" msgstr "Impossible de charger le fichier %1" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Contrôleur HD:" + +#~ msgid "ZIP drives:" +#~ msgstr "Lecteurs ZIP:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "Images ZIP" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 1eecaa2d0..cd8f2d621 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Pauza" -msgid "E&xit..." -msgstr "Iz&laz..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "Iz&laz" msgid "&View" msgstr "&Pogled" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0 jezgra)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "Odrediti veličinu..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "Metoda filtriranja" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "&Tip zaslona VGA" msgid "RGB &Color" msgstr "RGB u &boji" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "&RGB u nijansama sive boje" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "&Jantarni zaslon" @@ -384,6 +393,15 @@ msgstr "Uključeno (UTC)" msgid "Dynamic Recompiler" msgstr "Dinamički rekompilator" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Video:" @@ -399,6 +417,9 @@ msgstr "IBM 8514/A grafika" msgid "XGA Graphics" msgstr "XGA grafika" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Miš:" @@ -498,18 +519,21 @@ msgstr "Paralelna vrata 3" msgid "Parallel port 4" msgstr "Paralelna vrata 4" -msgid "HD Controller:" -msgstr "Kontroler tvrdog diska:" - msgid "FD Controller:" msgstr "Kontroler diskete:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "Tercijarni IDE kontroler" msgid "Quaternary IDE Controller" msgstr "Kvaternarni IDE kontroler" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Audio kaseta" msgid "Hard disks:" msgstr "Tvrdi diskovi:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "&Novi..." @@ -588,8 +615,8 @@ msgstr "CD-ROM pogoni:" msgid "MO drives:" msgstr "MO pogoni:" -msgid "ZIP drives:" -msgstr "ZIP pogoni:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "Sat stvarnog vremena (RTC):" msgid "ISA Memory Expansion" msgstr "Proširenje memorije ISA" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Kartica 1:" @@ -612,6 +642,15 @@ msgstr "Kartica 3:" msgid "Card 4:" msgstr "Kartica 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "Uređaj ISABugger" @@ -630,17 +669,20 @@ msgstr "Fatalna greška" msgid " - PAUSED" msgstr " - ZASTAO" -msgid "Press %s to return to windowed mode." -msgstr "Pritisnite %s za povratak u prozorski način rada." - msgid "Speed" msgstr "Brzina" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "ZIP slike" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "86Box nije mogao pronaći upotrebljive ROM datoteke.\n\nMolimte posjetite sknite paket s ROM datotekama i ekstrahirajte paket u mapu \"roms\"." @@ -717,11 +759,11 @@ msgstr "Ostali periferni uređaji" msgid "Click to capture mouse" msgstr "Kliknite da uhvatite miš" -msgid "Press %s to release mouse" -msgstr "Pritisnite %s za otpustanje miša" +msgid "Press %1 to release mouse" +msgstr "Pritisnite %1 za otpustanje miša" -msgid "Press %s or middle button to release mouse" -msgstr "Pritisnite %s ili srednji gumb miša za otpuštanje miša" +msgid "Press %1 or middle button to release mouse" +msgstr "Pritisnite %1 ili srednji gumb miša za otpuštanje miša" msgid "Bus" msgstr "Bus" @@ -768,7 +810,7 @@ msgstr "Palica za igru s 2 osi, 6 tipke" msgid "2-axis, 8-button joystick" msgstr "Palica za igru s 2 osi, 8 tipke" -msgid "3-axis, 2-button joystick(s)" +msgid "3-axis, 2-button joystick" msgstr "Palica za igru s 3 osi, 2 tipke" msgid "3-axis, 4-button joystick" @@ -780,12 +822,39 @@ msgstr "Palica za igru s 4 osi, 4 tipke" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Bez" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Disketa %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Disketa %1 (%2): %3" + msgid "Advanced sector images" msgstr "Napredne sektorske slike" @@ -816,6 +888,9 @@ msgstr "Nije moguće inicijalizirati GhostPCL" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "MO slike" @@ -864,9 +939,6 @@ msgstr "%1 je potrebno za automatsku konverziju PostScript datoteke u PDF datote msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 je potrebno za automatsku konverziju PCL datoteke u PDF datoteke.\n\nSvi dokumenti poslani na generički PCL pisač bit će spremljeni kao Printer Command Language (.pcl) datoteke." -msgid "Entering fullscreen mode" -msgstr "Ulazim u cijelozaslonski način" - msgid "Don't show this message again" msgstr "Ne pokazi više ovu poruku" @@ -903,12 +975,18 @@ msgstr "Nastavi" msgid "Cassette: %1" msgstr "Audio kaseta: %1" +msgid "C&assette: %1" +msgstr "&Audio kaseta: %1" + msgid "Cassette images" msgstr "Slike audio kasete" msgid "Cartridge %1: %2" msgstr "Kaseta %1: %2" +msgid "Car&tridge %1: %2" +msgstr "&Kaseta %1: %2" + msgid "Cartridge images" msgstr "Slike kasete" @@ -930,6 +1008,9 @@ msgstr "Ponovno pokretanje" msgid "ACPI shutdown" msgstr "ACPI bazirano gašenje" +msgid "ACP&I shutdown" +msgstr "ACP&I bazirano gašenje" + msgid "Hard disk (%1)" msgstr "Tvrdi disk (%1)" @@ -1077,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 KB" @@ -1215,41 +1299,41 @@ msgstr "Uređaji MCA" msgid "List of MCA devices:" msgstr "Spisak uređaja MCA:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Alat za tablet" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "O programu Qt" +msgid "About &Qt" +msgstr "O programu &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "Uređaji MCA ..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Prikaži neprimarne monitore" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Otvori mapu snimaka zaslona..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Primijeni način cijelozaslonskog rastezanja u maksimiziranom načinu" -msgid "Cursor/Puck" -msgstr "Kursor/Pak" +msgid "&Cursor/Puck" +msgstr "&Kursor/Pak" -msgid "Pen" -msgstr "Olovka" +msgid "&Pen" +msgstr "&Olovka" -msgid "Host CD/DVD Drive (%1:)" -msgstr "CD/DVD pogon nositelja (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "CD/DVD pogon &nositelja (%1:)" msgid "&Connected" msgstr "&Povezan" -msgid "Clear image history" -msgstr "Očisti povijest slika" +msgid "Clear image &history" +msgstr "Očisti &povijest slika" msgid "Create..." msgstr "Stvori..." @@ -1266,6 +1350,9 @@ msgstr "Nulti upravljački program" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "Ponašanje rendera" @@ -1305,8 +1392,8 @@ msgstr "Nije moguće inicijalizirati OpenGL" msgid "\nFalling back to software rendering." msgstr "\nVraća se na softverski renderer." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Prilikom odabira medijskih slika (CD-ROM, diskete itd.), otvoreni dijalog zopočet će u istom direktoriju kao i konfiguracijska datoteka 86Box-a. Razlika će vjerojatno biti primjetna samo na macOS-u.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Prilikom odabira medijskih slika (CD-ROM, diskete itd.), otvoreni dijalog zopočet će u istom direktoriju kao i konfiguracijska datoteka 86Box-a. Razlika će vjerojatno biti primjetna samo na macOS-u.

" msgid "This machine might have been moved or copied." msgstr "Ovaj je sistem mogao biti premješten ili kopiran." @@ -1371,9 +1458,27 @@ msgstr "Prolaz serijskih vrata 3" msgid "Serial port passthrough 4" msgstr "Prolaz serijskih vrata 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Opcije rendera..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Sabirnički miš Logitech/Microsoft" @@ -1383,18 +1488,30 @@ msgstr "Sabirnički miš Microsoft (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Serijski miš Mouse Systems" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Serijski miš Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Serijski miš Logitech" msgid "PS/2 Mouse" msgstr "Miš PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (serijski)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Standardni modem, usklađen s standardom Hayesom" @@ -1419,12 +1536,54 @@ msgstr "Sistemski MIDI" msgid "MIDI Input Device" msgstr "Ulazni uređaj MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "Adresa BIOS-a" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "Omogući pisanje u ROM proširenja BIOS-a" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Adresa" @@ -1434,6 +1593,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "Revizija BIOS-a" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Prevedi 26 -> 17" @@ -1449,6 +1620,18 @@ msgstr "Invertiraj boje" msgid "BIOS size" msgstr "Veličina BIOS-a" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "Mapiraj C0000-C7FFF kao UMB" @@ -1524,6 +1707,9 @@ msgstr "Nivo odjeka" msgid "Interpolation Method" msgstr "Metoda interpolacije" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Pojačavanje izlaza odjeka" @@ -1611,6 +1797,12 @@ msgstr "Niski DMA" msgid "Enable Game port" msgstr "Omogoći vrata za igru" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Modul Surround" @@ -1623,6 +1815,9 @@ msgstr "Podigni prekid CODEC na postavljanju CODEC-a (potrebno nekim upravljačk msgid "SB Address" msgstr "Adresa SB-a" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "IRQ WSS-a" @@ -1707,9 +1902,15 @@ msgstr "Vrsta RAMDAC-a" msgid "Blend" msgstr "Miješaj" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Bilinearno filtriranje" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Podrhtavanje" @@ -1752,6 +1953,33 @@ msgstr "Brzina prijenosa" msgid "EMS mode" msgstr "Načina EMS" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Adresa za > 2 MB" @@ -1770,11 +1998,11 @@ msgstr "Uvijek na odabranoj brzini" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Konfiguracija BIOS-a + Tipkovni prečaci (onemogućeni tekom POST-a)" -msgid "64 kB starting from F0000" -msgstr "64 kB od F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB od F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB od E0000 (MSB adrese invertiran, poslednjih 64KB prvo)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB od E0000 (MSB adrese invertiran, poslednjih 64 KB prvo)" msgid "Sine" msgstr "Sinusni" @@ -1840,7 +2068,7 @@ msgid "2 MB" msgstr "2 MB" msgid "8 MB" -msgstr " 8 MB" +msgstr "8 MB" msgid "28 MB" msgstr "28 MB" @@ -1908,6 +2136,15 @@ msgstr "Interpolacija sRGB" msgid "Linear interpolation" msgstr "Linearna interpolacija" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2178,9 @@ msgstr "Jantarna" msgid "Gray" msgstr "Siva" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Bojna" @@ -1956,6 +2196,12 @@ msgstr "Ostali jezici" msgid "Bochs latest" msgstr "Bochs poslednji" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Crno-biljeli bez preplitanja" @@ -2037,6 +2283,9 @@ msgstr "Baudova brzina prolaza" msgid "Named Pipe (Server)" msgstr "Imenovani vod (server)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "Prolaz serijskih vrata nositelja" @@ -2082,6 +2331,12 @@ msgstr "Klon IBM 8514/A (ISA)" msgid "Vendor" msgstr "Proizvođać" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "Generičko proširenje memorije PC/XT" @@ -2106,9 +2361,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2156,3 +2408,87 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Kontroler tvrdog diska:" + +#~ msgid "ZIP drives:" +#~ msgstr "ZIP pogoni:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "ZIP slike" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index 43a1fd9ba..e87fc01fe 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Szüneteltetés" -msgid "E&xit..." -msgstr "&Kilépés..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "&Kilépés" msgid "&View" msgstr "&Nézet" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "Méretek kézi megadása..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "Szűrési mód" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "VGA képernyő &típusa" msgid "RGB &Color" msgstr "RGB &színes" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "&RGB szürkeárnyalatos" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "&Gyömbér kijelző" @@ -384,6 +393,15 @@ msgstr "Engedélyezve (UTC)" msgid "Dynamic Recompiler" msgstr "Dinamikus újrafordítás" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Videokártya:" @@ -399,6 +417,9 @@ msgstr "IBM 8514/A-gyorsítókártya" msgid "XGA Graphics" msgstr "XGA-gyorsítókártya" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Egér:" @@ -498,18 +519,21 @@ msgstr "Párhuzamos port 3" msgid "Parallel port 4" msgstr "Párhuzamos port 4" -msgid "HD Controller:" -msgstr "Merevl.-vezérlő:" - msgid "FD Controller:" msgstr "Floppy-vezérlő:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "Harmadlagos IDE-vezérlő" msgid "Quaternary IDE Controller" msgstr "Negyedleges IDE-vezérlő" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Magnókazetta" msgid "Hard disks:" msgstr "Merevlemezek:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "&Új..." @@ -588,8 +615,8 @@ msgstr "CD-ROM meghajtók:" msgid "MO drives:" msgstr "MO-meghajtók:" -msgid "ZIP drives:" -msgstr "ZIP-meghajtók:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA RTC (óra):" msgid "ISA Memory Expansion" msgstr "ISA memóriabővítők" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Kártya 1:" @@ -612,6 +642,15 @@ msgstr "Kártya 3:" msgid "Card 4:" msgstr "Kártya 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "ISABugger eszköz" @@ -630,17 +669,20 @@ msgstr "Végzetes hiba" msgid " - PAUSED" msgstr " - SZÜNETELT" -msgid "Press %s to return to windowed mode." -msgstr "Használja a %s gombokat az ablakhoz való visszatéréshez." - msgid "Speed" msgstr "Sebesség" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "ZIP-lemezképek" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "A 86Box nem talált használható ROM-képeket\n\nKérem töltse le a ROM készletet és bontsa ki a \"roms\" könyvtárba." @@ -717,11 +759,11 @@ msgstr "Egyéb perifériák" msgid "Click to capture mouse" msgstr "Kattintson az egér elfogásához" -msgid "Press %s to release mouse" -msgstr "Nyomja meg az %s-t az egér elengédéséhez" +msgid "Press %1 to release mouse" +msgstr "Nyomja meg az %1-t az egér elengédéséhez" -msgid "Press %s or middle button to release mouse" -msgstr "Nyomja meg az %s-t vagy a középső gombot az egér elengédéséhez" +msgid "Press %1 or middle button to release mouse" +msgstr "Nyomja meg az %1-t vagy a középső gombot az egér elengédéséhez" msgid "Bus" msgstr "Busz" @@ -768,8 +810,8 @@ msgstr "2-tengelyes, 6-gombos játékvezérlő" msgid "2-axis, 8-button joystick" msgstr "2-tengelyes, 8-gombos játékvezérlő" -msgid "3-axis, 2-button joystick(s)" -msgstr "3-tengelyes, 2-gombos játékvezérlő(k)" +msgid "3-axis, 2-button joystick" +msgstr "3-tengelyes, 2-gombos játékvezérlő" msgid "3-axis, 4-button joystick" msgstr "3-tengelyes, 4-gombos játékvezérlő" @@ -780,12 +822,39 @@ msgstr "4-tengelyes, 4-gombos játékvezérlő" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Nincs" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Floppy %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Floppy %1 (%2): %3" + msgid "Advanced sector images" msgstr "Továbbfejlesztett szektor képek" @@ -816,6 +888,9 @@ msgstr "Nem sikerült inicializálni a GhostPCL-et" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "MO-képfájlok" @@ -861,12 +936,9 @@ msgstr "Érvénytelen konfiguráció" msgid "%1 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 "%1 szükséges a PostScript fájlok PDF formátumba való automatikus konvertálásához.\n\nAz általános PostScript nyomtatóra küldött dokumentumok PostScript (.ps) fájlként kerülnek mentésre." -msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Lnaugage (.pcl) files." +msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 szükséges a PCL fájlok PDF formátumba való automatikus konvertálásához.\n\nAz általános PCL nyomtatóra küldött dokumentumok Printer Command Language (.pcl) fájlként kerülnek mentésre." -msgid "Entering fullscreen mode" -msgstr "Teljes képernyős módra váltás" - msgid "Don't show this message again" msgstr "Ne jelenítse meg újra ezt az üzenetet " @@ -903,6 +975,9 @@ msgstr "Folytatás" msgid "Cassette: %1" msgstr "Magnókazetta: %1" +msgid "C&assette: %1" +msgstr "M&agnókazetta: %1" + msgid "Cassette images" msgstr "Magnókazetta-képek" @@ -930,6 +1005,9 @@ msgstr "Hardveres újraindítás" msgid "ACPI shutdown" msgstr "ACPI leállítás" +msgid "ACP&I shutdown" +msgstr "ACP&I leállítás" + msgid "Hard disk (%1)" msgstr "Merevlemez (%1)" @@ -1077,6 +1155,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 KB" @@ -1215,41 +1296,41 @@ msgstr "MCA eszközök" msgid "List of MCA devices:" msgstr "Az MCA-eszközök listája:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Tablet eszköz" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "A Qt-ről" +msgid "About &Qt" +msgstr "A &Qt-ről" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "MCA eszközök..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Nem elsődleges monitorok megjelenítése" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Nyissa meg a képernyőképek mappát..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Teljes képernyős méretezés alkalmazása maximalizáláskor" -msgid "Cursor/Puck" -msgstr "Cursor/Puck" +msgid "&Cursor/Puck" +msgstr "&Cursor/Puck" -msgid "Pen" -msgstr "Toll" +msgid "&Pen" +msgstr "&Toll" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Gazdag CD/DVD-meghajtó (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Gazdag CD/DVD-meghajtó (%1:)" msgid "&Connected" msgstr "" -msgid "Clear image history" -msgstr "Törölje a kép előzményeit" +msgid "Clear image &history" +msgstr "Törölje a kép &előzményeit" msgid "Create..." msgstr "Hozzon létre..." @@ -1266,6 +1347,9 @@ msgstr "Null Driver" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "Renderelési viselkedés" @@ -1305,8 +1389,8 @@ msgstr "Hiba az OpenGL inicializálásában" msgid "\nFalling back to software rendering." msgstr "\nVisszatérés a szoftveres rendereléshez." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>A médiaképek (CD-ROM, floppy stb.) kiválasztásakor a megnyitási párbeszédpanel ugyanabban a könyvtárban indul, mint a 86Box konfigurációs fájl. Ez a beállítás valószínűleg csak a macOS rendszerben jelent különbséget.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

A médiaképek (CD-ROM, floppy stb.) kiválasztásakor a megnyitási párbeszédpanel ugyanabban a könyvtárban indul, mint a 86Box konfigurációs fájl. Ez a beállítás valószínűleg csak a macOS rendszerben jelent különbséget.

" msgid "This machine might have been moved or copied." msgstr "Lehet, hogy ezt a gépet áthelyezték vagy lemásolták." @@ -1371,9 +1455,27 @@ msgstr "Soros port áthaladás 3" msgid "Serial port passthrough 4" msgstr "Soros port áthaladás 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Renderer opciók..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Logitech/Microsoft busz egér" @@ -1383,18 +1485,30 @@ msgstr "Microsoft buszos egér (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Egérrendszerek Soros egér" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Microsoft soros egér" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Logitech soros egér" msgid "PS/2 Mouse" msgstr "PS/2 egér" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (soros)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Szabványos Hayes-kompatibilis modem" @@ -1419,12 +1533,54 @@ msgstr "Rendszer MIDI" msgid "MIDI Input Device" msgstr "MIDI bemeneti eszköz" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "BIOS cím" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "BIOS bővítés ROM írások engedélyezése" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Cím:" @@ -1434,6 +1590,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "BIOS felülvizsgálata" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Fordítsd le 26 -> 17" @@ -1449,6 +1617,18 @@ msgstr "Invertált színek" msgid "BIOS size" msgstr "BIOS mérete" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "C0000-C7FFF mint UMB leképezése" @@ -1524,6 +1704,9 @@ msgstr "Visszhang szint" msgid "Interpolation Method" msgstr "Interpolációs módszer" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Visszhang kimenetének erősítése" @@ -1611,6 +1794,12 @@ msgstr "Alacsony DMA" msgid "Enable Game port" msgstr "Játékport engedélyezése" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Surround modul" @@ -1623,6 +1812,9 @@ msgstr "CODEC megszakítás felemelése CODEC beállításakor (néhány illeszt msgid "SB Address" msgstr "SB cím" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "WSS IRQ" @@ -1707,9 +1899,15 @@ msgstr "RAMDAC típus" msgid "Blend" msgstr "Blend" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Bilineáris szűrés" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Dithering" @@ -1752,6 +1950,33 @@ msgstr "Átviteli sebesség" msgid "EMS mode" msgstr "EMS üzemmód" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Cím > 2 MB" @@ -1770,11 +1995,11 @@ msgstr "Mindig a kiválasztott sebességen" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "BIOS beállítás + gyorsbillentyűk (kikapcsolva POST alatt)" -msgid "64 kB starting from F0000" -msgstr "64 kB F0000-től kezdődően" +msgid "64 KB starting from F0000" +msgstr "64 KB F0000-től kezdődően" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB E0000-től kezdődően (cím MSB invertálva, először az utolsó 64KB)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB E0000-től kezdődően (cím MSB invertálva, először az utolsó 64 KB)" msgid "Sine" msgstr "Szinuszos" @@ -1908,6 +2133,15 @@ msgstr "sRGB interpoláció" msgid "Linear interpolation" msgstr "Lineáris interpoláció" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2175,9 @@ msgstr "Sárga" msgid "Gray" msgstr "Szürke" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Színes" @@ -1956,6 +2193,12 @@ msgstr "Egyéb nyelvek" msgid "Bochs latest" msgstr "Bochs legújabb" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Monokróm nem átlapolt" @@ -2037,6 +2280,9 @@ msgstr "Az átmenő átviteli sebesség Baud-rátája" msgid "Named Pipe (Server)" msgstr "Megnevezett cső (kiszolgáló)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "Az állomás soros portjának áthaladása" @@ -2082,6 +2328,12 @@ msgstr "IBM 8514/A klón (ISA)" msgid "Vendor" msgstr "Gyártó" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "Általános PC/XT memóriabővítők" @@ -2106,9 +2358,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2156,3 +2405,88 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Merevl.-vezérlő:" + +#~ msgid "ZIP drives:" +#~ msgstr "ZIP-meghajtók:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "ZIP-lemezképek" + diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index b8ded74de..b216b5e96 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Pausa" -msgid "E&xit..." -msgstr "E&sci..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "E&sci" msgid "&View" msgstr "&Visualizza" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "Specifica dimensioni..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "Metodo filtro" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "Schermi VGA &" msgid "RGB &Color" msgstr "RGB &Color" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "&RGB Monocroma" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "&Monitor ambra" @@ -384,6 +393,15 @@ msgstr "Abilitata (UTC)" msgid "Dynamic Recompiler" msgstr "Ricompilatore dinamico" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Video:" @@ -399,6 +417,9 @@ msgstr "Grafica IBM 8514/A" msgid "XGA Graphics" msgstr "Grafica XGA" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Mouse:" @@ -498,18 +519,21 @@ msgstr "Porta parallela 3" msgid "Parallel port 4" msgstr "Porta parallela 4" -msgid "HD Controller:" -msgstr "Controller HD:" - msgid "FD Controller:" msgstr "Controller FD:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "Controller IDE terziario" msgid "Quaternary IDE Controller" msgstr "Controller IDE quaternario" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Cassetta" msgid "Hard disks:" msgstr "Hard disk:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "&Nuovo..." @@ -588,8 +615,8 @@ msgstr "Unità CD-ROM:" msgid "MO drives:" msgstr "Unità magneto-ottiche:" -msgid "ZIP drives:" -msgstr "Unità ZIP:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "RTC ISA:" msgid "ISA Memory Expansion" msgstr "Espansione memoria ISA" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Scheda 1:" @@ -612,6 +642,15 @@ msgstr "Scheda 3:" msgid "Card 4:" msgstr "Scheda 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "Dispositivo ISABugger" @@ -630,17 +669,20 @@ msgstr "Errore fatale" msgid " - PAUSED" msgstr " - IN PAUSA" -msgid "Press %s to return to windowed mode." -msgstr "Usa %s per tornare alla modalità finestra." - msgid "Speed" msgstr "Velocità" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "Immagini ZIP" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "86Box non può trovare immagini ROM utilizzabili.\n\nSi prega di scaricare un set di ROM ed estrarlo nella directory \"roms\"." @@ -717,11 +759,11 @@ msgstr "Altre periferiche" msgid "Click to capture mouse" msgstr "Fare clic per catturare mouse" -msgid "Press %s to release mouse" -msgstr "Premi %s per rilasciare il mouse" +msgid "Press %1 to release mouse" +msgstr "Premi %1 per rilasciare il mouse" -msgid "Press %s or middle button to release mouse" -msgstr "Premi %s o pulsante centrale per rilasciare il mouse" +msgid "Press %1 or middle button to release mouse" +msgstr "Premi %1 o pulsante centrale per rilasciare il mouse" msgid "Bus" msgstr "Bus" @@ -780,12 +822,39 @@ msgstr "Joystick da 4 assi, 4 pulsanti" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Nessuno" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Floppy %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Floppy %1 (%2): %3" + msgid "Advanced sector images" msgstr "Immagini da settori avanzati" @@ -816,6 +888,9 @@ msgstr "Impossibile inizializzare GhostPCL" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "Immagini MO" @@ -861,11 +936,8 @@ msgstr "Configurazione invalida" msgid "%1 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 "%1 è richiesto per la conversione automatica di file PostScript a file PDF.\n\nQualsiasi documento mandato alla stampante generica PostScript sarà salvato come file PostScript (.ps)." -msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as Printer Command Language (.pcl) files." -msgstr "%1 è richiesto per la conversione automatica di file PCL a file PDF.\n\nQualsiasi documento mandato alla stampante generica PCL sarà salvato come file Printer Command Language (.cl)." - -msgid "Entering fullscreen mode" -msgstr "Entrando nella modalità schermo intero" +msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." +msgstr "%1 è richiesto per la conversione automatica di file PCL a file PDF.\n\nQualsiasi documento mandato alla stampante generica PCL sarà salvato come file Printer Command Language (.pcl)." msgid "Don't show this message again" msgstr "Non mostrare più questo messaggio" @@ -903,12 +975,18 @@ msgstr "Continua" msgid "Cassette: %1" msgstr "Cassetta: %1" +msgid "C&assette: %1" +msgstr "C&assetta: %1" + msgid "Cassette images" msgstr "Immagini cassetta" msgid "Cartridge %1: %2" msgstr "Cartuccia %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Car&tuccia %1: %2" + msgid "Cartridge images" msgstr "Immagini cartuccia" @@ -930,6 +1008,9 @@ msgstr "Riavvia" msgid "ACPI shutdown" msgstr "Arresto ACPI" +msgid "ACP&I shutdown" +msgstr "Arresto ACP&I" + msgid "Hard disk (%1)" msgstr "Hard disk (%1)" @@ -1077,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 KB" @@ -1215,41 +1299,41 @@ msgstr "Dispositivi MCA" msgid "List of MCA devices:" msgstr "Elenco dei dispositivi MCA:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Strumento tablet" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "Informazioni su Qt" +msgid "About &Qt" +msgstr "Informazioni su &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "Dispositivi MCA..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Mostra i monitor non primari" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Aprire la cartella screenshot..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Applica la modalità adattamento schermo intero in modalità massimizzata" -msgid "Cursor/Puck" -msgstr "Cursore/Puck" +msgid "&Cursor/Puck" +msgstr "&Cursore/Puck" -msgid "Pen" -msgstr "Penna" +msgid "&Pen" +msgstr "&Penna" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Unità CD/DVD host (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Unità CD/DVD host (%1:)" msgid "&Connected" msgstr "&Connesso" -msgid "Clear image history" -msgstr "Cancella la cronologia delle immagini" +msgid "Clear image &history" +msgstr "Cancella la cr&onologia delle immagini" msgid "Create..." msgstr "Creare..." @@ -1266,6 +1350,9 @@ msgstr "Driver nullo" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "Comportamento di rendering" @@ -1305,8 +1392,8 @@ msgstr "Errore nell'inizializzazione di OpenGL" msgid "\nFalling back to software rendering." msgstr "\nRicaduta sul rendering software." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Quando si selezionano immagini multimediali (CD-ROM, floppy, ecc.) la finestra di dialogo di apertura si avvia nella stessa directory del file di configurazione di 86Box. Questa impostazione probabilmente farà la differenza solo su macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Quando si selezionano immagini multimediali (CD-ROM, floppy, ecc.) la finestra di dialogo di apertura si avvia nella stessa directory del file di configurazione di 86Box. Questa impostazione probabilmente farà la differenza solo su macOS.

" msgid "This machine might have been moved or copied." msgstr "Questa macchina potrebbe essere stata spostata o copiata." @@ -1371,9 +1458,27 @@ msgstr "Passaggio della porta seriale 3" msgid "Serial port passthrough 4" msgstr "Passaggio della porta seriale 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Opzioni del renderer..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Mouse bus Logitech/Microsoft" @@ -1383,18 +1488,30 @@ msgstr "Mouse bus Microsoft (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Mouse seriale Mouse Systems" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Mouse seriale Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Mouse seriale Logitech" msgid "PS/2 Mouse" msgstr "Mouse PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (seriale)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Modem standard conforme a Hayes" @@ -1419,12 +1536,54 @@ msgstr "MIDI di sistema" msgid "MIDI Input Device" msgstr "Dispositivo di ingresso MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "Indirizzo BIOS" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "Abilita scrittura al ROM dell'estensione del BIOS" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Indirizzo" @@ -1434,6 +1593,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "Revisione del BIOS" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Tradurre 26 -> 17" @@ -1449,6 +1620,18 @@ msgstr "Invertire i colori" msgid "BIOS size" msgstr "Dimensione del BIOS" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "Mappa C0000-C7FFF come UMB" @@ -1524,6 +1707,9 @@ msgstr "Livello di riverbero" msgid "Interpolation Method" msgstr "Metodo di interpolazione" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Guadagno dell'uscita del riverbero" @@ -1611,6 +1797,12 @@ msgstr "DMA basso" msgid "Enable Game port" msgstr "Abilita la porta giochi" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Modulo surround" @@ -1623,6 +1815,9 @@ msgstr "Solleva l'interrupt del CODEC all'impostazione del CODEC (necessario per msgid "SB Address" msgstr "Indirizzo SB" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "IRQ WSS" @@ -1707,9 +1902,15 @@ msgstr "Tipo di RAMDAC" msgid "Blend" msgstr "Miscela" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Filtraggio bilineare" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Dithering" @@ -1752,6 +1953,33 @@ msgstr "Velocità di trasferimento" msgid "EMS mode" msgstr "Modalità EMS" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Indirizzo per > 2 MB" @@ -1770,11 +1998,11 @@ msgstr "Sempre alla velocità selezionata" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Impostazione BIOS + Tasti di scelta rapida (disattivati durante il POST)" -msgid "64 kB starting from F0000" -msgstr "64 kB a partire da F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB a partire da F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB a partire da E0000 (indirizzo MSB invertito, prima gli ultimi 64KB)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB a partire da E0000 (indirizzo MSB invertito, prima gli ultimi 64 KB)" msgid "Sine" msgstr "Sinusoidale" @@ -1908,6 +2136,15 @@ msgstr "Interpolazione sRGB" msgid "Linear interpolation" msgstr "Interpolazione lineare" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2178,9 @@ msgstr "Ambra" msgid "Gray" msgstr "Grigio" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Colore" @@ -1956,6 +2196,12 @@ msgstr "Altre lingue" msgid "Bochs latest" msgstr "Bochs ultima versione" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Mono non interlacciato" @@ -2037,6 +2283,9 @@ msgstr "Velocità di trasmissione in baud del passaggio" msgid "Named Pipe (Server)" msgstr "Tubo denominato (Server)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "Passaggio della porta seriale host" @@ -2082,6 +2331,12 @@ msgstr "Clone IBM 8514/A (ISA)" msgid "Vendor" msgstr "Fabricante" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "Espansione di memoria generica PC/XT" @@ -2106,9 +2361,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2156,3 +2408,87 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Controller HD:" + +#~ msgid "ZIP drives:" +#~ msgstr "Unità ZIP:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "Immagini ZIP" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index dc000b175..0af11c545 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+Esc(&E)" msgid "&Pause" msgstr "一時停止(&P)" -msgid "E&xit..." -msgstr "終了(&X)..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "終了(&X)" msgid "&View" msgstr "表示(&V)" @@ -60,8 +63,8 @@ msgstr "OpenGL (3.0 Core)(&G)" msgid "&VNC" msgstr "VNC(&V)" -msgid "Specify dimensions..." -msgstr "ディメンションを指定..." +msgid "Specify &dimensions..." +msgstr "ディメンションを指定...(&D)" msgid "F&orce 4:3 display ratio" msgstr "4:3の縦横比を強制表示(&O)" @@ -99,8 +102,8 @@ msgstr "7x(&7)" msgid "&8x" msgstr "8x(&8)" -msgid "Filter method" -msgstr "フィルター方式" +msgid "Fi<er method" +msgstr "フィルター方式(&L)" msgid "&Nearest" msgstr "最近傍補間(&N)" @@ -144,9 +147,15 @@ msgstr "画面タイプ(&T)" msgid "RGB &Color" msgstr "RGB(カラー)(&C)" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "RGB(グレースケール)(&R)" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "モニター(黄色)(&A)" @@ -384,6 +393,15 @@ msgstr "有効(UTC)" msgid "Dynamic Recompiler" msgstr "動的再コンパイル" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "ビデオカード:" @@ -399,6 +417,9 @@ msgstr "IBM 8514/Aグラフィック" msgid "XGA Graphics" msgstr "XGAグラフィック" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "マウス:" @@ -498,18 +519,21 @@ msgstr "パラレルポート3" msgid "Parallel port 4" msgstr "パラレルポート4" -msgid "HD Controller:" -msgstr "HDDコントローラー:" - msgid "FD Controller:" msgstr "FDDコントローラー:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "第三IDEコントローラー" msgid "Quaternary IDE Controller" msgstr "第四IDEコントローラー" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "カセット" msgid "Hard disks:" msgstr "ハード ディスク:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "新規(&N)..." @@ -588,8 +615,8 @@ msgstr "CD-ROMドライブ:" msgid "MO drives:" msgstr "光磁気ドライブ:" -msgid "ZIP drives:" -msgstr "ZIPドライブ:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA RTCカード:" msgid "ISA Memory Expansion" msgstr "ISAメモリ拡張カード" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "カード1:" @@ -612,6 +642,15 @@ msgstr "カード3:" msgid "Card 4:" msgstr "カード4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "ISABuggerデバイス" @@ -630,17 +669,20 @@ msgstr "致命的なエラー" msgid " - PAUSED" msgstr " - 一時停止" -msgid "Press %s to return to windowed mode." -msgstr "%sでウィンドウ モードに戻ります。" - msgid "Speed" msgstr "速度" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "ZIPイメージ" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" 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 ディレクトリに解凍してください。" @@ -717,11 +759,11 @@ msgstr "他の周辺デバイス" msgid "Click to capture mouse" msgstr "左クリックでマウスをキャプチャします" -msgid "Press %s to release mouse" -msgstr "%sキーでマウスを解放します" +msgid "Press %1 to release mouse" +msgstr "%1キーでマウスを解放します" -msgid "Press %s or middle button to release mouse" -msgstr "%sキーまたは中クリックでマウスを解放します" +msgid "Press %1 or middle button to release mouse" +msgstr "%1キーまたは中クリックでマウスを解放します" msgid "Bus" msgstr "バス" @@ -780,12 +822,39 @@ msgstr "ジョイスティック(4軸、4ボタン)" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinderパッド" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster飛行制御システム" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "なし" @@ -795,6 +864,9 @@ msgstr "%u MB (CHS値: %i、%i、%i)" msgid "Floppy %1 (%2): %3" msgstr "フロッピー %1 (%2): %3" +msgid "Floppy %1 (%2): %3 (&F)" +msgstr "フロッピー %1 (%2): %3(&F)" + msgid "Advanced sector images" msgstr "アドバンスドセクターイメージ" @@ -816,6 +888,9 @@ msgstr "GhostPCLが初期化できません" msgid "MO %1 (%2): %3" msgstr "光磁気 %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "光磁気 %1 (%2): %3(&M)" + msgid "MO images" msgstr "光磁気イメージ" @@ -864,9 +939,6 @@ msgstr "PostScriptファイルをPDFに自動変換するには%1が必要です msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "PCLファイルをPDFに自動変換するには%1が必要です。\n\n汎用PCLプリンターに送信された文書は、Printer Command Language (.pcl) ファイルとして保存されます。" -msgid "Entering fullscreen mode" -msgstr "全画面モードを入力" - msgid "Don't show this message again" msgstr "今後、このメッセージを表示しない" @@ -903,12 +975,18 @@ msgstr "続行" msgid "Cassette: %1" msgstr "カセット: %1" +msgid "C&assette: %1" +msgstr "カセット: %1(&A)" + msgid "Cassette images" msgstr "カセットイメージ" msgid "Cartridge %1: %2" msgstr "カートリッジ %1: %2" +msgid "Car&tridge %1: %2" +msgstr "カートリッジ %1: %2(&T)" + msgid "Cartridge images" msgstr "カートリッジイメージ" @@ -930,6 +1008,9 @@ msgstr "ハードリセット" msgid "ACPI shutdown" msgstr "ACPIシャットダウン" +msgid "ACP&I shutdown" +msgstr "ACP&Iシャットダウン" + msgid "Hard disk (%1)" msgstr "ハードディスク (%1)" @@ -1077,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 KB" @@ -1215,41 +1299,41 @@ msgstr "MCAデバイス" msgid "List of MCA devices:" msgstr "MCAデバイスのリスト:" -msgid "Tablet tool" -msgstr "タブレットツール" +msgid "&Tablet tool" +msgstr "タブレットツール(&T)" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "Qtについて" +msgid "About &Qt" +msgstr "&Qtについて" -msgid "MCA devices..." -msgstr "MCAデバイス..." +msgid "&MCA devices..." +msgstr "&MCAデバイス..." -msgid "Show non-primary monitors" -msgstr "プライマリーモニター以外のモニターを表示する" +msgid "Show non-&primary monitors" +msgstr "プライマリーモニター以外のモニターを表示する(&P)" -msgid "Open screenshots folder..." -msgstr "スクリーンショットフォルダを開く" +msgid "Open screenshots &folder..." +msgstr "スクリーンショットフォルダを開く(&F)" -msgid "Apply fullscreen stretch mode when maximized" -msgstr "最大化時にフルスクリーンストレッチモードを適用" +msgid "Appl&y fullscreen stretch mode when maximized" +msgstr "最大化時にフルスクリーンストレッチモードを適用(&Y)" -msgid "Cursor/Puck" -msgstr "カーソル/パック" +msgid "&Cursor/Puck" +msgstr "カーソル/パック(&C)" -msgid "Pen" -msgstr "ペン" +msgid "&Pen" +msgstr "ペン(&P)" -msgid "Host CD/DVD Drive (%1:)" -msgstr "ホスト CD/DVD ドライブ (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "ホスト CD/DVD ドライブ (%1:) (&H)" msgid "&Connected" msgstr "コネクテッド" -msgid "Clear image history" -msgstr "クリア画像履歴" +msgid "Clear image &history" +msgstr "クリア画像履歴(&H)" msgid "Create..." msgstr "作成..." @@ -1266,6 +1350,9 @@ msgstr "ヌル・ドライバー" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "レンダリング動作" @@ -1305,8 +1392,8 @@ msgstr "OpenGLの初期化エラー" msgid "\nFalling back to software rendering." msgstr "\nソフトウェアレンダリングに逆戻り。" -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>メディアイメージ(CD-ROM、フロッピーなど)を選択するとき、オープンダイアログは86Box設定ファイルと同じディレクトリで開始します。この設定は、おそらく macOS でのみ違いがあります。</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

メディアイメージ(CD-ROM、フロッピーなど)を選択するとき、オープンダイアログは86Box設定ファイルと同じディレクトリで開始します。この設定は、おそらく macOS でのみ違いがあります。

" msgid "This machine might have been moved or copied." msgstr "このマシンは移動されたかコピーされた可能性がある。" @@ -1371,8 +1458,26 @@ msgstr "シリアル・ポート・パススルー 3" msgid "Serial port passthrough 4" msgstr "シリアル・ポート・パススルー 4" -msgid "Renderer options..." -msgstr "レンダラー設定..." +msgid "Renderer &options..." +msgstr "レンダラー設定...(&O)" + +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" msgid "Logitech/Microsoft Bus Mouse" msgstr "Logitech/Microsoft バスマウス" @@ -1383,18 +1488,30 @@ msgstr "Microsoft バスマウス(InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Mouse Systems シリアルマウス" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Microsoft シリアルマウス" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Logitech シリアルマウス" msgid "PS/2 Mouse" msgstr "PS/2マウス" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3Mマイクロタッチ(シリアル)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] 標準ヘイズ準拠モデム" @@ -1419,12 +1536,54 @@ msgstr "システムMIDI" msgid "MIDI Input Device" msgstr "MIDI入力デバイス" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "BIOSアドレス" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "BIOS拡張ROM書き込みを有効にする" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "アドレス" @@ -1434,6 +1593,18 @@ msgstr "割り込み要求" msgid "BIOS Revision" msgstr "BIOSリビジョン" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "26→17を翻訳" @@ -1449,6 +1620,18 @@ msgstr "色の反転" msgid "BIOS size" msgstr "BIOSサイズ" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "C0000-C7FFFをUMBとしてマップ" @@ -1524,6 +1707,9 @@ msgstr "リバーブ・レベル" msgid "Interpolation Method" msgstr "補間法" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "リバーブ出力のゲイン" @@ -1611,6 +1797,12 @@ msgstr "低DMA" msgid "Enable Game port" msgstr "ゲームポートを有効にする" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "サラウンド・モジュール" @@ -1623,6 +1815,9 @@ msgstr "CODECセットアップ時にCODEC割り込みを発生させる(一部 msgid "SB Address" msgstr "SBアドレス" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "WSS IRQ" @@ -1707,9 +1902,15 @@ msgstr "RAMDACタイプ" msgid "Blend" msgstr "ブレンド" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "バイリニア・フィルタリング" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "ディザリング" @@ -1752,6 +1953,33 @@ msgstr "転送速度" msgid "EMS mode" msgstr "EMSモード" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "2MB以上のアドレス" @@ -1770,10 +1998,10 @@ msgstr "常に選択された速度" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "BIOS設定+ホットキー(POST中はオフ)" -msgid "64 kB starting from F0000" +msgid "64 KB starting from F0000" msgstr "F0000から始まる64キロバイト" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" msgstr "E0000から始まる128キロバイト(アドレスMSBが反転、最後の64キロバイトが最初)" msgid "Sine" @@ -1908,6 +2136,15 @@ msgstr "sRGB補間" msgid "Linear interpolation" msgstr "線形補間" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2178,9 @@ msgstr "鼈甲色" msgid "Gray" msgstr "ねずみ色" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "カラー" @@ -1956,6 +2196,12 @@ msgstr "その他の言語" msgid "Bochs latest" msgstr "Bochs latest" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "モノラル・ノンインターレース" @@ -2037,6 +2283,9 @@ msgstr "パススルーのボーレート" msgid "Named Pipe (Server)" msgstr "名前付きパイプ(サーバー)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "ホストシリアルポートのパススルー" @@ -2082,6 +2331,12 @@ msgstr "IBM 8514/A クローン(ISA)" msgid "Vendor" msgstr "業者" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "汎用PC/XTメモリ拡張カード" @@ -2106,9 +2361,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2156,3 +2408,87 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "HDDコントローラー:" + +#~ msgid "ZIP drives:" +#~ msgstr "ZIPドライブ:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "ZIPイメージ" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 3ef901789..fa5339528 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+Esc(&E)" msgid "&Pause" msgstr "일시정지(&P)" -msgid "E&xit..." -msgstr "끝내기(&X)..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "끝내기(&X)" msgid "&View" msgstr "표시(&V)" @@ -60,8 +63,8 @@ msgstr "OpenGL (3.0 Core)(&G)" msgid "&VNC" msgstr "VNC(&V)" -msgid "Specify dimensions..." -msgstr "창 크기 지정하기..." +msgid "Specify &dimensions..." +msgstr "창 크기 지정하기...(&D)" msgid "F&orce 4:3 display ratio" msgstr "화면 비율을 4:3으로 맞추기(&O)" @@ -99,8 +102,8 @@ msgstr "7배(&7)" msgid "&8x" msgstr "8배(&8)" -msgid "Filter method" -msgstr "필터 형식" +msgid "Fi<er method" +msgstr "필터 형식(&L)" msgid "&Nearest" msgstr "최근방 이웃 보간법(&N)" @@ -144,9 +147,15 @@ msgstr "VGA 화면 종류(&T)" msgid "RGB &Color" msgstr "RGB 천연색(&C)" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "RGB 회색조(&R)" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "주황색 모니터(&A)" @@ -384,10 +393,19 @@ msgstr "사용 (UTC)" msgid "Dynamic Recompiler" msgstr "동적 재컴파일" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "비디오 카드:" -msgid "Video 2:" +msgid "Video #2:" msgstr "비디오 카드 2:" msgid "Voodoo 1 or 2 Graphics" @@ -399,6 +417,9 @@ msgstr "IBM 8514/A 그래픽" msgid "XGA Graphics" msgstr "XGA 그래픽" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "마우스:" @@ -498,18 +519,21 @@ msgstr "병렬 포트 3" msgid "Parallel port 4" msgstr "병렬 포트 4" -msgid "HD Controller:" -msgstr "HD 컨트롤러:" - msgid "FD Controller:" msgstr "FD 컨트롤러:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "제3의 IDE 컨트롤러" msgid "Quaternary IDE Controller" msgstr "제4의 IDE 컨트롤러" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "카세트 테이프" msgid "Hard disks:" msgstr "하드 디스크:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "새로 만들기(&N)..." @@ -588,8 +615,8 @@ msgstr "CD-ROM 드라이브:" msgid "MO drives:" msgstr "광자기 드라이브:" -msgid "ZIP drives:" -msgstr "ZIP 드라이브:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA RTC 카드:" msgid "ISA Memory Expansion" msgstr "ISA 메모리 확장 카드" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "카드 1:" @@ -612,6 +642,15 @@ msgstr "카드 3:" msgid "Card 4:" msgstr "카드 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "ISABugger 장치" @@ -630,17 +669,20 @@ msgstr "치명적인 오류" msgid " - PAUSED" msgstr " - 일시 중지됨" -msgid "Press %s to return to windowed mode." -msgstr "%s 키를 누르면 창 모드로 전환합니다." - msgid "Speed" msgstr "속도" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "ZIP 이미지" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" 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\" 디렉토리에 압축을 풀어 주세요." @@ -717,11 +759,11 @@ msgstr "기타 주변기기" msgid "Click to capture mouse" msgstr "이 창을 클릭하면 마우스를 사용합니다" -msgid "Press %s to release mouse" -msgstr "%s키를 누르면 마우스를 해제합니다" +msgid "Press %1 to release mouse" +msgstr "%1키를 누르면 마우스를 해제합니다" -msgid "Press %s or middle button to release mouse" -msgstr "%s키 또는 가운데 버튼을 클릭하면 마우스를 해제합니다" +msgid "Press %1 or middle button to release mouse" +msgstr "%1키 또는 가운데 버튼을 클릭하면 마우스를 해제합니다" msgid "Bus" msgstr "버스" @@ -780,12 +822,39 @@ msgstr "4축, 4버튼 조이스틱" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "없음" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "플로피 %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "플로피 %1 (%2): %3(&F)" + msgid "Advanced sector images" msgstr "어드밴스드 섹터 이미지" @@ -816,6 +888,9 @@ msgstr "GhostPCL를 초기화할 수 없습니다" msgid "MO %1 (%2): %3" msgstr "광자기 %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "광자기 %1 (%2): %3(&M)" + msgid "MO images" msgstr "광자기 이미지" @@ -864,9 +939,6 @@ msgstr "%1은(는) PostScript 파일을 PDF로 자동변환하는 데에 필요 msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1은(는) PCL 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PCL 프린터로 보내신 임의의 문서는 Printer Command Language (.pcl) 파일로 저장됩니다." -msgid "Entering fullscreen mode" -msgstr "전체 화면으로 전환" - msgid "Don't show this message again" msgstr "이 메시지 그만 보기" @@ -903,12 +975,18 @@ msgstr "계속" msgid "Cassette: %1" msgstr "카세트: %1" +msgid "C&assette: %1" +msgstr "카세트: %1(&A)" + msgid "Cassette images" msgstr "카세트 이미지" msgid "Cartridge %1: %2" msgstr "카트리지 %1: %2" +msgid "Car&tridge %1: %2" +msgstr "카트리지 %1: %2(&T)" + msgid "Cartridge images" msgstr "카트리지 이미지" @@ -930,6 +1008,9 @@ msgstr "재시작" msgid "ACPI shutdown" msgstr "ACPI 종료" +msgid "ACP&I shutdown" +msgstr "ACP&I 종료" + msgid "Hard disk (%1)" msgstr "하드 디스크 (%1)" @@ -1215,41 +1296,41 @@ msgstr "MCA 장치" msgid "List of MCA devices:" msgstr "MCA 장치 목록:" -msgid "Tablet tool" -msgstr "태블릿 도구" +msgid "&Tablet tool" +msgstr "태블릿 도구(&T)" msgid "Qt (OpenGL &ES)" msgstr "Qt(OpenGL &ES)" -msgid "About Qt" -msgstr "Qt 소개" +msgid "About &Qt" +msgstr "&Qt 소개" -msgid "MCA devices..." -msgstr "MCA 장치..." +msgid "&MCA devices..." +msgstr "&MCA 장치..." -msgid "Show non-primary monitors" -msgstr "기본 모니터가 아닌 모니터 표시" +msgid "Show non-&primary monitors" +msgstr "기본 모니터가 아닌 모니터 표시(&P)" -msgid "Open screenshots folder..." -msgstr "스크린샷 폴더 열기..." +msgid "Open screenshots &folder..." +msgstr "스크린샷 폴더 열기...(&F)" -msgid "Apply fullscreen stretch mode when maximized" -msgstr "최대화 시 전체 화면 비율 적용" +msgid "Appl&y fullscreen stretch mode when maximized" +msgstr "최대화 시 전체 화면 비율 적용(&Y)" -msgid "Cursor/Puck" -msgstr "커서/퍽" +msgid "&Cursor/Puck" +msgstr "커서/퍽(&P)" -msgid "Pen" -msgstr "펜" +msgid "&Pen" +msgstr "펜(&P)" -msgid "Host CD/DVD Drive (%1:)" -msgstr "호스트 CD/DVD 드라이브(%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "호스트 CD/DVD 드라이브(%1:) (&H)" msgid "&Connected" msgstr "&커넥티드" -msgid "Clear image history" -msgstr "이미지 기록 지우기" +msgid "Clear image &history" +msgstr "이미지 기록 지우기(&H)" msgid "Create..." msgstr "만들기..." @@ -1266,6 +1347,9 @@ msgstr "Null 드라이버" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "렌더링 동작" @@ -1305,8 +1389,8 @@ msgstr "OpenGL 초기화 중 오류 발생" msgid "\nFalling back to software rendering." msgstr "\n소프트웨어 렌더링으로 돌아가기." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>미디어 이미지(CD-ROM, 플로피 등)를 선택하면 86Box 구성 파일과 동일한 디렉터리에서 열기 대화 상자가 시작됩니다. 이 설정은 macOS에서만 차이가 있을 수 있습니다.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

미디어 이미지(CD-ROM, 플로피 등)를 선택하면 86Box 구성 파일과 동일한 디렉터리에서 열기 대화 상자가 시작됩니다. 이 설정은 macOS에서만 차이가 있을 수 있습니다.

" msgid "This machine might have been moved or copied." msgstr "이 컴퓨터가 이동되었거나 복사되었을 수 있습니다." @@ -1371,8 +1455,26 @@ msgstr "직렬 포트 패스스루 3" msgid "Serial port passthrough 4" msgstr "직렬 포트 패스스루 4" -msgid "Renderer options..." -msgstr "렌더러 옵션..." +msgid "Renderer &options..." +msgstr "렌더러 옵션...(&O)" + +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" msgid "Logitech/Microsoft Bus Mouse" msgstr "로지텍/마이크로소프트 버스 마우스" @@ -1383,18 +1485,30 @@ msgstr "마이크로소프트 버스 마우스(인포트)" msgid "Mouse Systems Serial Mouse" msgstr "마우스 시스템 시리얼 마우스" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "마이크로소프트 직렬 마우스" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "로지텍 직렬 마우스" msgid "PS/2 Mouse" msgstr "PS/2 마우스" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M 마이크로터치(직렬)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] 표준 헤이즈 호환 모뎀" @@ -1419,12 +1533,54 @@ msgstr "시스템 미디" msgid "MIDI Input Device" msgstr "미디 입력 장치" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "BIOS 주소" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "BIOS 확장 ROM 쓰기 활성화" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "주소" @@ -1434,6 +1590,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "BIOS 개정" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "번역 26 -> 17" @@ -1449,6 +1617,18 @@ msgstr "색상 반전" msgid "BIOS size" msgstr "BIOS 크기" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "C0000-C7FFF를 UMB로 매핑하기" @@ -1524,6 +1704,9 @@ msgstr "리버브 레벨" msgid "Interpolation Method" msgstr "보간 방법" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "리버브 출력의 게인" @@ -1611,6 +1794,12 @@ msgstr "낮은 DMA" msgid "Enable Game port" msgstr "게임 포트 사용" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "서라운드 모듈" @@ -1623,6 +1812,9 @@ msgstr "코덱 설정 시 코덱 인터럽트 올리기(일부 드라이버에 msgid "SB Address" msgstr "SB 주소" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "WSS IRQ" @@ -1707,9 +1899,15 @@ msgstr "램닥 유형" msgid "Blend" msgstr "블렌드" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "이중선형 필터링" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "디더링" @@ -1752,6 +1950,33 @@ msgstr "전송 속도" msgid "EMS mode" msgstr "EMS 모드" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "2MB 이상의 주소" @@ -1770,11 +1995,11 @@ msgstr "항상 선택한 속도로" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "BIOS 설정 + 핫키(POST 중 꺼짐)" -msgid "64 kB starting from F0000" -msgstr "64kB부터 F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB부터 F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "E0000에서 시작하는 128kB(주소 MSB 반전, 마지막 64KB 먼저)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "E0000에서 시작하는 128KB(주소 MSB 반전, 마지막 64 KB 먼저)" msgid "Sine" msgstr "사인" @@ -1908,6 +2133,15 @@ msgstr "sRGB 보간" msgid "Linear interpolation" msgstr "선형 보간" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2175,9 @@ msgstr "Amber" msgid "Gray" msgstr "회색" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "색상" @@ -1956,6 +2193,12 @@ msgstr "기타 언어" msgid "Bochs latest" msgstr "Bochs 최신 정보" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "모노 비인터레이스" @@ -2037,6 +2280,9 @@ msgstr "통과 속도" msgid "Named Pipe (Server)" msgstr "네임드 파이프(서버)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "호스트 직렬 포트 패스스루" @@ -2082,6 +2328,12 @@ msgstr "IBM 8514/A 클론(ISA)" msgid "Vendor" msgstr "제조사" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "일반 PC/XT 메모리 확장 카드" @@ -2106,9 +2358,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2156,3 +2405,87 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "HD 컨트롤러:" + +#~ msgid "ZIP drives:" +#~ msgstr "ZIP 드라이브:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "ZIP 이미지" diff --git a/src/qt/languages/nl-NL.po b/src/qt/languages/nl-NL.po index 49a32506b..4d69ade27 100644 --- a/src/qt/languages/nl-NL.po +++ b/src/qt/languages/nl-NL.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Pauze" -msgid "E&xit..." -msgstr "&Afsluiten..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "&Afsluiten" msgid "&View" msgstr "&Beeld" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "Afmetingen opgeven..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "Filtermethode" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "VGA-scherm &type" msgid "RGB &Color" msgstr "RGB &Kleur" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "&RGB grijstinten" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "&Amber monitor" @@ -384,6 +393,15 @@ msgstr "Ingeschakeld (UTC)" msgid "Dynamic Recompiler" msgstr "Dynamische Recompiler" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Video:" @@ -399,6 +417,9 @@ msgstr "IBM 8514/A-graphics" msgid "XGA Graphics" msgstr "XGA Graphics" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Muis:" @@ -498,18 +519,21 @@ msgstr "Parallelle poort 3" msgid "Parallel port 4" msgstr "Parallelle poort 4" -msgid "HD Controller:" -msgstr "HD-controller:" - msgid "FD Controller:" msgstr "FD-Controller:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "Tertiaire IDE-controller" msgid "Quaternary IDE Controller" msgstr "Quaternaire IDE-controller" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Cassette" msgid "Hard disks:" msgstr "Harde schijven:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "&Nieuw..." @@ -588,8 +615,8 @@ msgstr "CD-ROM-stations:" msgid "MO drives:" msgstr "MO-schijven:" -msgid "ZIP drives:" -msgstr "ZIP-schijven:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA RTC:" msgid "ISA Memory Expansion" msgstr "ISA-geheugenuitbreiding" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Kaart 1:" @@ -612,6 +642,15 @@ msgstr "Kaart 3:" msgid "Card 4:" msgstr "Kaart 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "ISABugger-apparaat" @@ -630,17 +669,20 @@ msgstr "Fatale fout" msgid " - PAUSED" msgstr " - GEPAUZEERD" -msgid "Press %s to return to windowed mode." -msgstr "Druk op %s om terug te gaan naar de venstermodus." - msgid "Speed" msgstr "Snelheid" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "ZIP-images" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "86Box kon geen bruikbare ROM images vinden.\n\nDownload een ROM set en pak deze uit in de map \"roms\"." @@ -717,11 +759,11 @@ msgstr "Andere randapparatuur" msgid "Click to capture mouse" msgstr "Klik om muis vast te leggen" -msgid "Press %s to release mouse" -msgstr "Druk op %s om de muis los te laten" +msgid "Press %1 to release mouse" +msgstr "Druk op %1 om de muis los te laten" -msgid "Press %s or middle button to release mouse" -msgstr "Druk op %s of middelste knop om de muis los te laten" +msgid "Press %1 or middle button to release mouse" +msgstr "Druk op %1 of middelste knop om de muis los te laten" msgid "Bus" msgstr "Bus" @@ -780,12 +822,39 @@ msgstr "Joystick met 4 assen en 4 knoppen" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control systeem" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Geen" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Floppy %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Floppy %1 (%2): %3" + msgid "Advanced sector images" msgstr "Geavanceerde sector-images" @@ -816,6 +888,9 @@ msgstr "Kan GhostPCL niet initialiseren" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "MO-images" @@ -864,9 +939,6 @@ msgstr "%1 is vereist voor automatische conversie van PostScript-bestanden naar msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 is vereist voor automatische conversie van PCL-bestanden naar PDF.\n\nAlle documenten die naar de generieke PCL-printer worden gestuurd, worden opgeslagen als Printer Command Language (.pcl) bestanden." -msgid "Entering fullscreen mode" -msgstr "Volledig scherm modus openen" - msgid "Don't show this message again" msgstr "Dit bericht niet meer tonen" @@ -903,12 +975,18 @@ msgstr "Doorgaan" msgid "Cassette: %1" msgstr "Cassette: %1" +msgid "C&assette: %1" +msgstr "C&assette: %1" + msgid "Cassette images" msgstr "Cassette-images" msgid "Cartridge %1: %2" msgstr "Cartridge %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Car&tridge %1: %2" + msgid "Cartridge images" msgstr "Cartridge-images" @@ -930,6 +1008,9 @@ msgstr "Harde reset" msgid "ACPI shutdown" msgstr "ACPI uitschakeling" +msgid "ACP&I shutdown" +msgstr "ACP&I uitschakeling" + msgid "Hard disk (%1)" msgstr "Harde schijf (%1)" @@ -1077,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 KB" @@ -1215,41 +1299,41 @@ msgstr "MCA-apparaten" msgid "List of MCA devices:" msgstr "Lijst van MCA-apparaten:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Tablet-hulpmiddel" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "Over Qt" +msgid "About &Qt" +msgstr "Over &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "MCA-apparaten..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Toon niet-primaire monitors" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Map met schermafbeeldingen openen..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Schakel de volledig scherm-uitrekmodus in bij maximaliseren" -msgid "Cursor/Puck" -msgstr "Cursor/Puck" +msgid "&Cursor/Puck" +msgstr "&Cursor/Puck" -msgid "Pen" -msgstr "Pen" +msgid "&Pen" +msgstr "&Pen" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Host cd/dvd-station (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Host cd/dvd-station (%1:)" msgid "&Connected" msgstr "&Verbonden" -msgid "Clear image history" -msgstr "Imagegeschiedenis verwijderen" +msgid "Clear image &history" +msgstr "Imagegeschiedenis verwijderen(&H)" msgid "Create..." msgstr "Creëer..." @@ -1266,6 +1350,9 @@ msgstr "Null Driver" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "Rendergedrag" @@ -1305,8 +1392,8 @@ msgstr "Fout bij het initialiseren van OpenGL" msgid "\nFalling back to software rendering." msgstr "\nTerugvallen op software rendering." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Bij het selecteren van media-images (CD-ROM, floppy, etc.) zal de \"open dialoog\" starten in dezelfde map als het 86Box configuratiebestand. Deze instelling is doet er waarschijnlijk alleen toe op macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Bij het selecteren van media-images (CD-ROM, floppy, etc.) zal de \"open dialoog\" starten in dezelfde map als het 86Box configuratiebestand. Deze instelling is doet er waarschijnlijk alleen toe op macOS.

" msgid "This machine might have been moved or copied." msgstr "Deze machine is misschien verplaatst of gekopieerd." @@ -1371,9 +1458,27 @@ msgstr "Seriële poort doorvoer 3" msgid "Serial port passthrough 4" msgstr "Seriële poort doorvoer 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Renderer-opties..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Logitech/Microsoft busmuis" @@ -1383,18 +1488,30 @@ msgstr "Microsoft busmuis (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Mouse Systems seriële muis" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Microsoft seriële muis" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Logitech seriële muis" msgid "PS/2 Mouse" msgstr "PS/2-muis" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (serieel)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "COM] Standaard Hayes-compatibele modem " @@ -1419,12 +1536,54 @@ msgstr "Systeem MIDI" msgid "MIDI Input Device" msgstr "MIDI-ingangsapparaat" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "BIOS-adres" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "BIOS-extensie ROM Writes inschakelen" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Adres" @@ -1434,6 +1593,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "BIOS Revisie" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Vertaal 26 -> 17" @@ -1449,6 +1620,18 @@ msgstr "Kleuren inverteren" msgid "BIOS size" msgstr "BIOS-grootte" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "Geheugenadres C0000-C7FFF toewijzen aan UMB" @@ -1524,6 +1707,9 @@ msgstr "Reverbniveau" msgid "Interpolation Method" msgstr "Interpolatiemethode" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Reverbuitgang Versterking" @@ -1611,6 +1797,12 @@ msgstr "Lage DMA" msgid "Enable Game port" msgstr "Game-poort inschakelen" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Surroundmodule" @@ -1623,6 +1815,9 @@ msgstr "Verhoog CODEC interrupt bij CODEC setup (nodig voor sommige stuurprogram msgid "SB Address" msgstr "SB-adres" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "WSS IRQ" @@ -1707,9 +1902,15 @@ msgstr "RAMDAC type" msgid "Blend" msgstr "Mengen" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Bilineaire filtering" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Dithering" @@ -1752,6 +1953,33 @@ msgstr "Overdrachtssnelheid" msgid "EMS mode" msgstr "EMS-modus" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Adres voor > 2 MB" @@ -1770,11 +1998,11 @@ msgstr "Altijd op geselecteerde snelheid" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "BIOS-instelling + Sneltoetsen (niet actief tijdens POST)" -msgid "64 kB starting from F0000" -msgstr "64 kB vanaf F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB vanaf F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB vanaf E0000 (geïnverteerd MSB adres, laatste 64KB eerst)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB vanaf E0000 (geïnverteerd MSB adres, laatste 64 KB eerst)" msgid "Sine" msgstr "Sinus" @@ -1908,6 +2136,15 @@ msgstr "sRGB-interpolatie" msgid "Linear interpolation" msgstr "Lineaire interpolatie" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2178,9 @@ msgstr "Amber" msgid "Gray" msgstr "Grijs" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Kleur" @@ -1956,6 +2196,12 @@ msgstr "Andere talen" msgid "Bochs latest" msgstr "Bochs nieuwste" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Mono niet geïnterlaced" @@ -2037,6 +2283,9 @@ msgstr "Baud-snelheid van doorvoer" msgid "Named Pipe (Server)" msgstr "Named Pipe (Server)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "Host seriële doorgave" @@ -2082,6 +2331,12 @@ msgstr "IBM 8514/A-kloon (ISA)" msgid "Vendor" msgstr "Leverancier" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "Generieke PC/XT geheugenuitbreiding" @@ -2106,9 +2361,6 @@ msgstr "Vraag om bevestiging voor een harde reset" msgid "Ask for confirmation before quitting" msgstr "Vraag om bevestiging voor afsluiten" -msgid "Display hotkey message when entering full-screen mode" -msgstr "Toon een sneltoetsmelding bij het openen van de volledigschermmodus" - msgid "Options" msgstr "Opties" @@ -2156,3 +2408,87 @@ msgstr "Omlaag verplaatsen" msgid "Could not load file %1" msgstr "Kon bestand %1 niet laden" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "HD-controller:" + +#~ msgid "ZIP drives:" +#~ msgstr "ZIP-schijven:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "ZIP-images" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index d5b5ec3ea..31914aa8e 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -10,13 +10,13 @@ msgid "&Action" msgstr "&Akcje" msgid "&Keyboard requires capture" -msgstr "&Klawaitura wymaga przechwytu myszy" +msgstr "&Klawiatura wymaga przechwytu myszy" msgid "&Right CTRL is left ALT" -msgstr "&Prawy CTRL to lewy Alt" +msgstr "Prawy C&TRL to lewy ALT" msgid "&Hard Reset..." -msgstr "&Twardy reset..." +msgstr "Twardy &reset..." msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Pauza" -msgid "E&xit..." -msgstr "W&yjdź..." +msgid "Re&sume" +msgstr "&Wznów" + +msgid "E&xit" +msgstr "W&yjście" msgid "&View" msgstr "&Widok" @@ -49,7 +52,7 @@ msgid "Re&nderer" msgstr "Re&nderer" msgid "&Qt (Software)" -msgstr "&Qt (Software)" +msgstr "&Qt (programowy)" msgid "Qt (&OpenGL)" msgstr "Qt (&OpenGL)" @@ -60,14 +63,14 @@ msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." -msgstr "Określ rozmiary..." +msgid "Specify &dimensions..." +msgstr "Określ wymiary..." msgid "F&orce 4:3 display ratio" msgstr "&Wymuś proporcje wyświetlania 4:3" msgid "&Window scale factor" -msgstr "&Czynnik skalowania okna" +msgstr "Współ&czynnik skalowania okna" msgid "&0.5x" msgstr "&0.5x" @@ -99,14 +102,14 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "Metoda filtrowania" msgid "&Nearest" -msgstr "&Nearest" +msgstr "&Najbliższa" msgid "&Linear" -msgstr "&Linear" +msgstr "&Liniowa" msgid "Hi&DPI scaling" msgstr "Skalowanie Hi&DPI" @@ -144,8 +147,14 @@ msgstr "Rodzaj ekranu &VGA" msgid "RGB &Color" msgstr "RGB - &Kolorowy" +msgid "RGB (no brown)" +msgstr "RGB (bez brązowego)" + msgid "&RGB Grayscale" -msgstr "&RGB - Skala szarości" +msgstr "&RGB - Skala odcieni szarości" + +msgid "Generic RGBI color monitor" +msgstr "Generyczny kolorowy monitor RGBI" msgid "&Amber monitor" msgstr "&Bursztynowy monitor" @@ -157,7 +166,7 @@ msgid "&White monitor" msgstr "&Biały monitor" msgid "Grayscale &conversion type" -msgstr "Typ konwersji &w skali szarości" +msgstr "Typ konwersji &w skali odcieni szarości" msgid "BT&601 (NTSC/PAL)" msgstr "BT&601 (NTSC/PAL)" @@ -166,16 +175,16 @@ msgid "BT&709 (HDTV)" msgstr "BT&709 (HDTV)" msgid "&Average" -msgstr "&Średni" +msgstr "&Średnia" msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" msgstr "Overscan dla CGA/PCjr/Tandy/E&GA/(S)VGA" msgid "Change contrast for &monochrome display" -msgstr "Zmień kontrast dla &monochromatycznego ekranu" +msgstr "Zmień kontrast dla ekranu &monochromatycznego" msgid "&Media" -msgstr "&Nośnik" +msgstr "N&ośnik" msgid "&Tools" msgstr "&Narzędzia" @@ -196,7 +205,7 @@ msgid "&Preferences..." msgstr "&Preferencje..." msgid "Enable &Discord integration" -msgstr "Włącz integrację z &Discord" +msgstr "Włącz integrację z &Discordem" msgid "Sound &gain..." msgstr "Wzmocnienie &dźwięku..." @@ -214,7 +223,7 @@ msgid "&Documentation..." msgstr "&Dokumentacja..." msgid "&About 86Box..." -msgstr "&O 86Box..." +msgstr "&O 86Boxie..." msgid "&New image..." msgstr "&Nowy obraz..." @@ -247,7 +256,7 @@ msgid "E&xport to 86F..." msgstr "E&ksportuj do 86F..." msgid "&Mute" -msgstr "&Ścisz" +msgstr "&Wycisz" msgid "E&mpty" msgstr "P&usty" @@ -256,13 +265,13 @@ msgid "Reload previous image" msgstr "Przeładuj poprzedni obraz" msgid "&Folder..." -msgstr "&Teczka..." +msgstr "&Folder..." msgid "Target &framerate" msgstr "Docelowa &liczba klatek na sekundę" msgid "&Sync with video" -msgstr "&Zsynchronizuj z wideo" +msgstr "&Zsynchronizuj z obrazem" msgid "&25 fps" msgstr "&25 fps" @@ -355,7 +364,7 @@ msgid "Speed:" msgstr "Szybkość:" msgid "Frequency:" -msgstr "Częstotliwość:" +msgstr "Taktowanie:" msgid "FPU:" msgstr "Jednostka FPU:" @@ -384,6 +393,15 @@ msgstr "Włączona (UTC)" msgid "Dynamic Recompiler" msgstr "Dynamiczny rekompilator" +msgid "CPU frame size" +msgstr "Rozmiar ramki CPU" + +msgid "Larger frames (less smooth)" +msgstr "Większe ramki (mniej płynne)" + +msgid "Smaller frames (smoother)" +msgstr "Mniejsze ramki (płynniejsze)" + msgid "Video:" msgstr "Wideo:" @@ -391,7 +409,7 @@ msgid "Video #2:" msgstr "Wideo 2:" msgid "Voodoo 1 or 2 Graphics" -msgstr "Grafika Voodoo 1 czy 2" +msgstr "Grafika Voodoo 1 lub 2" msgid "IBM 8514/A Graphics" msgstr "Grafika IBM 8514/A" @@ -399,6 +417,9 @@ msgstr "Grafika IBM 8514/A" msgid "XGA Graphics" msgstr "Grafika XGA" +msgid "Keyboard:" +msgstr "Klawiatura:" + msgid "Mouse:" msgstr "Mysz:" @@ -418,16 +439,16 @@ msgid "Joystick 4..." msgstr "Joystick 4..." msgid "Sound card #1:" -msgstr "Karta dźwiękowa 1:" +msgstr "Karta dźwiękowa nr 1:" msgid "Sound card #2:" -msgstr "Karta dźwiękowa 2:" +msgstr "Karta dźwiękowa nr 2:" msgid "Sound card #3:" -msgstr "Karta dźwiękowa 3:" +msgstr "Karta dźwiękowa nr 3:" msgid "Sound card #4:" -msgstr "Karta dźwiękowa 4:" +msgstr "Karta dźwiękowa nr 4:" msgid "MIDI Out Device:" msgstr "Urządzenie wyjściowe MIDI:" @@ -498,17 +519,20 @@ msgstr "Port równoległy 3" msgid "Parallel port 4" msgstr "Port równoległy 4" -msgid "HD Controller:" -msgstr "Kontroler dysku twardego:" - msgid "FD Controller:" msgstr "Kontroler dyskietek:" +msgid "CD-ROM Controller:" +msgstr "Kontroler CD-ROM:" + msgid "Tertiary IDE Controller" -msgstr "Trzeciorzędowy kontroler IDE" +msgstr "Trzeciorzędny kontroler IDE" msgid "Quaternary IDE Controller" -msgstr "Czwartorzędowy kontroler IDE" +msgstr "Czwartorzędny kontroler IDE" + +msgid "Hard disk" +msgstr "Dysk twardy" msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Kaseta" msgid "Hard disks:" msgstr "Dyski twarde:" +msgid "Firmware Version" +msgstr "Wersja firmware'u" + msgid "&New..." msgstr "&Nowy..." @@ -577,7 +604,7 @@ msgid "Floppy drives:" msgstr "Napędy dyskietek:" msgid "Turbo timings" -msgstr "Rozrządy Turbo" +msgstr "Timing Turbo" msgid "Check BPB" msgstr "Sprawdzaj BPB" @@ -588,8 +615,8 @@ msgstr "Napędy CD-ROM:" msgid "MO drives:" msgstr "Napędy MO:" -msgid "ZIP drives:" -msgstr "Napędy ZIP:" +msgid "Removable disk drives:" +msgstr "Stacje dysków wymiennych:" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA RTC:" msgid "ISA Memory Expansion" msgstr "Rozszerzenie pamięci ISA" +msgid "ISA ROM Cards" +msgstr "Karty ROM ISA" + msgid "Card 1:" msgstr "Karta 1:" @@ -612,6 +642,15 @@ msgstr "Karta 3:" msgid "Card 4:" msgstr "Karta 4:" +msgid "Generic ISA ROM Board" +msgstr "Generyczna płyta ROM ISA" + +msgid "Generic Dual ISA ROM Board" +msgstr "Generyczna podwójna płyta ROM ISA" + +msgid "Generic Quad ISA ROM Board" +msgstr "Generyczna poczwórna płyta ROM ISA" + msgid "ISABugger device" msgstr "Urządzenie ISABugger" @@ -628,19 +667,22 @@ msgid "Fatal error" msgstr "Fatalny błąd" msgid " - PAUSED" -msgstr " - PAUSED" - -msgid "Press %s to return to windowed mode." -msgstr "Naciśnij klawisze %s aby wrócić to trybu okna." +msgstr " - PAUZA" msgid "Speed" msgstr "Szybkość" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "Dysk wymienny %1 (%2): %3" -msgid "ZIP images" -msgstr "Obrazy ZIP" +msgid "&Removable disk %1 (%2): %3" +msgstr "Dysk &wymienny %1 (%2): %3" + +msgid "Removable disk images" +msgstr "Obrazy dysków wymiennych" + +msgid "Image %1" +msgstr "Obraz %1" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "86Box nie może znaleźć obrazów ROM nadających się do użytku.\n\nProszę pobrać zestaw obrazów ROM ze strony download, i rozpakować je do katalogu \"roms\"." @@ -667,19 +709,19 @@ msgid "Basic sector images" msgstr "Podstawowe obrazy sektorów" msgid "Surface images" -msgstr "Obrazy powierzchniowe" +msgstr "Obrazy powierzchni" msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -msgstr "Maszyna \"%hs\" nie jest dostępna, ponieważ brakuje obrazów ROM w katalogu roms/machines. Przełączanie na dostępną maszynę." +msgstr "Maszyna \"%hs\" nie jest dostępna, ponieważ brakuje ROM-ów w katalogu roms/machines. Przełączanie na dostępną maszynę." msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." -msgstr "Karta wideo \"%hs\" nie jest dostępna, ponieważ brakuje obrazów ROM w katalogu roms/video. Przełączanie na dostępną kartę wideo." +msgstr "Karta wideo \"%hs\" nie jest dostępna, ponieważ brakuje ROM-ów w katalogu roms/video. Przełączanie na dostępną kartę graficzną." msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." -msgstr "Karta wideo 2 \"%hs\" nie jest dostępna, ponieważ brakuje obrazów ROM w katalogu roms/video. Wyłączenie drugiej karty graficznej." +msgstr "Karta wideo 2 \"%hs\" nie jest dostępna, ponieważ brakuje ROM-ów w katalogu roms/video. Wyłączenie drugiej karty graficznej." msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." -msgstr "Urządzenie \"%hs\" nie jest dostępne, ponieważ brakuje obrazów ROM. Ignorowanie urządzenia." +msgstr "Urządzenie \"%hs\" nie jest dostępne, ponieważ brakuje ROM-ów. Ignorowanie urządzenia." msgid "Machine" msgstr "Maszyna" @@ -700,7 +742,7 @@ msgid "Ports (COM & LPT)" msgstr "Porty (COM & LPT)" msgid "Storage controllers" -msgstr "Kontrolery pamięci" +msgstr "Kontrolery pamięci masowej" msgid "Hard disks" msgstr "Dyski twarde" @@ -715,13 +757,13 @@ msgid "Other peripherals" msgstr "Inne urządzenia peryferyjne" msgid "Click to capture mouse" -msgstr "Kliknij w celu przechwycenia myszy" +msgstr "Kliknij, by przechwycić mysz" -msgid "Press %s to release mouse" -msgstr "Naciśnij klawisze %s w celu uwolnienia myszy" +msgid "Press %1 to release mouse" +msgstr "Naciśnij %1, by wypuścić mysz" -msgid "Press %s or middle button to release mouse" -msgstr "Naciśnij klawisze %s lub środkowy przycisk w celu uwolnienia myszy" +msgid "Press %1 or middle button to release mouse" +msgstr "Naciśnij %1 lub środkowy przycisk, by wypuścić mysz" msgid "Bus" msgstr "Magistrala" @@ -745,7 +787,7 @@ msgid "Default" msgstr "Domyślny" msgid "%1 Wait state(s)" -msgstr "%1 Stany oczekiwania" +msgstr "%1 stan(y/ów) oczekiwania" msgid "Type" msgstr "Rodzaj" @@ -780,12 +822,39 @@ msgstr "Joystick 4-osiowy, 4-przyciskowy" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "2-button gamepad(s)" +msgstr "Pad(y) z dwoma przyciskami" + +msgid "2-button flight yoke" +msgstr "Wolant z dwoma przyciskami" + +msgid "4-button gamepad" +msgstr "Pad z czterema przyciskami" + +msgid "4-button flight yoke" +msgstr "Wolant z czterema przyciskami" + +msgid "2-button flight yoke with throttle" +msgstr "Wolant z dwoma przyciskami i przepustnicą" + +msgid "4-button flight yoke with throttle" +msgstr "Wolant z czterema przyciskami i przepustnicą" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "Kierownica Win95 (3 osie, 4 przyciski)" + msgid "None" msgstr "Żaden" @@ -795,20 +864,23 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Dyskietka %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Dyskietka %1 (%2): %3" + msgid "Advanced sector images" msgstr "Zaawansowane obrazy sektorów" msgid "Flux images" -msgstr "Flux images" +msgstr "Obrazy flux" msgid "Are you sure you want to hard reset the emulated machine?" -msgstr "Jesteś pewien że chcesz wykonać twardy reset emulowanej maszyny?" +msgstr "Czy na pewno chcesz wykonać twardy reset emulowanej maszyny?" msgid "Are you sure you want to exit 86Box?" -msgstr "Jesteś pewien że chcesz zakończyć 86Box?" +msgstr "Czy na pewno chcesz zakończyć 86Box?" msgid "Unable to initialize Ghostscript" -msgstr "Nie można zainicjować Ghostscript" +msgstr "Nie można zainicjować Ghostscriptu" msgid "Unable to initialize GhostPCL" msgstr "Nie można zainicjować GhostPCL" @@ -816,11 +888,14 @@ msgstr "Nie można zainicjować GhostPCL" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "Obrazy MO" msgid "Welcome to 86Box!" -msgstr "Witamy w 86Box!" +msgstr "Witamy w 86Boxie!" msgid "Internal device" msgstr "Urządzenie wewnętrzne" @@ -829,7 +904,7 @@ msgid "Exit" msgstr "Zakończ" msgid "No ROMs found" -msgstr "Nie znaleziono obrazów ROM" +msgstr "Nie znaleziono ROM-ów" msgid "Do you want to save the settings?" msgstr "Czy chcesz zapisać ustawienia?" @@ -847,7 +922,7 @@ 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 "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\nZ wcześniejszym wkładem od Sarah Walker, leilei, JohnElliott, greatpsycho i innych.\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." +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\nZ wcześniejszym wkładem od Sarah Walker, leilei, JohnElliott, greatpsycho i innych.\n\nPrzetłumaczony przez: Fanta-Shokata, Lili1228\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" @@ -864,9 +939,6 @@ msgstr "%1 jest wymagany do automatycznej konwersji plików PostScript do PDF.\n msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 jest wymagany do automatycznej konwersji plików PCL do PDF.\n\nDokumenty wysłane do generycznej drukarki PCL zostaną zapisane jako pliki Printer Command Language (.pcl)." -msgid "Entering fullscreen mode" -msgstr "Przechodzenie do trybu pełnoekranowego" - msgid "Don't show this message again" msgstr "Nie pokazuj więcej tego komunikatu" @@ -874,10 +946,10 @@ msgid "Don't exit" msgstr "Nie kończ" msgid "Reset" -msgstr "Przywróć" +msgstr "Resetuj" msgid "Don't reset" -msgstr "Nie przywracaj" +msgstr "Nie resetuj" msgid "CD-ROM images" msgstr "Obrazy CD-ROM" @@ -892,10 +964,10 @@ msgid "GLSL shaders" msgstr "Shadery GLSL" msgid "You are loading an unsupported configuration" -msgstr "Ładujesz nieobsługiwaną konfigurację" +msgstr "Wczytujesz nieobsługiwaną konfigurację" 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 "Wybór rodzaju procesora oparty na wybranej maszynie jest wyłączony dla tej emulowanej maszyny.\n\nPozwala to na wybór procesora który jest niekompatybilny z wybraną maszyną. Jednak możesz napotkać niezgodności z BIOS-em maszyny lub innym oprogramowaniem.\n\nAktywacja tego ustawienia nie jest wspierana i każde zgłoszenie błędu może zostać zamknięte jako nieważne." +msgstr "Filtrowanie rodzaju procesora na podstawie wybranej maszyny jest wyłączone dla tej emulowanej maszyny.\n\nPozwala to na wybór procesora, który jest niekompatybilny z wybraną maszyną, jednak możesz napotkać niezgodności z BIOS-em maszyny lub innym oprogramowaniem.\n\nAktywacja tego ustawienia nie jest wspierana i każde zgłoszenie błędu może zostać zamknięte jako nieprawidłowe." msgid "Continue" msgstr "Kontynuuj" @@ -903,14 +975,20 @@ msgstr "Kontynuuj" msgid "Cassette: %1" msgstr "Kaseta: %1" +msgid "C&assette: %1" +msgstr "K&aseta: %1" + msgid "Cassette images" msgstr "Obrazy kaset" msgid "Cartridge %1: %2" -msgstr "Kartrydż %1: %2" +msgstr "Kartridż %1: %2" + +msgid "Cart&ridge %1: %2" +msgstr "Kar&tridż %1: %2" msgid "Cartridge images" -msgstr "Obrazy kartrydżu" +msgstr "Obrazy kartridżów" msgid "Resume execution" msgstr "Wznów wykonywanie" @@ -930,6 +1008,9 @@ msgstr "Twardy reset" msgid "ACPI shutdown" msgstr "Wyłączenie ACPI" +msgid "ACP&I shutdown" +msgstr "Wyłączenie ACP&I" + msgid "Hard disk (%1)" msgstr "Dysk twardy (%1)" @@ -985,7 +1066,7 @@ msgid "Disk image too large" msgstr "Obraz dysku jest za duży" msgid "Remember to partition and format the newly-created drive." -msgstr "Nie zapomnij o partycjonowaniu i sformatowaniu nowo utworzego dysku" +msgstr "Nie zapomnij o partycjonowaniu i sformatowaniu nowo utworzonego dysku." msgid "The selected file will be overwritten. Are you sure you want to use it?" msgstr "Wybrany plik zostanie nadpisany. Czy na pewno chcesz użyć tego pliku?" @@ -1000,7 +1081,7 @@ msgid "Don't overwrite" msgstr "Nie nadpisuj" msgid "Raw image" -msgstr "Obraz surowy" +msgstr "Surowy obraz" msgid "HDI image" msgstr "Obraz HDI" @@ -1018,10 +1099,10 @@ msgid "Differencing VHD" msgstr "VHD różnicujący" msgid "(N/A)" -msgstr "(Bez)" +msgstr "(nd.)" msgid "Raw image (.img)" -msgstr "Obraz surowy (.img)" +msgstr "Surowy obraz (.img)" msgid "HDI image (.hdi)" msgstr "Obraz HDI (.hdi)" @@ -1036,7 +1117,7 @@ msgid "Dynamic-size VHD (.vhd)" msgstr "VHD o dynamicznym rozmiarze (.vhd)" msgid "Differencing VHD (.vhd)" -msgstr "VHD różnicujący (.vhd)" +msgstr "VHD różnicowy (.vhd)" msgid "Large blocks (2 MB)" msgstr "Duże bloki (2 MB)" @@ -1051,7 +1132,7 @@ msgid "Select the parent VHD" msgstr "Wybierz nadrzędny plik 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 "Może to oznaczać, że obraz nadrzędny został zmodyfikowany po utworzeniu obrazu różnicującego.\n\nMoże się to również zdarzyć, jeśli pliki obrazów zostały przeniesione lub skopiowane, lub wystąpił błąd w programie, który utworzył ten dysk\n\nCzy chcesz naprawić sygnatury czasowe?" +msgstr "Może to oznaczać, że obraz nadrzędny został zmodyfikowany po utworzeniu obrazu różnicowego.\n\nMoże się to również zdarzyć, jeśli pliki obrazów zostały przeniesione lub skopiowane, lub wystąpił błąd w programie, który utworzył ten dysk.\n\nCzy chcesz naprawić sygnatury czasowe?" msgid "Parent and child disk timestamps do not match" msgstr "Sygnatury czasowe dysku nadrzędnego i podrzędnego nie zgadzają się" @@ -1077,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 KB" @@ -1168,10 +1252,10 @@ msgid "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:" +msgstr "Czułość myszy:" msgid "Select media images from program working directory" -msgstr "Wybór obrazów multimedialnych z katalogu roboczego programu" +msgstr "Wybór obrazów nośników z katalogu roboczego programu" msgid "PIT mode:" msgstr "Tryb PIT:" @@ -1192,7 +1276,7 @@ msgid "WinBox is no longer supported" msgstr "WinBox nie jest już wspierany" msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." -msgstr "Rozwój menedżera WinBox został zatrzymany w 2022 roku z powodu braku opiekunów. Ponieważ kierujemy nasze wysiłki na uczynienie 86Box jeszcze lepszym, podjęliśmy decyzję o zaprzestaniu wspierania WinBox jako menedżera.\n\nŻadne dalsze aktualizacje nie będą dostarczane za pośrednictwem WinBox i możesz napotkać nieprawidłowe zachowanie, jeśli będziesz go nadal używać z nowszymi wersjami 86Box. Wszelkie zgłoszenia błędów związane z działaniem WinBox zostaną zamknięte jako nieważne.\n\nLista innych menedżerów, z których można korzystać, znajduje się na stronie 86box.net." +msgstr "Menedżer WinBox przestał być rozwijany w 2022 roku z powodu braku opiekunów. Ponieważ kierujemy nasze wysiłki na uczynienie 86Box jeszcze lepszym, podjęliśmy decyzję o zaprzestaniu wspierania WinBox jako menedżera.\n\nŻadne dalsze aktualizacje nie będą dostarczane za pośrednictwem WinBoxa i możesz napotkać nieprawidłowe zachowanie, jeśli będziesz go nadal używać z nowszymi wersjami 86Box. Wszelkie zgłoszenia błędów związane z działaniem WinBox zostaną zamknięte jako nieważne.\n\nLista innych menedżerów, z których można korzystać, znajduje się na stronie 86box.net." msgid "Generate" msgstr "Generuj" @@ -1215,41 +1299,41 @@ msgstr "Urządzenia MCA" msgid "List of MCA devices:" msgstr "Lista urządzeń MCA:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Narzędzie do tabletów" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "O Qt" +msgid "About &Qt" +msgstr "O &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "Urządzenia MCA..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Pokaż monitory inne niż podstawowe" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Otwórz folder zrzutów ekranu..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Zastosowanie trybu rozciągania na pełnym ekranie w stanie zmaksymalizowanym" -msgid "Cursor/Puck" -msgstr "Kursor/krążek" +msgid "&Cursor/Puck" +msgstr "&Kursor/krążek" -msgid "Pen" -msgstr "Pióro" +msgid "&Pen" +msgstr "P&ióro" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Napęd CD/DVD hosta (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Napęd CD/DVD hosta (%1:)" msgid "&Connected" -msgstr "" +msgstr "&Podłączone" -msgid "Clear image history" -msgstr "Wyczyść historię obrazów" +msgid "Clear image &history" +msgstr "Wyczyść historię obrazów(&H)" msgid "Create..." msgstr "Stwórz..." @@ -1266,6 +1350,9 @@ msgstr "Null Driver" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "Zachowanie renderowania" @@ -1279,7 +1366,7 @@ msgid "VSync" msgstr "VSync" msgid "Synchronize with video" -msgstr "Zsynchronizuj z wideo" +msgstr "Synchronizuj z obrazem" msgid "Shaders" msgstr "Shadery" @@ -1303,10 +1390,10 @@ msgid "Error initializing OpenGL" msgstr "Błąd inicjalizacji OpenGL" msgid "\nFalling back to software rendering." -msgstr "\nPowrót do renderowania oprogramowania." +msgstr "\nPowrót do renderowania programowego." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Podczas wybierania obrazów nośników (CD-ROM, dyskietka itp.) otwarte okno dialogowe rozpocznie się w tym samym katalogu, co plik konfiguracyjny 86Box. To ustawienie prawdopodobnie będzie miało znaczenie tylko na macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Podczas wybierania obrazów nośników (CD-ROM, dyskietka itd.), otwarte okno dialogowe rozpocznie się w tym samym katalogu, co plik konfiguracyjny 86Box. To ustawienie prawdopodobnie będzie miało znaczenie tylko na macOS.

" msgid "This machine might have been moved or copied." msgstr "To urządzenie mogło zostać przeniesione lub skopiowane." @@ -1330,16 +1417,16 @@ msgid "MiB" msgstr "MiB" msgid "Network Card #1" -msgstr "Karta sieciowa 1" +msgstr "Karta sieciowa nr 1" msgid "Network Card #2" -msgstr "Karta sieciowa 2" +msgstr "Karta sieciowa nr 2" msgid "Network Card #3" -msgstr "Karta sieciowa 3" +msgstr "Karta sieciowa nr 3" msgid "Network Card #4" -msgstr "Karta sieciowa 4" +msgstr "Karta sieciowa nr 4" msgid "Mode:" msgstr "Tryb:" @@ -1360,40 +1447,70 @@ msgid "Novell NetWare 2.x Key Card" msgstr "Karta klucza Novell NetWare 2.x" msgid "Serial port passthrough 1" -msgstr "Przełączanie portu szeregowego 1" +msgstr "Przelotka portu szeregowego 1" msgid "Serial port passthrough 2" -msgstr "Przełączanie portu szeregowego 2" +msgstr "Przelotka portu szeregowego 2" msgid "Serial port passthrough 3" -msgstr "Przełączanie portu szeregowego 3" +msgstr "Przelotka portu szeregowego 3" msgid "Serial port passthrough 4" -msgstr "Przełączanie portu szeregowego 4" +msgstr "Przelotka portu szeregowego 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Opcje renderowania..." +msgid "PC/XT Keyboard" +msgstr "Klawiatura PC/XT" + +msgid "AT Keyboard" +msgstr "Klawiatura AT" + +msgid "AX Keyboard" +msgstr "Klawiatura AX" + +msgid "PS/2 Keyboard" +msgstr "Klawiatura PS/2" + +msgid "PS/55 Keyboard" +msgstr "Klawiatura PS/55" + +msgid "Keys" +msgstr "Klawisze" + msgid "Logitech/Microsoft Bus Mouse" -msgstr "Mysz magistralna Logitech/Microsoft" +msgstr "Mysz magistralowa Logitech/Microsoft" msgid "Microsoft Bus Mouse (InPort)" -msgstr "Mysz magistralna Microsoft (InPort)" +msgstr "Mysz magistralowa Microsoft (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Mysz szeregowa Mouse Systems" +msgid "Mouse Systems Bus Mouse" +msgstr "Mysz magistralowa Mouse Systems" + msgid "Microsoft Serial Mouse" msgstr "Mysz szeregowa Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "Microsoft Serial BallPoint" + msgid "Logitech Serial Mouse" msgstr "Mysz szeregowa Logitech" msgid "PS/2 Mouse" msgstr "Mysz PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "PS/2 QuickPort Mouse" + msgid "3M MicroTouch (Serial)" -msgstr "3M MicroTouch (szeregowa)" +msgstr "3M MicroTouch (szeregowy)" + +msgid "Default Baud rate" +msgstr "Domyślna szybkość transmisji" msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Standardowy modem zgodny z Hayes" @@ -1402,7 +1519,7 @@ msgid "Roland MT-32 Emulation" msgstr "Emulacja Roland MT-32" msgid "Roland MT-32 (New) Emulation" -msgstr "Emulacja Roland MT-32 (nowego)" +msgstr "(Nowa) emulacja Roland MT-32" msgid "Roland CM-32L Emulation" msgstr "Emulacja Roland CM-32L" @@ -1411,7 +1528,7 @@ msgid "Roland CM-32LN Emulation" msgstr "Emulacja Roland CM-32LN" msgid "OPL4-ML Daughterboard" -msgstr "Płyta córka OPL4-ML" +msgstr "Płyta-córka OPL4-ML" msgid "System MIDI" msgstr "System MIDI" @@ -1419,11 +1536,53 @@ msgstr "System MIDI" msgid "MIDI Input Device" msgstr "Urządzenie wejściowe MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "Plik BIOS" + +msgid "BIOS file (ROM #1)" +msgstr "Plik BIOS (ROM nr 1)" + +msgid "BIOS file (ROM #2)" +msgstr "Plik BIOS (ROM nr 2)" + +msgid "BIOS file (ROM #3)" +msgstr "Plik BIOS (ROM nr 3)" + +msgid "BIOS file (ROM #4)" +msgstr "Plik BIOS (ROM nr 4)" + +msgid "BIOS address" msgstr "Adres BIOS" +msgid "BIOS address (ROM #1)" +msgstr "Adres BIOS (ROM nr 1)" + +msgid "BIOS address (ROM #2)" +msgstr "Adres BIOS (ROM nr 2)" + +msgid "BIOS address (ROM #3)" +msgstr "Adres BIOS (ROM nr 3)" + +msgid "BIOS address (ROM #4)" +msgstr "Adres BIOS (ROM nr 4)" + msgid "Enable BIOS extension ROM Writes" -msgstr "Włączenie zapisu do pamięci ROM rozszerzenia BIOS" +msgstr "Włącz zapis do pamięci ROM rozszerzenia BIOS" + +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "Włącz zapis do pamięci ROM rozszerzenia BIOS (ROM nr 1)" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "Włącz zapis do pamięci ROM rozszerzenia BIOS (ROM nr 2)" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "Włącz zapis do pamięci ROM rozszerzenia BIOS (ROM nr 3)" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "Włącz zapis do pamięci ROM rozszerzenia BIOS (ROM nr 4)" + +msgid "Linear framebuffer base" +msgstr "Adres bazowy liniowego buforu ramki" msgid "Address" msgstr "Adres" @@ -1432,8 +1591,20 @@ msgid "IRQ" msgstr "IRQ" msgid "BIOS Revision" +msgstr "Rewizja BIOS-u" + +msgid "BIOS Version" msgstr "Wersja BIOS-u" +msgid "BIOS Language" +msgstr "Język BIOS-u" + +msgid "IBM 5161 Expansion Unit" +msgstr "IBM 5161 Expansion Unit" + +msgid "IBM Cassette Basic" +msgstr "IBM Cassette Basic" + msgid "Translate 26 -> 17" msgstr "Przetłumacz 26 -> 17" @@ -1449,6 +1620,18 @@ msgstr "Odwracanie kolorów" msgid "BIOS size" msgstr "Rozmiar BIOS-u" +msgid "BIOS size (ROM #1)" +msgstr "Rozmiar BIOS-u (ROM nr 1)" + +msgid "BIOS size (ROM #2)" +msgstr "Rozmiar BIOS-u (ROM nr 2)" + +msgid "BIOS size (ROM #3)" +msgstr "Rozmiar BIOS-u (ROM nr 3)" + +msgid "BIOS size (ROM #4)" +msgstr "Rozmiar BIOS-u (ROM nr 4)" + msgid "Map C0000-C7FFF as UMB" msgstr "Mapowanie C0000-C7FFF jako UMB" @@ -1524,6 +1707,9 @@ msgstr "Poziom pogłosu" msgid "Interpolation Method" msgstr "Metoda interpolacji" +msgid "Dynamic Sample Loading" +msgstr "Dynamiczne wczytywanie sampli" + msgid "Reverb Output Gain" msgstr "Wzmocnienie sygnału wyjściowego pogłosu" @@ -1611,6 +1797,12 @@ msgstr "Niski poziom DMA" msgid "Enable Game port" msgstr "Włącz port gier" +msgid "SID Model" +msgstr "Model SID" + +msgid "SID Filter Strength" +msgstr "Siła filtra SID" + msgid "Surround module" msgstr "Moduł Surround" @@ -1618,11 +1810,14 @@ msgid "CODEC" msgstr "CODEC" msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "Podniesienie przerwania CODEC przy konfiguracji CODEC (wymagane przez niektóre sterowniki)" +msgstr "Podnieś przerwanie CODEC podczas konfiguracji CODEC-a (wymagane przez niektóre sterowniki)" msgid "SB Address" msgstr "Adres SB" +msgid "Use EEPROM setting" +msgstr "Użyj ustawień z EEPROM" + msgid "WSS IRQ" msgstr "WSS IRQ" @@ -1636,7 +1831,7 @@ msgid "Receive MIDI input (MPU-401)" msgstr "Odbiór wejścia MIDI (MPU-401)" msgid "SB low DMA" -msgstr "SB low DMA" +msgstr "Low DMA SB" msgid "6CH variant (6-channel)" msgstr "Wariant 6CH (6-kanałowy)" @@ -1651,7 +1846,7 @@ msgid "High DMA" msgstr "Wysokie DMA" msgid "Control PC speaker" -msgstr "Głośnik komputera sterującego" +msgstr "Kontroluj PC speaker" msgid "Memory size" msgstr "Rozmiar pamięci" @@ -1669,10 +1864,10 @@ msgid "GUS type" msgstr "Typ GUS" msgid "Enable 0x04 \"Exit 86Box\" command" -msgstr "Włącz polecenie 0x04 \"Wyjdź z 86Box\"" +msgstr "Włącz polecenie 0x04 \"Wyjdź z 86Boxa\"" msgid "Display type" -msgstr "Typ wyświetlacza" +msgstr "Typ ekranu" msgid "Composite type" msgstr "Typ kompozytowy" @@ -1707,9 +1902,15 @@ msgstr "Typ RAMDAC" msgid "Blend" msgstr "Mieszanka" +msgid "Font" +msgstr "Font" + msgid "Bilinear filtering" msgstr "Filtrowanie dwuliniowe" +msgid "Video chroma-keying" +msgstr "Chroma-keying obrazu" + msgid "Dithering" msgstr "Dithering" @@ -1752,6 +1953,33 @@ msgstr "Prędkość transferu" msgid "EMS mode" msgstr "Tryb EMS" +msgid "EMS Address" +msgstr "Adres EMS" + +msgid "EMS 1 Address" +msgstr "Adres EMS 1" + +msgid "EMS 2 Address" +msgstr "Adres EMS 2" + +msgid "EMS Memory Size" +msgstr "Rozmiar pamięci EMS" + +msgid "EMS 1 Memory Size" +msgstr "Rozmiar pamięci EMS 1" + +msgid "EMS 2 Memory Size" +msgstr "Rozmiar pamięci EMS 2" + +msgid "Enable EMS" +msgstr "Włącz EMS" + +msgid "Enable EMS 1" +msgstr "Włącz EMS 1" + +msgid "Enable EMS 2" +msgstr "Włącz EMS 2" + msgid "Address for > 2 MB" msgstr "Adres dla > 2 MB" @@ -1770,11 +1998,11 @@ msgstr "Zawsze z wybraną prędkością" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Ustawienia BIOS + klawisze skrótu (wyłączone podczas testu POST)" -msgid "64 kB starting from F0000" -msgstr "64 kB począwszy od F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB począwszy od F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB począwszy od E0000 (adres MSB odwrócony, najpierw ostatnie 64KB)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB począwszy od E0000 (adres MSB odwrócony, najpierw ostatnie 64 KB)" msgid "Sine" msgstr "Sinusoidalny" @@ -1783,7 +2011,7 @@ msgid "Triangle" msgstr "Trójkątny" msgid "Linear" -msgstr "Liniowa" +msgstr "Liniowy" msgid "4th Order" msgstr "4. rzędu" @@ -1804,13 +2032,13 @@ msgid "Three" msgstr "Trzy" msgid "Wheel" -msgstr "Koło" +msgstr "Rolka" msgid "Five + Wheel" -msgstr "" +msgstr "Pięć + rolka" msgid "Five + 2 Wheels" -msgstr "" +msgstr "Pięć + dwie rolki" msgid "A3 - SMT2 Serial / SMT3(R)V" msgstr "A3 - SMT2 szeregowa / SMT3(R)V" @@ -1882,7 +2110,7 @@ msgid "New" msgstr "Nowość" msgid "Color (generic)" -msgstr "Kolor (generyczny)" +msgstr "Kolorowy (generyczny)" msgid "Green Monochrome" msgstr "Zielony monochromatyczny" @@ -1894,10 +2122,10 @@ msgid "Gray Monochrome" msgstr "Szary monochromatyczny" msgid "Color (no brown)" -msgstr "Kolor (bez brązowego)" +msgstr "Kolorowy (bez brązowego)" msgid "Color (IBM 5153)" -msgstr "Kolor (IBM 5153)" +msgstr "Kolorowy (IBM 5153)" msgid "Simple doubling" msgstr "Proste podwojenie" @@ -1908,6 +2136,15 @@ msgstr "Interpolacja sRGB" msgid "Linear interpolation" msgstr "Interpolacja liniowa" +msgid "Has secondary 8x8 character set" +msgstr "Posiada pomocniczy zestaw znaków 8x8" + +msgid "Has Quadcolor II daughter board" +msgstr "Posiada płytę rozszerzeń Quadcolor II" + +msgid "Alternate monochrome contrast" +msgstr "Alternatywny kontrast monochromatyczny" + msgid "128 KB" msgstr "128 KB" @@ -1927,7 +2164,7 @@ msgid "Color 80x25 (5153/CGA)" msgstr "Kolor 80x25 (5153/CGA)" msgid "Enhanced Color - Normal Mode (5154/ECD)" -msgstr "Rozszerzone kolory - tryb normalny (5154/ECD)" +msgstr "Rozszerzony kolor - tryb zwykły (5154/ECD)" msgid "Enhanced Color - Enhanced Mode (5154/ECD)" msgstr "Rozszerzony kolor - tryb rozszerzony (5154/ECD)" @@ -1941,11 +2178,14 @@ msgstr "Bursztynowy" msgid "Gray" msgstr "Szary" +msgid "Grayscale" +msgstr "Skala odcieni szarości" + msgid "Color" -msgstr "Kolor" +msgstr "Kolorowy" msgid "U.S. English" -msgstr "Amerykański angielski" +msgstr "Angielski (USA)" msgid "Scandinavian" msgstr "Skandynawski" @@ -1954,13 +2194,19 @@ msgid "Other languages" msgstr "Inne języki" msgid "Bochs latest" -msgstr "Bochs najnowsze" +msgstr "Najnowszy Bochs" + +msgid "Apply overscan deltas" +msgstr "Zastosuj delty overscanu" + +msgid "Mono Interlaced" +msgstr "Monochromatyczny z przeplotem" msgid "Mono Non-Interlaced" -msgstr "Mono bez przeplotu" +msgstr "Monochromatyczny bez przeplotu" msgid "Color Interlaced" -msgstr "Kolor z przeplotem" +msgstr "Kolorowy z przeplotem" msgid "Color Non-Interlaced" msgstr "Kolor bez przeplotu" @@ -1969,7 +2215,7 @@ msgid "3Dfx Voodoo Graphics" msgstr "Grafika 3Dfx Voodoo" msgid "Obsidian SB50 + Amethyst (2 TMUs)" -msgstr "Obsydian SB50 + Ametyst (2 jednostki TMU)" +msgstr "Obsidian SB50 + Amethyst (2 jednostki TMU)" msgid "8-bit" msgstr "8-bitowy" @@ -1993,7 +2239,7 @@ msgid "High-Speed" msgstr "Wysoka prędkość" msgid "Stereo LPT DAC" -msgstr "Stereofoniczny przetwornik cyfrowo-analogowy LPT" +msgstr "Stereo LPT DAC" msgid "Generic Text Printer" msgstr "Generyczna drukarka tekstowa" @@ -2008,7 +2254,7 @@ msgid "Generic PCL5e Printer" msgstr "Generyczna drukarka PCL5e" msgid "Parallel Line Internet Protocol" -msgstr "Protokół internetowy linii równoległej" +msgstr "Parallel Line Internet Protocol" msgid "Protection Dongle for Savage Quest" msgstr "Klucz ochronny dla Savage Quest" @@ -2023,7 +2269,7 @@ msgid "Host Serial Device" msgstr "Urządzenie szeregowe hosta" msgid "Name of pipe" -msgstr "Nazwa rury" +msgstr "Nazwa potoku" msgid "Data bits" msgstr "Bity danych" @@ -2032,19 +2278,22 @@ msgid "Stop bits" msgstr "Bity stopu" msgid "Baud Rate of Passthrough" -msgstr "Szybkość transmisji Passthrough" +msgstr "Szybkość transmisji przelotowej" msgid "Named Pipe (Server)" -msgstr "Nazwana rura (serwer)" +msgstr "Nazwany potok (serwer)" + +msgid "Named Pipe (Client)" +msgstr "Nazwany potok (klient)" msgid "Host Serial Passthrough" -msgstr "Przejście przez port szeregowy hosta" +msgstr "Przelot przez port szeregowy hosta" msgid "E&ject %1" msgstr "W&yjmij %1" msgid "&Unmute" -msgstr "&Wycisz" +msgstr "&Odcisz" msgid "Softfloat FPU" msgstr "FPU Softfloat" @@ -2053,28 +2302,28 @@ msgid "High performance impact" msgstr "Wysoki wpływ na wydajność" msgid "[Generic] RAM Disk (max. speed)" -msgstr "[Generic] Dysk RAM (maks. prędkość)" +msgstr "[generyczny] Dysk RAM (maks. prędkość)" msgid "[Generic] 1989 (3500 RPM)" -msgstr "" +msgstr "[generyczny] 1989 (3500 RPM)" msgid "[Generic] 1992 (3600 RPM)" -msgstr "" +msgstr "[generyczny] 1992 (3600 RPM)" msgid "[Generic] 1994 (4500 RPM)" -msgstr "" +msgstr "[generyczny] 1994 (4500 RPM)" msgid "[Generic] 1996 (5400 RPM)" -msgstr "" +msgstr "[generyczny] 1996 (5400 RPM)" msgid "[Generic] 1997 (5400 RPM)" -msgstr "" +msgstr "[generyczny] 1997 (5400 RPM)" msgid "[Generic] 1998 (5400 RPM)" -msgstr "" +msgstr "[generyczny] 1998 (5400 RPM)" msgid "[Generic] 2000 (7200 RPM)" -msgstr "" +msgstr "[generyczny] 2000 (7200 RPM)" msgid "IBM 8514/A clone (ISA)" msgstr "Klon IBM 8514/A (ISA)" @@ -2082,6 +2331,12 @@ msgstr "Klon IBM 8514/A (ISA)" msgid "Vendor" msgstr "Producent" +msgid "30 Hz (JMP2 = 1)" +msgstr "30 Hz (JMP2 = 1)" + +msgid "60 Hz (JMP2 = 2)" +msgstr "60 Hz (JMP2 = 2)" + msgid "Generic PC/XT Memory Expansion" msgstr "Generyczne rozszerzenie pamięci PC/XT" @@ -2089,70 +2344,139 @@ msgid "Generic PC/AT Memory Expansion" msgstr "Generyczne rozszerzenie pamięci PC/AT" msgid "Unable to find Dot-Matrix fonts" -msgstr "Nie można znaleźć czcionek igłowych" +msgstr "Nie można znaleźć fontów igłowych" msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for the emulation of the Generic ESC/P Dot-Matrix Printer." -msgstr "Czcionki TrueType w katalogu \"roms/printer/fonts\" są wymagane do emulacji generyczniej drukarki igłowej ESC/P." +msgstr "Fonty TrueType w katalogu \"roms/printer/fonts\" są wymagane do emulacji generycznej drukarki igłowej ESC/P." msgid "Inhibit multimedia keys" -msgstr "" +msgstr "Przejmij klawisze multimedialne" msgid "Ask for confirmation before saving settings" -msgstr "" +msgstr "Pytaj o potwierdzenie przed zapisaniem ustawień" msgid "Ask for confirmation before hard resetting" -msgstr "" +msgstr "Pytaj o potwierdzenie przed twardym resetem" msgid "Ask for confirmation before quitting" -msgstr "" - -msgid "Display hotkey message when entering full-screen mode" -msgstr "" +msgstr "Pytaj o potwierdzenie przed wyjściem" msgid "Options" -msgstr "" +msgstr "Opcje" msgid "Model" -msgstr "" +msgstr "Model" msgid "Model:" -msgstr "" +msgstr "Model:" msgid "Failed to initialize Vulkan renderer." -msgstr "" +msgstr "Nie udało się zainicjować renderera Vulkan." msgid "GLSL Error" -msgstr "" +msgstr "Błąd GLSL" msgid "Could not load shader: %1" -msgstr "" +msgstr "Nie udało się wczytać shadera: %1" msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "" +msgstr "Wymagana jest wersja OpenGL 3.0 lub wyższa. Aktualna wersja GLSL to %1.%2" msgid "Could not load texture: %1" -msgstr "" +msgstr "Nie udało się wczytać tekstury: %1" msgid "Could not compile shader:\n\n%1" -msgstr "" +msgstr "Nie udało się skompilować shadera:\n\n%1" msgid "Program not linked:\n\n%1" -msgstr "" +msgstr "Program niezalinkowany:\n\n%1" msgid "Shader Manager" -msgstr "" +msgstr "Menedżer shaderów" msgid "Shader Configuration" -msgstr "" +msgstr "Konfiguracja shadera" msgid "Add" -msgstr "" +msgstr "Dodaj" msgid "Move up" -msgstr "" +msgstr "Przesuń w górę" msgid "Move down" -msgstr "" +msgstr "Przesuń w dół" msgid "Could not load file %1" +msgstr "Nie można wczytać pliku %1" + +msgid "Key Bindings:" +msgstr "Przypisania klawiszy:" + +msgid "Action" +msgstr "Akcja" + +msgid "Keybind" +msgstr "Przypisane klawisze" + +msgid "Clear binding" +msgstr "Wyczyść przypisanie" + +msgid "Bind" +msgstr "Przypisanie" + +msgid "Bind Key" +msgstr "Przypisanie klawiszy" + +msgid "Enter key combo:" +msgstr "Wciśnij kombinację klawiszy:" + +msgid "Bind conflict" +msgstr "Konflikt przypisań" + +msgid "This key combo is already in use." +msgstr "Ta kombinacja klawiszy jest już w użyciu." + +msgid "Send Control+Alt+Del" +msgstr "Wyślij Control+Alt+Del" + +msgid "Send Control+Alt+Escape" +msgstr "Wyślij Control+Alt+Escape" + +msgid "Toggle fullscreen" +msgstr "Przełącz pełny ekran" + +msgid "Screenshot" +msgstr "Zrzut ekranu" + +msgid "Release mouse pointer" +msgstr "Wypuść wskaźnik myszy" + +msgid "Toggle pause" +msgstr "Przełącz pauzę" + +msgid "Toggle mute" +msgstr "Przełącz wyciszenie" + +msgid "Text files" +msgstr "Pliki tekstowe" + +msgid "ROM files" +msgstr "Pliki ROM" + +msgid "SoundFont files" +msgstr "Pliki SoundFont" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" msgstr "" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index e33630ccf..2199780a1 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -13,13 +13,13 @@ msgid "&Keyboard requires capture" msgstr "&Teclado requer captura" msgid "&Right CTRL is left ALT" -msgstr "&CTRL direito é o ALT esquerdo" +msgstr "CTR&L direito é o ALT esquerdo" msgid "&Hard Reset..." msgstr "&Reinicialização completa..." msgid "&Ctrl+Alt+Del" -msgstr "&Ctrl+Alt+Del" +msgstr "Ctrl+Alt+&Del" msgid "Ctrl+Alt+&Esc" msgstr "Ctrl+Alt+&Esc" @@ -27,17 +27,20 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Pausar" -msgid "E&xit..." -msgstr "&Sair..." +msgid "Re&sume" +msgstr "&Continuar" + +msgid "E&xit" +msgstr "&Sair" msgid "&View" msgstr "&Exibir" msgid "&Hide status bar" -msgstr "&Ocultar barra de status" +msgstr "Ocultar barra de &status" msgid "Hide &toolbar" -msgstr "Ocultar &barra de ferramenta" +msgstr "Ocultar barra de &ferramenta" msgid "&Resizeable window" msgstr "&Janela redimensionável" @@ -60,14 +63,14 @@ msgstr "Open&GL (Núcleo 3.0)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "Especificar as dimensões..." msgid "F&orce 4:3 display ratio" msgstr "F&orçar proporção de tela em 4:3" msgid "&Window scale factor" -msgstr "&Fator de redimensionamento da janela" +msgstr "F&ator de redimensionamento da janela" msgid "&0.5x" msgstr "&0,5x" @@ -99,8 +102,8 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" -msgstr "Método de filtragem" +msgid "Fi<er method" +msgstr "Método d&e filtragem" msgid "&Nearest" msgstr "&Mais próximo" @@ -115,7 +118,7 @@ msgid "&Fullscreen" msgstr "&Tela cheia" msgid "Fullscreen &stretch mode" -msgstr "Modo de &redimensionamento da tela cheia" +msgstr "Modo de redimensionamento da tela &cheia" msgid "&Full screen stretch" msgstr "&Tela cheia redimensionada" @@ -133,7 +136,7 @@ msgid "4:&3 Integer scale" msgstr "Redimensionamento com valores inteiros 4:&3" msgid "E&GA/(S)VGA settings" -msgstr "Configurações de E&GA/(S)VGA" +msgstr "Configurações de EGA/(S)&VGA" msgid "&Inverted VGA monitor" msgstr "Monitor VGA &invertido" @@ -144,9 +147,15 @@ msgstr "&Tipo de tela VGA" msgid "RGB &Color" msgstr "&Cor RGB" +msgid "RGB (no brown)" +msgstr "RGB (sem marrom)" + msgid "&RGB Grayscale" msgstr "Tons de cinza &RGB" +msgid "Generic RGBI color monitor" +msgstr "Monitor colorido RGBI genérico" + msgid "&Amber monitor" msgstr "Monitor &âmbar" @@ -208,7 +217,7 @@ msgid "End trace" msgstr "Finalizar rastreamento" msgid "&Help" -msgstr "&Ajuda" +msgstr "Aj&uda" msgid "&Documentation..." msgstr "&Documentação..." @@ -352,7 +361,7 @@ msgid "CPU type:" msgstr "Tipo de CPU:" msgid "Speed:" -msgstr "Veloc.:" +msgstr "Velocidade:" msgid "Frequency:" msgstr "Frequência:" @@ -384,6 +393,15 @@ msgstr "Ativar (UTC)" msgid "Dynamic Recompiler" msgstr "Recompilador dinâmico" +msgid "CPU frame size" +msgstr "Tamanho de quadro do CPU" + +msgid "Larger frames (less smooth)" +msgstr "Quadros largos (menos suave)" + +msgid "Smaller frames (smoother)" +msgstr "Quadros menores (mais suave)" + msgid "Video:" msgstr "Vídeo:" @@ -399,6 +417,9 @@ msgstr "Gráficos IBM 8514/A" msgid "XGA Graphics" msgstr "Gráficos XGA" +msgid "Keyboard:" +msgstr "Teclado:" + msgid "Mouse:" msgstr "Mouse:" @@ -442,7 +463,7 @@ msgid "Use FLOAT32 sound" msgstr "Usar som FLOAT32" msgid "FM synth driver" -msgstr "Controlador de sint. FM" +msgstr "Driver de sintetizador FM" msgid "Nuked (more accurate)" msgstr "Nuked (mais preciso)" @@ -498,18 +519,21 @@ msgstr "Porta paralela 3" msgid "Parallel port 4" msgstr "Porta paralela 4" -msgid "HD Controller:" -msgstr "Controlador HD:" - msgid "FD Controller:" msgstr "Controlador FD:" +msgid "CD-ROM Controller:" +msgstr "Controlador de CD-ROM:" + msgid "Tertiary IDE Controller" msgstr "Controlador IDE terciário" msgid "Quaternary IDE Controller" msgstr "Controlador IDE quaternário" +msgid "Hard disk" +msgstr "Disco rígido" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Cassete" msgid "Hard disks:" msgstr "Discos rígidos:" +msgid "Firmware Version" +msgstr "Versão de Firmware" + msgid "&New..." msgstr "&Novo..." @@ -588,8 +615,8 @@ msgstr "Unidades de CD-ROM:" msgid "MO drives:" msgstr "Unidades magneto-ópticas:" -msgid "ZIP drives:" -msgstr "Unidades ZIP:" +msgid "Removable disk drives:" +msgstr "Unidades de disco removível:" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "RTC ISA:" msgid "ISA Memory Expansion" msgstr "Expansão de memória ISA" +msgid "ISA ROM Cards" +msgstr "Placas ROM ISA" + msgid "Card 1:" msgstr "Placa 1:" @@ -612,6 +642,15 @@ msgstr "Placa 3:" msgid "Card 4:" msgstr "Placa 4:" +msgid "Generic ISA ROM Board" +msgstr "Placa ROM ISA Genérica" + +msgid "Generic Dual ISA ROM Board" +msgstr "Placa Dual ROM ISA Genérica" + +msgid "Generic Quad ISA ROM Board" +msgstr "Placa Quad ROM ISA Genérica" + msgid "ISABugger device" msgstr "Dispositivo ISABugger" @@ -630,17 +669,20 @@ msgstr "Erro fatal" msgid " - PAUSED" msgstr " - PAUSADO" -msgid "Press %s to return to windowed mode." -msgstr "Use %s para retornar ao modo janela." - msgid "Speed" msgstr "Velocidade" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "Disco removível %1 (%2): %3" -msgid "ZIP images" -msgstr "Imagens ZIP" +msgid "&Removable disk %1 (%2): %3" +msgstr "Disco &removível %1 (%2): %3" + +msgid "Removable disk images" +msgstr "Imagens de disco removível" + +msgid "Image %1" +msgstr "Imagem %1" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "O 86Box não conseguiu encontrar nenhuma imagem de ROM utilizável.\n\nPor favor, baixe um conjunto de ROM e extraia no diretório \"roms\"." @@ -717,11 +759,11 @@ msgstr "Outros periféricos" msgid "Click to capture mouse" msgstr "Clique para capturar o mouse" -msgid "Press %s to release mouse" -msgstr "Aperte %s para liberar o mouse" +msgid "Press %1 to release mouse" +msgstr "Aperte %1 para liberar o mouse" -msgid "Press %s or middle button to release mouse" -msgstr "Aperte %s ou botão do meio para liberar o mouse" +msgid "Press %1 or middle button to release mouse" +msgstr "Aperte %1 ou botão do meio para liberar o mouse" msgid "Bus" msgstr "Barramento" @@ -780,12 +822,39 @@ msgstr "Joystick padrão de 4 eixos, 4 botões" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedais" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Sistema de Controle de Voo Thrustmaster" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "SCV Thrustmaster + Sistema de Controle de Leme" + +msgid "2-button gamepad(s)" +msgstr "Gamepad(s) de 2 botões" + +msgid "2-button flight yoke" +msgstr "Manche de voo de 2 botões" + +msgid "4-button gamepad" +msgstr "Gamepad de 4 botões" + +msgid "4-button flight yoke" +msgstr "Manche de voo de 4 botões" + +msgid "2-button flight yoke with throttle" +msgstr "Manche de voo de 2 botões com acelerador" + +msgid "4-button flight yoke with throttle" +msgstr "Manche de voo de 4 botões com acelerador" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "Volante Win95 (3 eixos, 4 botões)" + msgid "None" msgstr "Nenhum" @@ -795,6 +864,9 @@ msgstr "%1 MB (CCS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Disquete %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Disquete %1 (%2): %3" + msgid "Advanced sector images" msgstr "Imagens de setor avançado" @@ -816,6 +888,9 @@ msgstr "Não foi possível inicializar o GhostPCL" msgid "MO %1 (%2): %3" msgstr "Magneto-óptico %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&Magneto-óptico %1 (%2): %3" + msgid "MO images" msgstr "Imagens magneto-ópticas" @@ -844,7 +919,7 @@ msgid "About 86Box" msgstr "Sobre o 86Box" msgid "86Box v" -msgstr "86Box versão" +msgstr "86Box versão " 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\nCom contribuições anteriores de Sarah Walker, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva, Nelson K. Hennemann Filho\n\nLançado sob a Licença Pública Geral GNU, versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." @@ -864,9 +939,6 @@ msgstr "%1 é necessário para a conversão automática de arquivos PostScript p msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 é necessário para a conversão automática de arquivos PCL para PDF.\n\nQualquer documento enviado para a impressora genérica PCL será salvo como arquivos Printer Command Language (.pcl)." -msgid "Entering fullscreen mode" -msgstr "Entrando no modo de tela cheia" - msgid "Don't show this message again" msgstr "Não exibir esta mensagem novamente" @@ -903,12 +975,18 @@ msgstr "Continuar" msgid "Cassette: %1" msgstr "Cassete: %1" +msgid "C&assette: %1" +msgstr "C&assete: %1" + msgid "Cassette images" msgstr "Imagens de cassete" msgid "Cartridge %1: %2" msgstr "Cartucho %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Car&tucho %1: %2" + msgid "Cartridge images" msgstr "Imagens de cartucho" @@ -930,6 +1008,9 @@ msgstr "Reinicialização completa" msgid "ACPI shutdown" msgstr "Desligamento por ACPI" +msgid "ACP&I shutdown" +msgstr "Desligamento por ACP&I" + msgid "Hard disk (%1)" msgstr "Disco rígido (%1)" @@ -1077,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 KB" @@ -1215,41 +1299,41 @@ msgstr "Dispositivos MCA" msgid "List of MCA devices:" msgstr "Lista de dispositivos MCA:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Ferramenta para tablet" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "Sobre o Qt" +msgid "About &Qt" +msgstr "Sobre o &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "Dispositivos MCA..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Mostrar monitores não primários" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Abrir pasta de capturas de tela..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Aplicar modo de ampliação em tela cheia quando maximizado" -msgid "Cursor/Puck" -msgstr "Cursor/Puck" +msgid "&Cursor/Puck" +msgstr "&Cursor/Puck" -msgid "Pen" -msgstr "Caneta" +msgid "&Pen" +msgstr "C&aneta" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Unidade de CD/DVD do anfitrião (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Unidade de CD/DVD do anfitrião (%1:)" msgid "&Connected" msgstr "&Conectado" -msgid "Clear image history" -msgstr "Limpar histórico de imagens" +msgid "Clear image &history" +msgstr "Limpar histórico de imagens(&H)" msgid "Create..." msgstr "Criar..." @@ -1266,6 +1350,9 @@ msgstr "Driver nulo" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "Comportamento de renderização" @@ -1305,8 +1392,8 @@ msgstr "Erro ao inicializar o OpenGL" msgid "\nFalling back to software rendering." msgstr "\nVoltando à renderização de software." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Ao selecionar imagens de mídia (CD-ROM, disquete, etc.), a caixa de diálogo de abertura será iniciada no mesmo diretório do arquivo de configuração do 86Box. Essa configuração provavelmente só fará diferença no macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Ao selecionar imagens de mídia (CD-ROM, disquete, etc.), a caixa de diálogo de abertura será iniciada no mesmo diretório do arquivo de configuração do 86Box. Essa configuração provavelmente só fará diferença no macOS.

" msgid "This machine might have been moved or copied." msgstr "Essa máquina pode ter sido movida ou copiada." @@ -1371,9 +1458,27 @@ msgstr "Passagem de porta serial 3" msgid "Serial port passthrough 4" msgstr "Passagem de porta serial 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Opções do renderizador..." +msgid "PC/XT Keyboard" +msgstr "Teclado PC/XT" + +msgid "AT Keyboard" +msgstr "Teclado AT" + +msgid "AX Keyboard" +msgstr "Teclado AX" + +msgid "PS/2 Keyboard" +msgstr "Teclado PS/2" + +msgid "PS/55 Keyboard" +msgstr "Teclado PS/55" + +msgid "Keys" +msgstr "Teclas" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Mouse de barramento Logitech/Microsoft" @@ -1383,18 +1488,30 @@ msgstr "Mouse de barramento Microsoft (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Mouse serial Mouse Systems" +msgid "Mouse Systems Bus Mouse" +msgstr "Mouse de barramento Mouse Systems" + msgid "Microsoft Serial Mouse" msgstr "Mouse serial Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "Mouse serial Microsoft BallPoint" + msgid "Logitech Serial Mouse" msgstr "Mouse serial Logitech" msgid "PS/2 Mouse" msgstr "Mouse PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "Mouse PS/2 QuickPort" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (serial)" +msgid "Default Baud rate" +msgstr "Taxa de transmissão padrão" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Modem padrão compatível com Hayes" @@ -1419,12 +1536,54 @@ msgstr "Sistema MIDI" msgid "MIDI Input Device" msgstr "Dispositivo de entrada MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "Arquivo do BIOS" + +msgid "BIOS file (ROM #1)" +msgstr "Arquivo do BIOS (ROM #1)" + +msgid "BIOS file (ROM #2)" +msgstr "Arquivo do BIOS (ROM #2)" + +msgid "BIOS file (ROM #3)" +msgstr "Arquivo do BIOS (ROM #3)" + +msgid "BIOS file (ROM #4)" +msgstr "Arquivo do BIOS (ROM #4)" + +msgid "BIOS address" msgstr "Endereço do BIOS" +msgid "BIOS address (ROM #1)" +msgstr "Endereço do BIOS (ROM #1)" + +msgid "BIOS address (ROM #2)" +msgstr "Endereço do BIOS (ROM #2)" + +msgid "BIOS address (ROM #3)" +msgstr "Endereço do BIOS (ROM #3)" + +msgid "BIOS address (ROM #4)" +msgstr "Endereço do BIOS (ROM #4)" + msgid "Enable BIOS extension ROM Writes" msgstr "Habilitar gravações na ROM de extensão do BIOS" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "Habilitar gravações na ROM de extensão do BIOS (ROM #1)" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "Habilitar gravações na ROM de extensão do BIOS (ROM #2)" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "Habilitar gravações na ROM de extensão do BIOS (ROM #3)" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "Habilitar gravações na ROM de extensão do BIOS (ROM #4)" + +msgid "Linear framebuffer base" +msgstr "Base do framebuffer linear" + msgid "Address" msgstr "Endereço" @@ -1434,6 +1593,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "Revisão do BIOS" +msgid "BIOS Version" +msgstr "Versão do BIOS" + +msgid "BIOS Language" +msgstr "Idioma do BIOS" + +msgid "IBM 5161 Expansion Unit" +msgstr "Unidade de Expansão IBM 5161" + +msgid "IBM Cassette Basic" +msgstr "Cassete BASIC IBM" + msgid "Translate 26 -> 17" msgstr "Traduzir 26 -> 17" @@ -1449,6 +1620,18 @@ msgstr "Inverter cores" msgid "BIOS size" msgstr "Tamanho do BIOS" +msgid "BIOS size (ROM #1)" +msgstr "Tamanho do BIOS (ROM #1)" + +msgid "BIOS size (ROM #2)" +msgstr "Tamanho do BIOS (ROM #2)" + +msgid "BIOS size (ROM #3)" +msgstr "Tamanho do BIOS (ROM #3)" + +msgid "BIOS size (ROM #4)" +msgstr "Tamanho do BIOS (ROM #4)" + msgid "Map C0000-C7FFF as UMB" msgstr "Mapear C0000-C7FFF como UMB" @@ -1524,6 +1707,9 @@ msgstr "Nível de reverberação" msgid "Interpolation Method" msgstr "Método de interpolação" +msgid "Dynamic Sample Loading" +msgstr "Carregamento dinâmico de amostra" + msgid "Reverb Output Gain" msgstr "Ganho da saída da reverberação" @@ -1531,7 +1717,7 @@ msgid "Reversed stereo" msgstr "Estéreo invertido" msgid "Nice ramp" -msgstr "Bela rampa" +msgstr "Rampa suave" msgid "Hz" msgstr "Hz" @@ -1611,6 +1797,12 @@ msgstr "DMA baixo" msgid "Enable Game port" msgstr "Ativar a porta do jogo" +msgid "SID Model" +msgstr "Modelo do SID" + +msgid "SID Filter Strength" +msgstr "Força do Filtro SID" + msgid "Surround module" msgstr "Módulo surround" @@ -1623,6 +1815,9 @@ msgstr "Aumentar a interrupção do CODEC na configuração do CODEC (necessári msgid "SB Address" msgstr "Endereço do SB" +msgid "Use EEPROM setting" +msgstr "Usar configuração da EEPROM" + msgid "WSS IRQ" msgstr "WSS IRQ" @@ -1645,7 +1840,7 @@ msgid "Enable CMS" msgstr "Ativar o CMS" msgid "Mixer" -msgstr "Misturador" +msgstr "Mixer" msgid "High DMA" msgstr "DMA alto" @@ -1707,9 +1902,15 @@ msgstr "Tipo de RAMDAC" msgid "Blend" msgstr "Mistura" +msgid "Font" +msgstr "Fonte" + msgid "Bilinear filtering" msgstr "Filtragem bilinear" +msgid "Video chroma-keying" +msgstr "Chroma-keying de vídeo" + msgid "Dithering" msgstr "Pontilhamento" @@ -1752,6 +1953,33 @@ msgstr "Velocidade de transferência" msgid "EMS mode" msgstr "Modo EMS" +msgid "EMS Address" +msgstr "Endereço EMS" + +msgid "EMS 1 Address" +msgstr "Endereço EMS 1" + +msgid "EMS 2 Address" +msgstr "Endereço EMS 2" + +msgid "EMS Memory Size" +msgstr "Tamanho de Memória EMS" + +msgid "EMS 1 Memory Size" +msgstr "Tamanho de Memória EMS 1" + +msgid "EMS 2 Memory Size" +msgstr "Tamanho de Memória EMS 2" + +msgid "Enable EMS" +msgstr "Habilitar EMS" + +msgid "Enable EMS 1" +msgstr "Habilitar EMS 1" + +msgid "Enable EMS 2" +msgstr "Habilitar EMS 2" + msgid "Address for > 2 MB" msgstr "Endereço para > 2 MB" @@ -1770,11 +1998,11 @@ msgstr "Sempre na velocidade selecionada" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Configuração do BIOS + teclas de atalho (desativadas durante o POST)" -msgid "64 kB starting from F0000" -msgstr "64 kB a partir de F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB a partir de F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB a partir de E0000 (endereço MSB invertido, os últimos 64 kB primeiro)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB a partir de E0000 (endereço MSB invertido, os últimos 64 KB primeiro)" msgid "Sine" msgstr "Senoidal" @@ -1908,6 +2136,15 @@ msgstr "Interpolação sRGB" msgid "Linear interpolation" msgstr "Interpolação linear" +msgid "Has secondary 8x8 character set" +msgstr "Tem conjunto secundário de caracteres 8x8" + +msgid "Has Quadcolor II daughter board" +msgstr "Tem placa filha Quadcolor II" + +msgid "Alternate monochrome contrast" +msgstr "Contraste monocromático alternativo" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2178,9 @@ msgstr "Âmbar" msgid "Gray" msgstr "Cinza" +msgid "Grayscale" +msgstr "Escala de cinza" + msgid "Color" msgstr "Colorido" @@ -1956,6 +2196,12 @@ msgstr "Outros idiomas" msgid "Bochs latest" msgstr "Bochs mais recente" +msgid "Apply overscan deltas" +msgstr "Aplicar deltas de overscan" + +msgid "Mono Interlaced" +msgstr "Monocromático entrelaçado" + msgid "Mono Non-Interlaced" msgstr "Monocromático não entrelaçado" @@ -1999,7 +2245,7 @@ msgid "Generic Text Printer" msgstr "Impressora de texto genérica" msgid "Generic ESC/P Dot-Matrix Printer" -msgstr "Impressora matricial de pontos ESC/P genérica" +msgstr "Impressora matricial ESC/P genérica" msgid "Generic PostScript Printer" msgstr "Impressora PostScript genérica" @@ -2023,7 +2269,7 @@ msgid "Host Serial Device" msgstr "Dispositivo serial host" msgid "Name of pipe" -msgstr "Nome do tubo" +msgstr "Nome do pipe" msgid "Data bits" msgstr "Bits de dados" @@ -2035,7 +2281,10 @@ msgid "Baud Rate of Passthrough" msgstr "Taxa de transmissão de passagem" msgid "Named Pipe (Server)" -msgstr "Pipe nomeado (servidor)" +msgstr "Pipe nomeado (Servidor)" + +msgid "Named Pipe (Client)" +msgstr "Pipe nomeado (Cliente)" msgid "Host Serial Passthrough" msgstr "Passagem da porta serial do host" @@ -2082,6 +2331,12 @@ msgstr "Clone IBM 8514/A (ISA)" msgid "Vendor" msgstr "Fabricante" +msgid "30 Hz (JMP2 = 1)" +msgstr "30 Hz (JMP2 = 1)" + +msgid "60 Hz (JMP2 = 2)" +msgstr "60 Hz (JMP2 = 2)" + msgid "Generic PC/XT Memory Expansion" msgstr "Expansão de memória genérica PC/XT" @@ -2092,7 +2347,7 @@ msgid "Unable to find Dot-Matrix fonts" msgstr "Não foi possível localizar os fontes matriciais de pontos" msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for the emulation of the Generic ESC/P Dot-Matrix Printer." -msgstr "As fontes TrueType no diretório \"roms/printer/fonts\" são necessárias para a emulação da impressora matricial de pontos ESC/P genérica." +msgstr "As fontes TrueType no diretório \"roms/printer/fonts\" são necessárias para a emulação da impressora matricial ESC/P genérica." msgid "Inhibit multimedia keys" msgstr "Inibir teclas multimídia" @@ -2106,9 +2361,6 @@ msgstr "Perguntar antes de reinicialização completa" msgid "Ask for confirmation before quitting" msgstr "Perguntar antes de sair" -msgid "Display hotkey message when entering full-screen mode" -msgstr "Mostrar mensagem de atalho quando entrar em tela cheia" - msgid "Options" msgstr "Opções" @@ -2178,6 +2430,12 @@ msgstr "Vincular tecla" msgid "Enter key combo:" msgstr "Pressione combinação de teclas:" +msgid "Bind conflict" +msgstr "Conflito de vínculo" + +msgid "This key combo is already in use." +msgstr "Esta combinação de teclas já está em uso." + msgid "Send Control+Alt+Del" msgstr "Enviar Control+Alt+Del" @@ -2198,3 +2456,27 @@ msgstr "Alternar pausa" msgid "Toggle mute" msgstr "Alternar mudo" + +msgid "Text files" +msgstr "Arquivos de texto" + +msgid "ROM files" +msgstr "Arquivos de ROM" + +msgid "SoundFont files" +msgstr "Arquivos SoundFont" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index ba1c6976c..edf66545a 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Pausa" -msgid "E&xit..." -msgstr "&Sair..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "&Sair" msgid "&View" msgstr "&Ver" @@ -60,7 +63,7 @@ msgstr "Open&GL (Núcleo 3.0)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "&Especificar dimensões..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "Método de filtragem" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "&Tipo de ecrã VGA" msgid "RGB &Color" msgstr "&Cores RGB" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "&RGB em escala de cinzentos" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "Monitor âmb&ar" @@ -384,6 +393,15 @@ msgstr "Ativada (UTC)" msgid "Dynamic Recompiler" msgstr "Recompilador dinâmico" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Vídeo:" @@ -399,6 +417,9 @@ msgstr "Gráficos IBM 8514/A" msgid "XGA Graphics" msgstr "Gráficos XGA" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Rato:" @@ -498,18 +519,21 @@ msgstr "Porta paralela 3" msgid "Parallel port 4" msgstr "Porta paralela 4" -msgid "HD Controller:" -msgstr "Controlador HD:" - msgid "FD Controller:" msgstr "Controlador FD:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "Controlador IDE terciário" msgid "Quaternary IDE Controller" msgstr "Controlador IDE quaternário" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Cassete" msgid "Hard disks:" msgstr "Discos rígidos:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "&Novo..." @@ -588,8 +615,8 @@ msgstr "Unidades CD-ROM:" msgid "MO drives:" msgstr "Unidades magneto-ópticas:" -msgid "ZIP drives:" -msgstr "Unidades ZIP:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA RTC:" msgid "ISA Memory Expansion" msgstr "Expansão de memória ISA" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Placa 1:" @@ -612,6 +642,15 @@ msgstr "Placa 3:" msgid "Card 4:" msgstr "Placa 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "Dispositivo ISABugger" @@ -630,17 +669,20 @@ msgstr "Erro fatal" msgid " - PAUSED" msgstr " - EM PAUSA" -msgid "Press %s to return to windowed mode." -msgstr "Pressione %s para voltar ao modo de janela." - msgid "Speed" msgstr "Velocidade" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "Imagens ZIP" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "O 86Box não conseguiu encontrar nenhuma imagem ROM utilizável.\n\nPor favor, vá a href=\"https://github.com/86Box/roms/releases/latest\">descarregue um pacote ROM e instale-o na pasta \"roms\"." @@ -717,11 +759,11 @@ msgstr "Outros dispositivos" msgid "Click to capture mouse" msgstr "Clique para capturar o rato" -msgid "Press %s to release mouse" -msgstr "Pressione %s para soltar o rato" +msgid "Press %1 to release mouse" +msgstr "Pressione %1 para soltar o rato" -msgid "Press %s or middle button to release mouse" -msgstr "Pressione %s ou tecla média para soltar o rato" +msgid "Press %1 or middle button to release mouse" +msgstr "Pressione %1 ou tecla média para soltar o rato" msgid "Bus" msgstr "Barramento" @@ -780,12 +822,39 @@ msgstr "Joystick de 4 eixos, 4 botões" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Nenhum" @@ -795,6 +864,9 @@ msgstr "%1 MB (CCS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Disquete %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Disquete %1 (%2): %3" + msgid "Advanced sector images" msgstr "Imagens avançadas de sector" @@ -816,6 +888,9 @@ msgstr "Não foi possível inicializar o GhostPCL" msgid "MO %1 (%2): %3" msgstr "Magneto-óptico %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&Magneto-óptico %1 (%2): %3" + msgid "MO images" msgstr "Imagens magneto-ópticas" @@ -864,9 +939,6 @@ msgstr "%1 é requerido para a conversão automática de ficheiros PostScript pa msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 é requerido para a conversão automática de ficheiros PCL para ficheiros PDF.\n\nQualquer documento enviado para a impressora PCL genérica será gravado como um ficheiro Printer Command Language (.pcl)." -msgid "Entering fullscreen mode" -msgstr "A entrar no modo de tela cheia" - msgid "Don't show this message again" msgstr "Não mostrar mais esta mensagem" @@ -903,12 +975,18 @@ msgstr "Continuar" msgid "Cassette: %1" msgstr "Cassete: %1" +msgid "C&assette: %1" +msgstr "C&assete: %1" + msgid "Cassette images" msgstr "Imagens de cassete" msgid "Cartridge %1: %2" msgstr "Cartucho %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Car&tucho %1: %2" + msgid "Cartridge images" msgstr "Imagens de cartucho" @@ -930,6 +1008,9 @@ msgstr "Reinicialização completa" msgid "ACPI shutdown" msgstr "Encerramento ACPI" +msgid "ACP&I shutdown" +msgstr "Encerramento ACP&I" + msgid "Hard disk (%1)" msgstr "Disco rígido (%1)" @@ -1077,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 KB" @@ -1215,41 +1299,41 @@ msgstr "Dispositivos MCA" msgid "List of MCA devices:" msgstr "Lista de dispositivos MCA:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Ferramenta para tablet" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "Acerca do Qt" +msgid "About &Qt" +msgstr "Acerca do &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "Dispositivos MCA..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Mostrar monitores não primários" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Abrir a pasta de capturas de ecrã..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Aplicar o modo de estiramento na tela cheia quando maximizado" -msgid "Cursor/Puck" -msgstr "Cursor/Puck" +msgid "&Cursor/Puck" +msgstr "&Cursor/Puck" -msgid "Pen" -msgstr "Caneta" +msgid "&Pen" +msgstr "C&aneta" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Unidade de CD/DVD do anfitrião (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Unidade de CD/DVD do anfitrião (%1:)" msgid "&Connected" msgstr "&Conectado" -msgid "Clear image history" -msgstr "Limpar o histórico de imagens" +msgid "Clear image &history" +msgstr "Limpar o histórico de imagens(&H)" msgid "Create..." msgstr "Criar..." @@ -1266,6 +1350,9 @@ msgstr "Condutor nulo" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "Comportamento de renderização" @@ -1305,8 +1392,8 @@ msgstr "Erro ao inicializar o OpenGL" msgid "\nFalling back to software rendering." msgstr "\nRecuando para a renderização de software." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Ao selecionar imagens multimédia (CD-ROM, disquete, etc.) a caixa de diálogo de abertura irá começar no mesmo diretório que o ficheiro de configuração da 86Box. Esta configuração provavelmente só fará diferença no macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Ao selecionar imagens multimédia (CD-ROM, disquete, etc.) a caixa de diálogo de abertura irá começar no mesmo diretório que o ficheiro de configuração da 86Box. Esta configuração provavelmente só fará diferença no macOS.

" msgid "This machine might have been moved or copied." msgstr "Esta máquina pode ter sido deslocada ou copiada." @@ -1371,9 +1458,27 @@ msgstr "Passagem da porta de série 3" msgid "Serial port passthrough 4" msgstr "Passagem da porta de série 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Opções do renderizador..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Rato Logitech/Microsoft Bus" @@ -1383,18 +1488,30 @@ msgstr "Rato Microsoft Bus (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Sistemas de ratos Rato de série" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Rato de série Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Rato de série Logitech" msgid "PS/2 Mouse" msgstr "Rato PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (série)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Modem padrão compatível com Hayes" @@ -1419,12 +1536,54 @@ msgstr "Sistema MIDI" msgid "MIDI Input Device" msgstr "Dispositivo de entrada MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "Endereço da BIOS" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "Ativar as escritas de ROM de extensão da BIOS" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Endereço" @@ -1434,6 +1593,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "Revisão da BIOS" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Traduzir 26 -> 17" @@ -1449,6 +1620,18 @@ msgstr "Inverter cores" msgid "BIOS size" msgstr "Tamanho da BIOS" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "Mapear C0000-C7FFF como UMB" @@ -1524,6 +1707,9 @@ msgstr "Nível de reverberação" msgid "Interpolation Method" msgstr "Método de interpolação" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Ganho da saída do reverb" @@ -1611,6 +1797,12 @@ msgstr "DMA baixo" msgid "Enable Game port" msgstr "Ativar a porta de jogos" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Módulo Surround" @@ -1623,6 +1815,9 @@ msgstr "Ativar a interrupção do CODEC na configuração do CODEC (necessário msgid "SB Address" msgstr "Endereço SB" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "WSS IRQ" @@ -1707,9 +1902,15 @@ msgstr "Tipo de RAMDAC" msgid "Blend" msgstr "Mistura" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Filtragem bilinear" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Dithering" @@ -1752,6 +1953,33 @@ msgstr "Velocidade de transferência" msgid "EMS mode" msgstr "Modo EMS" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Endereço para > 2 MB" @@ -1770,11 +1998,11 @@ msgstr "Sempre à velocidade selecionada" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Definição da BIOS + Teclas de atalho (desligadas durante o POST)" -msgid "64 kB starting from F0000" -msgstr "64 kB a partir de F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB a partir de F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB a partir de E0000 (endereço MSB invertido, os últimos 64KB primeiro)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB a partir de E0000 (endereço MSB invertido, os últimos 64 KB primeiro)" msgid "Sine" msgstr "Sinusoidal" @@ -1908,6 +2136,15 @@ msgstr "interpolação sRGB" msgid "Linear interpolation" msgstr "Interpolação linear" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2178,9 @@ msgstr "Âmbar" msgid "Gray" msgstr "Cinzento" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Cor" @@ -1956,6 +2196,12 @@ msgstr "Outros idiomas" msgid "Bochs latest" msgstr "Bochs mais recente" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Monocromático não entrelaçado" @@ -2037,6 +2283,9 @@ msgstr "Taxa de transmissão de passagem" msgid "Named Pipe (Server)" msgstr "Tubo nomeado (servidor)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "Passagem da porta de série do anfitrião" @@ -2082,6 +2331,12 @@ msgstr "Clone IBM 8514/A (ISA)" msgid "Vendor" msgstr "Fabricante" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "Expansão de memória genérica PC/XT" @@ -2106,9 +2361,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2156,3 +2408,87 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Controlador HD:" + +#~ msgid "ZIP drives:" +#~ msgstr "Unidades ZIP:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "Imagens ZIP" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index e88f4f0fc..6f4a3de0a 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Пауза" -msgid "E&xit..." -msgstr "&Выход..." +msgid "Re&sume" +msgstr "В&озобновить" + +msgid "E&xit" +msgstr "&Выход" msgid "&View" msgstr "&Вид" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "&Указать размеры главного окна..." msgid "F&orce 4:3 display ratio" @@ -99,8 +102,8 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" -msgstr "Метод фильтрации" +msgid "Fi<er method" +msgstr "Метод &фильтрации" msgid "&Nearest" msgstr "&Ближайший" @@ -144,9 +147,15 @@ msgstr "&Тип экрана VGA" msgid "RGB &Color" msgstr "RGB &цветной" +msgid "RGB (no brown)" +msgstr "RGB (без коричневого)" + msgid "&RGB Grayscale" msgstr "&RGB монохромный" +msgid "Generic RGBI color monitor" +msgstr "Стандартный цветной монитор RGBI" + msgid "&Amber monitor" msgstr "&Янтарный оттенок" @@ -208,7 +217,7 @@ msgid "End trace" msgstr "Завершить трассировку" msgid "&Help" -msgstr "&Помощь" +msgstr "&Справка" msgid "&Documentation..." msgstr "&Документация..." @@ -384,6 +393,15 @@ msgstr "Включено (UTC)" msgid "Dynamic Recompiler" msgstr "Динамический рекомпилятор" +msgid "CPU frame size" +msgstr "Размер кадра ЦП" + +msgid "Larger frames (less smooth)" +msgstr "Большие кадры (менее плавные)" + +msgid "Smaller frames (smoother)" +msgstr "Меньшие кадры (более плавные)" + msgid "Video:" msgstr "Видеокарта 1:" @@ -399,6 +417,9 @@ msgstr "Ускоритель IBM 8514/A" msgid "XGA Graphics" msgstr "Ускоритель XGA" +msgid "Keyboard:" +msgstr "Клавиатура:" + msgid "Mouse:" msgstr "Мышь:" @@ -498,18 +519,21 @@ msgstr "Параллельный порт LPT3" msgid "Parallel port 4" msgstr "Параллельный порт LPT4" -msgid "HD Controller:" -msgstr "Контроллер HD:" - msgid "FD Controller:" msgstr "Контроллер FD:" +msgid "CD-ROM Controller:" +msgstr "Контроллер CD-ROM:" + msgid "Tertiary IDE Controller" msgstr "Третичный IDE контроллер" msgid "Quaternary IDE Controller" msgstr "Четвертичный IDE контроллер" +msgid "Hard disk" +msgstr "Жёсткий диск" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Кассета" msgid "Hard disks:" msgstr "Жёсткие диски:" +msgid "Firmware Version" +msgstr "Версия прошивки" + msgid "&New..." msgstr "&Создать..." @@ -588,8 +615,8 @@ msgstr "Дисководы CD-ROM:" msgid "MO drives:" msgstr "Магнитооптические дисководы:" -msgid "ZIP drives:" -msgstr "ZIP дисководы:" +msgid "Removable disk drives:" +msgstr "Дисководы съёмных дисков:" msgid "ZIP 250" msgstr "ZIP 250" @@ -598,7 +625,10 @@ msgid "ISA RTC:" msgstr "ISA RTC:" msgid "ISA Memory Expansion" -msgstr "Карта расширения памяти ISA" +msgstr "Карты расширения памяти ISA" + +msgid "ISA ROM Cards" +msgstr "Карты ПЗУ ISA" msgid "Card 1:" msgstr "Карта 1:" @@ -612,6 +642,15 @@ msgstr "Карта 3:" msgid "Card 4:" msgstr "Карта 4:" +msgid "Generic ISA ROM Board" +msgstr "Стандартная плата ПЗУ ISA" + +msgid "Generic Dual ISA ROM Board" +msgstr "Стандартная плата на 2 ПЗУ ISA" + +msgid "Generic Quad ISA ROM Board" +msgstr "Стандартная плата на 4 ПЗУ ISA" + msgid "ISABugger device" msgstr "Устройство ISABugger" @@ -630,17 +669,20 @@ msgstr "Неустранимая ошибка" msgid " - PAUSED" msgstr " - ПАУЗА" -msgid "Press %s to return to windowed mode." -msgstr "Нажмите %s для возврата в оконный режим." - msgid "Speed" msgstr "Скорость" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "Съёмный диск %1 (%2): %3" -msgid "ZIP images" -msgstr "Образы ZIP" +msgid "&Removable disk %1 (%2): %3" +msgstr "&Съёмный диск %1 (%2): %3" + +msgid "Removable disk images" +msgstr "Образы съёмных дисков" + +msgid "Image %1" +msgstr "Образ %1" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "86Box не смог найти ни одного подходящего для использования файла с ПЗУ.\n\nПожалуйста скачайте набор ПЗУ и извлеките его в каталог \"roms\"." @@ -717,11 +759,11 @@ msgstr "Другая периферия" msgid "Click to capture mouse" msgstr "Щёлкните мышью для захвата курсора" -msgid "Press %s to release mouse" -msgstr "Нажмите %s, чтобы освободить курсор" +msgid "Press %1 to release mouse" +msgstr "Нажмите %1, чтобы освободить курсор" -msgid "Press %s or middle button to release mouse" -msgstr "Нажмите %s или среднюю кнопку мыши, чтобы освободить курсор" +msgid "Press %1 or middle button to release mouse" +msgstr "Нажмите %1 или среднюю кнопку мыши, чтобы освободить курсор" msgid "Bus" msgstr "Шина" @@ -780,12 +822,39 @@ msgstr "4-осевой, 4-кнопочный джойстик" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Педали" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Система управления полётом Thrustmaster" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Система управления рулем" + +msgid "2-button gamepad(s)" +msgstr "2-кнопочный геймпад" + +msgid "2-button flight yoke" +msgstr "2-кнопочный flight yoke" + +msgid "4-button gamepad" +msgstr "4-кнопочный геймпад" + +msgid "4-button flight yoke" +msgstr "4-кнопочный flight yoke" + +msgid "2-button flight yoke with throttle" +msgstr "2-кнопочный flight yoke с дросселем" + +msgid "4-button flight yoke with throttle" +msgstr "4-кнопочный flight yoke с дросселем" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "Руль Win95 (3-осевой, 4-кнопочный)" + msgid "None" msgstr "Нет" @@ -795,6 +864,9 @@ msgstr "%1 МБ (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Дисковод %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Дисковод %1 (%2): %3" + msgid "Advanced sector images" msgstr "Расширенные образы секторов" @@ -816,6 +888,9 @@ msgstr "Невозможно инициализировать GhostPCL" msgid "MO %1 (%2): %3" msgstr "Магнитооптический %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&Магнитооптический %1 (%2): %3" + msgid "MO images" msgstr "Образы магнитооптических дисков" @@ -864,9 +939,6 @@ msgstr "Для автоматического преобразования фа msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "Для автоматического преобразования файлов PCL в PDF требуется %1.\n\nВсе документы, отправленные на стандартный принтер PCL, будут сохранены в виде файлов Printer Command Language (.pcl)." -msgid "Entering fullscreen mode" -msgstr "Вход в полноэкранный режим" - msgid "Don't show this message again" msgstr "Больше не показывать это сообщение" @@ -903,12 +975,18 @@ msgstr "Продолжить" msgid "Cassette: %1" msgstr "Кассета: %1" +msgid "C&assette: %1" +msgstr "&Кассета: %1" + msgid "Cassette images" msgstr "Образы кассет" msgid "Cartridge %1: %2" msgstr "Картридж %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Кар&тридж %1: %2" + msgid "Cartridge images" msgstr "Образы картриджей" @@ -930,6 +1008,9 @@ msgstr "Холодная перезагрузка" msgid "ACPI shutdown" msgstr "Сигнал завершения ACPI" +msgid "ACP&I shutdown" +msgstr "Сигнал завершения ACP&I" + msgid "Hard disk (%1)" msgstr "Жёсткий диск (%1)" @@ -1077,6 +1158,9 @@ msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" msgstr "CD-ROM %1 (%2): %3" +msgid "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2): %3" + msgid "160 KB" msgstr "160 КБ" @@ -1215,47 +1299,47 @@ msgstr "Устройства MCA" msgid "List of MCA devices:" msgstr "Список устройств MCA:" -msgid "Tablet tool" -msgstr "Планшетный инструмент" +msgid "&Tablet tool" +msgstr "Планшетный &инструмент" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "О Qt" +msgid "About &Qt" +msgstr "О &Qt" -msgid "MCA devices..." -msgstr "Устройства MCA..." +msgid "&MCA devices..." +msgstr "Устройства &MCA..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "&Показывать неосновные мониторы" -msgid "Open screenshots folder..." -msgstr "Открыть папку скриншотов..." +msgid "Open screenshots &folder..." +msgstr "Открыть папку &скриншотов..." -msgid "Apply fullscreen stretch mode when maximized" -msgstr "Применить полноэкранный режим растяжения при разворачивании окна" +msgid "Appl&y fullscreen stretch mode when maximized" +msgstr "Применить полно&экранный режим растяжения при разворачивании окна" -msgid "Cursor/Puck" -msgstr "Курсор/шайба" +msgid "&Cursor/Puck" +msgstr "&Курсор/шайба" -msgid "Pen" -msgstr "Ручка" +msgid "&Pen" +msgstr "&Ручка" -msgid "Host CD/DVD Drive (%1:)" -msgstr "CD/DVD-привод хоста (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "CD/DVD Привод &хоста (%1:)" msgid "&Connected" msgstr "&Кабель подключен" -msgid "Clear image history" -msgstr "Очистить историю образов" +msgid "Clear image &history" +msgstr "Очистить &историю образов" msgid "Create..." msgstr "Создать..." msgid "Host CD/DVD Drive (%1)" -msgstr "CD/DVD-привод хоста (%1)" +msgstr "CD/DVD Привод хоста (%1)" msgid "Unknown Bus" msgstr "Неизвестная шина" @@ -1266,6 +1350,9 @@ msgstr "Нулевой драйвер" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" +msgid "&NIC %1 (%2) %3" +msgstr "&NIC %1 (%2) %3" + msgid "Render behavior" msgstr "Режим рендеринга" @@ -1305,8 +1392,8 @@ msgstr "Ошибка инициализации OpenGL" msgid "\nFalling back to software rendering." msgstr "\nПереключение на программный рендеринг." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>При выборе образов носителей (CD-ROM, дискет и т. д.) диалог открытия будет запускаться в том же каталоге, что и файл конфигурации 86Box. Эта настройка, скорее всего, будет иметь значение только на macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

При выборе образов носителей (CD-ROM, дискет и т. д.) диалог открытия будет запускаться в том же каталоге, что и файл конфигурации 86Box. Эта настройка, скорее всего, будет иметь значение только на macOS.

" msgid "This machine might have been moved or copied." msgstr "Возможно, эта машина была перемещена или скопирована." @@ -1371,8 +1458,26 @@ msgstr "Сквозной последовательный порт COM3" msgid "Serial port passthrough 4" msgstr "Сквозной последовательный порт COM4" -msgid "Renderer options..." -msgstr "Параметры рендеринга..." +msgid "Renderer &options..." +msgstr "Параметры &рендеринга..." + +msgid "PC/XT Keyboard" +msgstr "Клавиатура PC/XT" + +msgid "AT Keyboard" +msgstr "Клавиатура AT" + +msgid "AX Keyboard" +msgstr "Клавиатура AX" + +msgid "PS/2 Keyboard" +msgstr "Клавиатура PS/2" + +msgid "PS/55 Keyboard" +msgstr "Клавиатура PS/55" + +msgid "Keys" +msgstr "Клавиши" msgid "Logitech/Microsoft Bus Mouse" msgstr "Bus-мышь Logitech/Microsoft" @@ -1383,18 +1488,30 @@ msgstr "Bus-мышь Microsoft (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "COM-мышь Mouse Systems" +msgid "Mouse Systems Bus Mouse" +msgstr "Bus-мышь Mouse Systems" + msgid "Microsoft Serial Mouse" msgstr "COM-мышь Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "COM-мышь Microsoft BallPoint" + msgid "Logitech Serial Mouse" msgstr "COM-мышь Logitech" msgid "PS/2 Mouse" msgstr "Мышь PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "Мышь PS/2 QuickPort" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (последовательный)" +msgid "Default Baud rate" +msgstr "Скорость передачи данных по умолчанию" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Стандартный Hayes-совместимый модем" @@ -1419,21 +1536,81 @@ msgstr "Системный MIDI" msgid "MIDI Input Device" msgstr "Устройство ввода MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "Файл BIOS" + +msgid "BIOS file (ROM #1)" +msgstr "Файл BIOS (ПЗУ #1)" + +msgid "BIOS file (ROM #2)" +msgstr "Файл BIOS (ПЗУ #2)" + +msgid "BIOS file (ROM #3)" +msgstr "Файл BIOS (ПЗУ #3)" + +msgid "BIOS file (ROM #4)" +msgstr "Файл BIOS (ПЗУ #4)" + +msgid "BIOS address" msgstr "Адрес BIOS" +msgid "BIOS address (ROM #1)" +msgstr "Адрес BIOS (ПЗУ #1)" + +msgid "BIOS address (ROM #2)" +msgstr "Адрес BIOS (ПЗУ #2)" + +msgid "BIOS address (ROM #3)" +msgstr "Адрес BIOS (ПЗУ #3)" + +msgid "BIOS address (ROM #4)" +msgstr "Адрес BIOS (ПЗУ #4)" + msgid "Enable BIOS extension ROM Writes" msgstr "Разрешить запись в ПЗУ расширения BIOS" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "Разрешить запись в ПЗУ расширения BIOS (ПЗУ #1)" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "Разрешить запись в ПЗУ расширения BIOS (ПЗУ #2)" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "Разрешить запись в ПЗУ расширения BIOS (ПЗУ #3)" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "Разрешить запись в ПЗУ расширения BIOS (ПЗУ #4)" + +msgid "Linear framebuffer base" +msgstr "Линейная база кадрового буфера" + msgid "Address" msgstr "Адрес" msgid "IRQ" msgstr "IRQ" +msgid "Serial port IRQ" +msgstr "IRQ последовательного порта" + +msgid "Parallel port IRQ" +msgstr "IRQ параллельного порта" + msgid "BIOS Revision" msgstr "Версия BIOS" +msgid "BIOS Version" +msgstr "Версия BIOS" + +msgid "BIOS Language" +msgstr "Язык BIOS" + +msgid "IBM 5161 Expansion Unit" +msgstr "Блок расширения IBM 5161" + +msgid "IBM Cassette Basic" +msgstr "Кассетный бейсик IBM" + msgid "Translate 26 -> 17" msgstr "Переводить 26 -> 17" @@ -1449,6 +1626,18 @@ msgstr "Инвертировать цвета" msgid "BIOS size" msgstr "Размер BIOS" +msgid "BIOS size (ROM #1)" +msgstr "Размер BIOS (ПЗУ #1)" + +msgid "BIOS size (ROM #2)" +msgstr "Размер BIOS (ПЗУ #2)" + +msgid "BIOS size (ROM #3)" +msgstr "Размер BIOS (ПЗУ #3)" + +msgid "BIOS size (ROM #4)" +msgstr "Размер BIOS (ПЗУ #4)" + msgid "Map C0000-C7FFF as UMB" msgstr "Отображение C0000-C7FFF в качестве UMB" @@ -1524,6 +1713,9 @@ msgstr "Уровень реверберации" msgid "Interpolation Method" msgstr "Метод интерполяции" +msgid "Dynamic Sample Loading" +msgstr "Динамическая загрузка сэмплов" + msgid "Reverb Output Gain" msgstr "Усиление выходного сигнала ревербератора" @@ -1611,8 +1803,14 @@ msgstr "Низкий DMA" msgid "Enable Game port" msgstr "Включить игровой порт" +msgid "SID Model" +msgstr "Модель SID" + +msgid "SID Filter Strength" +msgstr "Сила фильтра SID" + msgid "Surround module" -msgstr "Модуль объемного звучания" +msgstr "Модуль объёмного звучания" msgid "CODEC" msgstr "Кодек" @@ -1623,6 +1821,12 @@ msgstr "Поднимать прерывание кодека при настро msgid "SB Address" msgstr "Адрес SB" +msgid "Adlib Address" +msgstr "Адрес AdLib" + +msgid "Use EEPROM setting" +msgstr "Использовать настройку EEPROM" + msgid "WSS IRQ" msgstr "IRQ WSS" @@ -1707,14 +1911,20 @@ msgstr "Тип RAMDAC" msgid "Blend" msgstr "Смесь" +msgid "Font" +msgstr "Шрифт" + msgid "Bilinear filtering" msgstr "Билинейная фильтрация" +msgid "Video chroma-keying" +msgstr "Видео хромакеинг" + msgid "Dithering" msgstr "Дизеринг" msgid "Enable NMI for CGA emulation" -msgstr "Включение NMI для эмуляции CGA" +msgstr "Включить NMI для эмуляции CGA" msgid "Voodoo type" msgstr "Тип Voodoo" @@ -1752,6 +1962,33 @@ msgstr "Скорость передачи данных" msgid "EMS mode" msgstr "Режим EMS" +msgid "EMS Address" +msgstr "Адрес EMS" + +msgid "EMS 1 Address" +msgstr "Адрес EMS 1" + +msgid "EMS 2 Address" +msgstr "Адрес EMS 2" + +msgid "EMS Memory Size" +msgstr "Размер памяти EMS" + +msgid "EMS 1 Memory Size" +msgstr "Размер памяти EMS 1" + +msgid "EMS 2 Memory Size" +msgstr "Размер памяти EMS 2" + +msgid "Enable EMS" +msgstr "Включить EMS" + +msgid "Enable EMS 1" +msgstr "Включить EMS 1" + +msgid "Enable EMS 2" +msgstr "Включить EMS 2" + msgid "Address for > 2 MB" msgstr "Адрес для > 2 МБ" @@ -1770,11 +2007,11 @@ msgstr "Всегда на выбранной скорости" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Настройка BIOS + горячие клавиши (отключается во время POST)" -msgid "64 kB starting from F0000" -msgstr "64 кБ, начиная с F0000" +msgid "64 KB starting from F0000" +msgstr "64 КБ, начиная с F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 кБ, начиная с E0000 (адрес MSB инвертирован, сначала последние 64 КБ)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 КБ, начиная с E0000 (адрес MSB инвертирован, сначала последние 64 КБ)" msgid "Sine" msgstr "Синусоидальная" @@ -1798,7 +2035,7 @@ msgid "45 Hz (JMP2 not populated)" msgstr "45 Гц (без джампера на JMP2)" msgid "Two" -msgstr "Два" +msgstr "Две" msgid "Three" msgstr "Три" @@ -1908,6 +2145,15 @@ msgstr "Интерполяция sRGB" msgid "Linear interpolation" msgstr "Линейная интерполяция" +msgid "Has secondary 8x8 character set" +msgstr "Вторичный набор символов 8x8" + +msgid "Has Quadcolor II daughter board" +msgstr "Дочерняя плата Quadcolor II" + +msgid "Alternate monochrome contrast" +msgstr "Альтернативный монохромный контраст" + msgid "128 KB" msgstr "128 КБ" @@ -1941,6 +2187,9 @@ msgstr "Янтарный" msgid "Gray" msgstr "Серый" +msgid "Grayscale" +msgstr "Монохромный" + msgid "Color" msgstr "Цветной" @@ -1956,6 +2205,12 @@ msgstr "Другие языки" msgid "Bochs latest" msgstr "Bochs последний" +msgid "Apply overscan deltas" +msgstr "Применить дельты вылетов развёртки" + +msgid "Mono Interlaced" +msgstr "Монохромный с чересстрочной развёрткой" + msgid "Mono Non-Interlaced" msgstr "Монохромный без чересстрочной развёртки" @@ -2037,6 +2292,9 @@ msgstr "Скорость передачи данных через канал" msgid "Named Pipe (Server)" msgstr "Именованный пайп (Сервер)" +msgid "Named Pipe (Client)" +msgstr "Именованный пайп (Клиент)" + msgid "Host Serial Passthrough" msgstr "Последовательный порт хоста" @@ -2101,7 +2359,7 @@ msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for t msgstr "Шрифты TrueType в каталоге \"roms/printer/fonts\" необходимы для эмуляции стандартного матричного принтера ESC/P." msgid "Inhibit multimedia keys" -msgstr "Перехватывать мультимедиа-клавиши" +msgstr "Перехватывать мультимедийные клавиши" msgid "Ask for confirmation before saving settings" msgstr "Запрашивать подтверждение перед сохранением настроек" @@ -2112,9 +2370,6 @@ msgstr "Запрашивать подтверждение перед холод msgid "Ask for confirmation before quitting" msgstr "Запрашивать подтверждение перед выходом" -msgid "Display hotkey message when entering full-screen mode" -msgstr "Показывать сообщение о горячей клавише при входе в полноэкранный режим" - msgid "Options" msgstr "Параметры" @@ -2184,6 +2439,12 @@ msgstr "Привязать клавишу" msgid "Enter key combo:" msgstr "Введите комбинацию клавиш:" +msgid "Bind conflict" +msgstr "Конфликт привязки" + +msgid "This key combo is already in use." +msgstr "Эта комбинация клавиш уже используется." + msgid "Send Control+Alt+Del" msgstr "Отправить Control+Alt+Del" @@ -2191,7 +2452,7 @@ msgid "Send Control+Alt+Escape" msgstr "Отправить Control+Alt+Escape" msgid "Toggle fullscreen" -msgstr "Переключить на полноэкранный режим" +msgstr "Переключить полноэкранный режим" msgid "Screenshot" msgstr "Скриншот" @@ -2203,4 +2464,40 @@ msgid "Toggle pause" msgstr "Переключить паузу" msgid "Toggle mute" -msgstr "Переключить беззвучный режим" \ No newline at end of file +msgstr "Переключить беззвучный режим" + +msgid "Text files" +msgstr "Текстовые файлы" + +msgid "ROM files" +msgstr "Файлы ПЗУ" + +msgid "SoundFont files" +msgstr "Файлы SoundFont" + +msgid "Local Switch" +msgstr "Локальный коммутатор" + +msgid "Remote Switch" +msgstr "Удалённый коммутатор" + +msgid "Switch:" +msgstr "Номер коммутатора:" + +msgid "Hub Mode" +msgstr "Режим концентратора" + +msgid "Hostname:" +msgstr "Имя хоста:" + +#~ msgid "HD Controller:" +#~ msgstr "Контроллер HD:" + +#~ msgid "ZIP drives:" +#~ msgstr "ZIP дисководы:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "Образы ZIP" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index f11f335d4..fd3a4ed21 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -27,7 +27,10 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "P&ozastaviť" -msgid "E&xit..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" msgstr "&Ukončiť" msgid "&View" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "&Zadať veľkosť..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "Spôsob &filtrovania" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "&Typ monitora VGA" msgid "RGB &Color" msgstr "RGB &farebný" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "&Odtiene sivej" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "&Jantárová obrazovka" @@ -384,6 +393,15 @@ msgstr "Zapnutá (UTC)" msgid "Dynamic Recompiler" msgstr "Dynamický prekladač" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Grafika:" @@ -399,6 +417,9 @@ msgstr "Grafika IBM 8514/A" msgid "XGA Graphics" msgstr "Grafika XGA" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Myš:" @@ -498,18 +519,21 @@ 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 "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "Tretí radič IDE" msgid "Quaternary IDE Controller" msgstr "Štvrtý radič IDE" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Kazeta" msgid "Hard disks:" msgstr "Pevné disky:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "&Nový..." @@ -588,8 +615,8 @@ msgstr "Mechaniky CD-ROM:" msgid "MO drives:" msgstr "Magnetooptické mechaniky:" -msgid "ZIP drives:" -msgstr "Mechaniky ZIP:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA hodiny:" msgid "ISA Memory Expansion" msgstr "ISA rozšírenie pamäte" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Karta 1:" @@ -612,6 +642,15 @@ msgstr "Karta 3:" msgid "Card 4:" msgstr "Karta 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "Zariadenie ISABugger" @@ -630,17 +669,20 @@ msgstr "Kritická chyba" msgid " - PAUSED" msgstr " - POZASTAVENÝ" -msgid "Press %s to return to windowed mode." -msgstr "Stlačte %s pre návrat z režimu celej obrazovky." - msgid "Speed" msgstr "Rýchlosť" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "Obrazy ZIP diskov" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" 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\"." @@ -717,11 +759,11 @@ msgstr "Iné príslušenstvo" msgid "Click to capture mouse" msgstr "Kliknite pre zabráni myši" -msgid "Press %s to release mouse" -msgstr "Stlačte %s pre uvoľnenie myši" +msgid "Press %1 to release mouse" +msgstr "Stlačte %1 pre uvoľnenie myši" -msgid "Press %s or middle button to release mouse" -msgstr "Stlačte %s alebo prostredné tlačidlo na uvoľnenie myši" +msgid "Press %1 or middle button to release mouse" +msgstr "Stlačte %1 alebo prostredné tlačidlo na uvoľnenie myši" msgid "Bus" msgstr "Zbernica" @@ -780,12 +822,39 @@ msgstr "4-osový, 4-tlačidlový joystick" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Žiadne" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Disketová mechanika %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Disketová mechanika %1 (%2): %3" + msgid "Advanced sector images" msgstr "Rozšírené sektorové obrazy" @@ -816,6 +888,9 @@ msgstr "Nastala chyba pri inicializácii knižnice GhostPCL" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "Obrazy MO" @@ -852,7 +927,7 @@ msgstr "Emulátor starých počítačov\n\nAutori: Miran Grča (OBattler), Richa msgid "Hardware not available" msgstr "Hardvér nie je dostupný" -msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." msgstr "Uistite sa, že je nainštalovaný %1 a používate sieťové pripojenie s ním kompatibilné." msgid "Invalid configuration" @@ -861,12 +936,9 @@ msgstr "Neplatná konfigurácia" msgid "%1 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 "%1 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 "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Lnaugage (.pcl) files." +msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 je potrebná pre automatický prevod PCL dokumentov do PDF.\n\nAkékoľvek dokumenty vytlačené cez všeobecnú PCLovú tlačiareň budú uložené ako Printer Command Language (.pcl) 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" @@ -903,12 +975,18 @@ msgstr "Pokračovať" msgid "Cassette: %1" msgstr "Kazeta: %1" +msgid "C&assette: %1" +msgstr "K&azeta: %1" + msgid "Cassette images" msgstr "Kazetové nahrávky" msgid "Cartridge %1: %2" msgstr "Cartridge %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Car&tridge %1: %2" + msgid "Cartridge images" msgstr "Obrazy cartridge" @@ -930,6 +1008,9 @@ msgstr "Resetovať" msgid "ACPI shutdown" msgstr "Vypnúť cez rozhranie ACPI" +msgid "ACP&I shutdown" +msgstr "Vypnúť cez rozhranie ACP&I" + msgid "Hard disk (%1)" msgstr "Pevný disk (%1)" @@ -1215,40 +1296,40 @@ msgstr "Zariadenia MCA" msgid "List of MCA devices:" msgstr "Zoznam zariadení MCA:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Nástroj pre tablety" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "O Qt" +msgid "About &Qt" +msgstr "O &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "Zariadenia MCA..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Zobrazenie iných ako primárnych monitorov" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Otvorte priečinok so snímkami obrazovky..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Použitie režimu roztiahnutia na celú obrazovku pri maximalizácii" -msgid "Cursor/Puck" -msgstr "Kurzor/Puck" +msgid "&Cursor/Puck" +msgstr "&Kurzor/Puck" -msgid "Pen" -msgstr "Pero" +msgid "&Pen" +msgstr "&Pero" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Hostiteľská jednotka CD/DVD (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Hostiteľská jednotka CD/DVD (%1:)" msgid "&Connected" msgstr "" -msgid "Clear image history" +msgid "Clear image &history" msgstr "Vymazanie histórie obrázkov" msgid "Create..." @@ -1266,7 +1347,6 @@ msgstr "Nulový ovládač" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" - msgid "Render behavior" msgstr "Správanie pri vykresľovaní" @@ -1306,8 +1386,8 @@ msgstr "Chyba pri inicializácii OpenGL" msgid "\nFalling back to software rendering." msgstr "\nNávrat k softvérovému vykresľovaniu." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Pri výbere multimediálnych obrazov (CD-ROM, disketa atď.) sa dialógové okno otvorenia spustí v rovnakom adresári ako konfiguračný súbor 86Box. Toto nastavenie bude mať pravdepodobne význam len v systéme MacOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Pri výbere multimediálnych obrazov (CD-ROM, disketa atď.) sa dialógové okno otvorenia spustí v rovnakom adresári ako konfiguračný súbor 86Box. Toto nastavenie bude mať pravdepodobne význam len v systéme MacOS.

" msgid "This machine might have been moved or copied." msgstr "Tento stroj mohol byť premiestnený alebo skopírovaný." @@ -1372,9 +1452,27 @@ msgstr "Priechod sériového portu 3" msgid "Serial port passthrough 4" msgstr "Priechod cez sériový port 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Možnosti vykresľovača..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Zbernicová myš Logitech/Microsoft" @@ -1384,18 +1482,30 @@ msgstr "Zbernicová myš Microsoft (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Zbernicová myš Mouse Systems" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Sériová myš Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Sériová myš Logitech" msgid "PS/2 Mouse" msgstr "Myš PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (sériová)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Štandardný modem kompatibilný s Hayesom" @@ -1420,12 +1530,54 @@ msgstr "Systém MIDI" msgid "MIDI Input Device" msgstr "Vstupné zariadenie MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "Adresa BIOS" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "Povolenie zápisu do pamäte ROM s rozšírením BIOS" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Adresa" @@ -1435,6 +1587,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "Revízia systému BIOS" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Preložiť 26 -> 17" @@ -1450,6 +1614,18 @@ msgstr "Invertovanie farieb" msgid "BIOS size" msgstr "Veľkosť systému BIOS" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "Mapa C0000-C7FFF ako UMB" @@ -1525,6 +1701,9 @@ msgstr "Úroveň dozvuku" msgid "Interpolation Method" msgstr "Metóda interpolácie" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Zosilnenie výstupu dozvuku" @@ -1612,6 +1791,12 @@ msgstr "Nízka hodnota DMA" msgid "Enable Game port" msgstr "Povolenie herného portu" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Surround modul" @@ -1624,6 +1809,9 @@ msgstr "Zvýšenie prerušenia CODEC pri nastavení CODEC (potrebné v niektorý msgid "SB Address" msgstr "Adresa SB" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "WSS IRQ" @@ -1708,9 +1896,15 @@ msgstr "Typ RAMDAC" msgid "Blend" msgstr "Zmes" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Bilineárne filtrovanie" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Dithering" @@ -1753,6 +1947,33 @@ msgstr "Rýchlosť prenosu" msgid "EMS mode" msgstr "Režim EMS" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Adresa pre > 2 MB" @@ -1771,11 +1992,11 @@ msgstr "Vždy pri zvolenej rýchlosti" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Nastavenie BIOS + klávesové skratky (vypnuté počas POST)" -msgid "64 kB starting from F0000" -msgstr "64 kB od F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB od F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB od E0000 (adresa MSB invertovaná, najprv posledných 64 kB)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB od E0000 (adresa MSB invertovaná, najprv posledných 64 KB)" msgid "Sine" msgstr "Sinusový" @@ -1909,6 +2130,15 @@ msgstr "Interpolácia sRGB" msgid "Linear interpolation" msgstr "Lineárna interpolácia" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1942,6 +2172,9 @@ msgstr "Oranžový" msgid "Gray" msgstr "Šedý" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Farebný" @@ -1957,6 +2190,12 @@ msgstr "Ostatné jazyky" msgid "Bochs latest" msgstr "Bochs najnovšie" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Mono bez prelínania" @@ -2038,6 +2277,9 @@ msgstr "Prenosová rýchlosť priechodu" msgid "Named Pipe (Server)" msgstr "Pomenované potrubie (server)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "Priechod sériového portu hostiteľa" @@ -2083,6 +2325,12 @@ msgstr "Klon IBM 8514/A (ISA)" msgid "Vendor" msgstr "Výrobca" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "Všeobecné rozšírenie pamäte PC/XT" @@ -2107,9 +2355,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2157,3 +2402,87 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Radič disku:" + +#~ msgid "ZIP drives:" +#~ msgstr "Mechaniky ZIP:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "Obrazy ZIP diskov" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 7c2b36650..bda54793d 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Premor" -msgid "E&xit..." -msgstr "Iz&hod..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "Iz&hod" msgid "&View" msgstr "&Pogled" @@ -37,7 +40,7 @@ msgid "&Hide status bar" msgstr "&Skrij statusno vrstico" msgid "Hide &toolbar" -msgstr "Hide &toolbar" +msgstr "Skrij &orodno vrstico" msgid "&Resizeable window" msgstr "S&premenljiva velikost okna" @@ -55,19 +58,19 @@ msgid "Qt (&OpenGL)" msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" -msgstr "Open&GL (Jedro 3.0)" +msgstr "Open&GL (jedro 3.0)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "&Določi velikost..." msgid "F&orce 4:3 display ratio" -msgstr "&Vsili 4:3 razmerje zaslona" +msgstr "&Vsili razmerje zaslona 4:3" msgid "&Window scale factor" -msgstr "&Faktor velikosti okna" +msgstr "&Faktor povečave okna" msgid "&0.5x" msgstr "&0.5x" @@ -99,8 +102,8 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" -msgstr "&Metoda filtriranja" +msgid "Fi<er method" +msgstr "&Vrsta filtriranja" msgid "&Nearest" msgstr "&Najbližja" @@ -144,9 +147,15 @@ msgstr "&Vrsta zaslona VGA" msgid "RGB &Color" msgstr "&Barvni RGB" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "&Sivinski RGB" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "&Rumeni zaslon" @@ -241,7 +250,7 @@ msgid "E&ject" msgstr "I&zvrzi" msgid "&Image..." -msgstr "Slika..." +msgstr "S&lika..." msgid "E&xport to 86F..." msgstr "&Izvozi v 86F..." @@ -355,7 +364,7 @@ msgid "Speed:" msgstr "Hitrost:" msgid "Frequency:" -msgstr "Pogostost:" +msgstr "Takt:" msgid "FPU:" msgstr "Procesor plavajoče vejice:" @@ -367,7 +376,7 @@ msgid "MB" msgstr "MB" msgid "Memory:" -msgstr "Spomin:" +msgstr "Pomnilnik:" msgid "Time synchronization" msgstr "Sinhronizacija časa" @@ -384,6 +393,15 @@ msgstr "Omogočeno (UTC)" msgid "Dynamic Recompiler" msgstr "Dinamični prevajalnik" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Video:" @@ -399,6 +417,9 @@ msgstr "Grafika IBM 8514/A" msgid "XGA Graphics" msgstr "Grafika XGA" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Miška:" @@ -445,7 +466,7 @@ msgid "FM synth driver" msgstr "Gonilnik sintetizacije FM" msgid "Nuked (more accurate)" -msgstr "Nuked (točnejši)" +msgstr "Nuked (natančnejši)" msgid "YMFM (faster)" msgstr "YMFM (hitrejši)" @@ -487,22 +508,22 @@ msgid "Serial port 4" msgstr "Serijska vrata 4" msgid "Parallel port 1" -msgstr "Paralelna vrata 1" +msgstr "Vzporedna vrata 1" msgid "Parallel port 2" -msgstr "Paralelna vrata 2" +msgstr "Vzporedna vrata 2" msgid "Parallel port 3" -msgstr "Paralelna vrata 3" +msgstr "Vzporedna vrata 3" msgid "Parallel port 4" -msgstr "Paralelna vrata 4" - -msgid "HD Controller:" -msgstr "Krmilnik trdega diska:" +msgstr "Vzporedna vrata 4" msgid "FD Controller:" -msgstr "Krmilnik disketnika:" +msgstr "Disketni krmilnik:" + +msgid "CD-ROM Controller:" +msgstr "" msgid "Tertiary IDE Controller" msgstr "Terciarni krmilnik IDE" @@ -510,6 +531,9 @@ msgstr "Terciarni krmilnik IDE" msgid "Quaternary IDE Controller" msgstr "Kvartarni krmilnik IDE" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Kasetnik" msgid "Hard disks:" msgstr "Trdi diski:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "Nov..." @@ -550,7 +577,7 @@ msgid "ID:" msgstr "ID:" msgid "&Specify..." -msgstr "Določi..." +msgstr "&Določi..." msgid "Sectors:" msgstr "Sektorji:" @@ -588,18 +615,21 @@ msgstr "Pogoni CD-ROM:" msgid "MO drives:" msgstr "Magnetno-optični pogoni:" -msgid "ZIP drives:" -msgstr "Pogoni ZIP:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" msgid "ISA RTC:" -msgstr "Ura v realnem času ISA:" +msgstr "Ura realnega časa ISA:" msgid "ISA Memory Expansion" msgstr "Razširitev pomnilnika ISA" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Kartica 1:" @@ -612,6 +642,15 @@ msgstr "Kartica 3:" msgid "Card 4:" msgstr "Kartica 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "Naprava ISABugger" @@ -630,20 +669,23 @@ msgstr "Kritična napaka" msgid " - PAUSED" msgstr " - ZAUSTAVLJEN" -msgid "Press %s to return to windowed mode." -msgstr "Pritisnite %s za povratek iz celozaslonskega načina." - msgid "Speed" msgstr "Hitrost" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "ZIP slike" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box ni našel nobenih uporabnih ROM slik.\n\nProsim prenesite set ROM-ov in ga razširite v mapo \"roms\"." +msgstr "86Box ni našel nobenih uporabnih ROM slik.\n\nProsim prenesite komplet ROM-ov in ga razširite v mapo \"roms\"." msgid "(empty)" msgstr "(prazno)" @@ -717,11 +759,11 @@ msgstr "Druga periferija" msgid "Click to capture mouse" msgstr "Kliknite za zajem miške" -msgid "Press %s to release mouse" -msgstr "Pritisnite %s za izpust miške" +msgid "Press %1 to release mouse" +msgstr "Pritisnite %1 za izpust miške" -msgid "Press %s or middle button to release mouse" -msgstr "Pritisnite %s ali srednji gumb za izpust miške" +msgid "Press %1 or middle button to release mouse" +msgstr "Pritisnite %1 ali srednji gumb za izpust miške" msgid "Bus" msgstr "Vodilo" @@ -751,7 +793,7 @@ msgid "Type" msgstr "Vrsta" msgid "No PCap devices found" -msgstr "Nobena naprava PCap ni bila najdena" +msgstr "Najdena ni bila nobena naprava PCap" msgid "Invalid PCap device" msgstr "Neveljavna naprava PCap" @@ -780,12 +822,39 @@ msgstr "Igralna palica z 4 osmi, 4 gumbi" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Brez" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Disketa %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Disketa %1 (%2): %3" + msgid "Advanced sector images" msgstr "Napredne sektorske slike" @@ -816,6 +888,9 @@ msgstr "GhostPCL-ja ni bilo mogoče inicializirati" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "Slike MO" @@ -852,8 +927,8 @@ msgstr "Emulator starih računalnikov\n\nAvtorji: Miran Grča (OBattler), Richar msgid "Hardware not available" msgstr "Strojna oprema ni na voljo" -msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." -msgstr "Prepičajte se, da je nameščen %1 in da ste na omrežni povezavi, združljivi z libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Prepičajte se, da je nameščen %1 in da ste na omrežni povezavi, združljivi z %1." msgid "Invalid configuration" msgstr "Neveljavna konfiguracija" @@ -861,12 +936,9 @@ msgstr "Neveljavna konfiguracija" msgid "%1 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 "%1 je potreben za samodejno pretvorbo datotek PostScript v PDF.\n\nVsi dokumenti, poslani generičnemu tiskalniku PostScript bodo shranjeni kot datoteke PostScript (.ps)." -msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Lnaugage (.pcl) files." +msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 je potreben za samodejno pretvorbo datotek PCL v PDF.\n\nVsi dokumenti, poslani generičnemu tiskalniku PCL bodo shranjeni kot datoteke Printer Command Language (.pcl)." -msgid "Entering fullscreen mode" -msgstr "Preklapljam v celozaslonski način" - msgid "Don't show this message again" msgstr "Ne pokaži več tega sporočila" @@ -874,16 +946,16 @@ msgid "Don't exit" msgstr "Prekliči izhod" msgid "Reset" -msgstr "Resetiraj" +msgstr "Znova zaženi" msgid "Don't reset" -msgstr "Ne resetiraj" +msgstr "Ne zaženi znova" msgid "CD-ROM images" msgstr "Slike CD-ROM" msgid "%1 Device Configuration" -msgstr "Konfiguracija naprave %1" +msgstr "Nastavitev naprave %1" msgid "Monitor in sleep mode" msgstr "Zaslon v načinu spanja" @@ -903,12 +975,18 @@ msgstr "Nadaljuj" msgid "Cassette: %1" msgstr "Kaseta: %1" +msgid "C&assette: %1" +msgstr "K&aseta: %1" + msgid "Cassette images" msgstr "Slike kaset" msgid "Cartridge %1: %2" msgstr "Spominski vložek %1: %2" +msgid "Car&tridge %1: %2" +msgstr "S&pominski vložek %1: %2" + msgid "Cartridge images" msgstr "Slike spominskega vložka" @@ -930,6 +1008,9 @@ msgstr "Ponovni zagon" msgid "ACPI shutdown" msgstr "Zaustavitev ACPI" +msgid "ACP&I shutdown" +msgstr "Zaustavitev ACP&I" + msgid "Hard disk (%1)" msgstr "Trdi disk (%1)" @@ -946,7 +1027,7 @@ msgid "Add New Hard Disk" msgstr "Dodaj nov trdi disk" msgid "Add Existing Hard Disk" -msgstr "Dodaj obstoječ trdi disk" +msgstr "Dodaj obstoječi trdi disk" msgid "HDI disk images cannot be larger than 4 GB." msgstr "Slike diska HDI ne morejo biti večje od 4 GB." @@ -1048,13 +1129,13 @@ msgid "VHD files" msgstr "Datoteke VHD" msgid "Select the parent VHD" -msgstr "Izberite starševsko sliko VHD" +msgstr "Izberite nadrejeno sliko 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 "To lahko pomeni, da je bila starševska slika spremenjena potem, ko je že bila ustvarjena diferencialna slika.\n\nDo tega lahko pride tudi kadar so datoteke slik diska premaknjene ali kopirane, ali pa gre za hrošča v programu, ki je ustvaril ta disk.\n\nŽelite popraviti časovni žig?" +msgstr "To lahko pomeni, da je bila nadrejena slika spremenjena po ustvaritvi diferencialne slike.\n\nDo tega lahko pride tudi kadar so datoteke slik diska premaknjene ali kopirane, ali pa gre za hrošča v programu, ki je ustvaril ta disk.\n\nŽelite popraviti časovni žig?" msgid "Parent and child disk timestamps do not match" -msgstr "Časovna žiga starševske slike diska in slike diska otroka se ne ujemata" +msgstr "Časovna žiga nadrejene in podrejene slike diska se ne ujemata" msgid "Could not fix VHD timestamp." msgstr "Ne morem popraviti časovnega žiga slike VHD." @@ -1105,10 +1186,10 @@ msgid "1.44 MB" msgstr "1.44 MB" msgid "DMF (cluster 1024)" -msgstr "DMF (grozd 1024)" +msgstr "DMF (gruča 1024)" msgid "DMF (cluster 2048)" -msgstr "DMF (grozd 2048)" +msgstr "DMF (gruča 2048)" msgid "2.88 MB" msgstr "2.88 MB" @@ -1162,7 +1243,7 @@ msgid "(System Default)" msgstr "(Sistemsko privzeto)" msgid "Failed to initialize network driver" -msgstr "Ni uspelo inicializirati omrežnega gonilnika" +msgstr "Inicializacija omrežnega gonilnika ni uspela" msgid "The network configuration will be switched to the null driver" msgstr "Omrežne nastavitve bodo preklopljene na ničelni gonilnik" @@ -1215,47 +1296,47 @@ msgstr "Naprave MCA" msgid "List of MCA devices:" msgstr "Seznam naprav MCA:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Orodje za tablico" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "O programu Qt" +msgid "About &Qt" +msgstr "O programu &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "Naprave MCA..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Prikaži neprimarne monitorje" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Odprite mapo s posnetki zaslona..." -msgid "Apply fullscreen stretch mode when maximized" -msgstr "Uporabi način celozaslonskega raztezanja v povečanem stanju" +msgid "Appl&y fullscreen stretch mode when maximized" +msgstr "Uporabi način celozaslonskega raztezanja v maksimiranem stanju" -msgid "Cursor/Puck" -msgstr "Kazalec/ključ" +msgid "&Cursor/Puck" +msgstr "&Kazalec/ključ" -msgid "Pen" -msgstr "Pisalo" +msgid "&Pen" +msgstr "&Pisalo" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Pogon CD/DVD gostitelja (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Gostiteljski pogon CD/DVD (%1:)" msgid "&Connected" msgstr "&Povezan" -msgid "Clear image history" -msgstr "Jasna zgodovina slik" +msgid "Clear image &history" +msgstr "Počisti zgodovino slik" msgid "Create..." msgstr "Ustvari..." msgid "Host CD/DVD Drive (%1)" -msgstr "Pogon CD/DVD gostitelja (%1)" +msgstr "Gostiteljski pogon CD/DVD (%1)" msgid "Unknown Bus" msgstr "Neznano vodilo" @@ -1288,7 +1369,7 @@ msgid "Remove" msgstr "Odstrani" msgid "Browse..." -msgstr "Brskaj..." +msgstr "Prerskaj..." msgid "Couldn't create OpenGL context." msgstr "Ni bilo mogoče ustvariti konteksta OpenGL." @@ -1297,22 +1378,22 @@ msgid "Couldn't switch to OpenGL context." msgstr "Ni bilo mogoče preklopiti na kontekst OpenGL." msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" -msgstr "Zahteva se različica OpenGL 3.0 ali novejša. Trenutna različica je %1.%2" +msgstr "Potrebna je OpenGL različica 3.0 ali novejša. Trenutna različica je %1.%2" msgid "Error initializing OpenGL" msgstr "Napaka pri inicializaciji OpenGL" msgid "\nFalling back to software rendering." -msgstr "\nVrnitev k programskemu upodabljanju." +msgstr "\nVrnitev na programsko upodabljanje." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Pri izbiri medijskih slik (CD-ROM, disketa itd.) se bo odprto pogovorno okno začelo v istem imeniku kot konfiguracijska datoteka 86Box. Ta nastavitev bo verjetno imela pomen le v operacijskem sistemu MacOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Pri izbiri medijskih slik (CD-ROM, disketa itd.) se bo odprto pogovorno okno začelo v istem imeniku kot konfiguracijska datoteka 86Box. Ta nastavitev bo verjetno imela pomen le v operacijskem sistemu MacOS.

" msgid "This machine might have been moved or copied." msgstr "Ta naprava je bila morda premeščena ali kopirana." msgid "In order to ensure proper networking functionality, 86Box needs to know if this machine was moved or copied.\n\nSelect \"I Copied It\" if you are not sure." -msgstr "Da bi zagotovili pravilno delovanje omrežja, mora 86Box vedeti, ali je bil ta stroj prestavljen ali kopiran.\n\nČe niste prepričani, izberite \"Kopiral sem jo\"." +msgstr "Da bi zagotovili pravilno delovanje omrežja, mora 86Box vedeti, ali je bil ta virtualna naprava prestavljena ali kopirana.\n\nČe niste prepričani, izberite \"Kopiral sem jo\"." msgid "I Moved It" msgstr "Premaknil sem jo" @@ -1348,7 +1429,7 @@ msgid "Interface:" msgstr "Vmesnik:" msgid "Adapter:" -msgstr "Adapter:" +msgstr "Mrežna kartica:" msgid "VDE Socket:" msgstr "Vtičnica VDE:" @@ -1371,9 +1452,27 @@ msgstr "Prepust za serijska vrata 3" msgid "Serial port passthrough 4" msgstr "Prepust za serijska vrata 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Možnosti sistema za upodabljanje..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Miška na vodilu Logitech/Microsoft" @@ -1383,20 +1482,32 @@ msgstr "Miška na vodilu Microsoft (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Serijska miška Mouse Systems" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Serijska miška Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Serijska miška Logitech" msgid "PS/2 Mouse" msgstr "Miška PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (serijska)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" -msgstr "[COM] Standardni modem v skladu s standardom Hayes" +msgstr "[COM] Standardni modem v skladen s Hayes" msgid "Roland MT-32 Emulation" msgstr "Emulacija Roland MT-32" @@ -1411,19 +1522,61 @@ msgid "Roland CM-32LN Emulation" msgstr "Emulacija Roland CM-32LN" msgid "OPL4-ML Daughterboard" -msgstr "Hčerinska plošča OPL4-ML" +msgstr "Dodatna kartica OPL4-ML" msgid "System MIDI" -msgstr "Sistem MIDI" +msgstr "Sistemski MIDI" msgid "MIDI Input Device" msgstr "Vhodna naprava MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "Naslov BIOS-a" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" -msgstr "Omogočanje razširitve BIOS-a ROM piše" +msgstr "Omogoči zapisovanje razširitev BIOS ROM-a" + +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" msgid "Address" msgstr "Naslov" @@ -1434,8 +1587,20 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "Revizija BIOS-a" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" -msgstr "Prevesti 26 -> 17" +msgstr "Prevedi 26 -> 17" msgid "Language" msgstr "Jezik" @@ -1449,26 +1614,38 @@ msgstr "Invertiraj barve" msgid "BIOS size" msgstr "Velikost BIOS-a" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" -msgstr "Zemljevid C0000-C7FFF kot UMB" +msgstr "Preslikaj C0000-C7FFF kot UMB" msgid "Map C8000-CFFFF as UMB" -msgstr "Zemljevid C8000-CFFFF kot UMB" +msgstr "Preslikaj C8000-CFFFF kot UMB" msgid "Map D0000-D7FFF as UMB" -msgstr "Zemljevid D0000-D7FFF kot UMB" +msgstr "Preslikaj D0000-D7FFF kot UMB" msgid "Map D8000-DFFFF as UMB" -msgstr "Zemljevid D8000-DFFFF kot UMB" +msgstr "Preslikaj D8000-DFFFF kot UMB" msgid "Map E0000-E7FFF as UMB" -msgstr "Zemljevid E0000-E7FFF kot UMB" +msgstr "Preslikaj E0000-E7FFF kot UMB" msgid "Map E8000-EFFFF as UMB" -msgstr "Zemljevid E8000-EFFFF kot UMB" +msgstr "Preslikaj E8000-EFFFF kot UMB" msgid "JS9 Jumper (JIM)" -msgstr "JS9 Jumper (JIM)" +msgstr "JS9 mostiček (JIM)" msgid "MIDI Output Device" msgstr "Izhodna naprava MIDI" @@ -1524,6 +1701,9 @@ msgstr "Raven odmeva" msgid "Interpolation Method" msgstr "Metoda interpolacije" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Ojačanje izhoda odmeva" @@ -1582,10 +1762,10 @@ msgid "RAM Address" msgstr "Naslov RAM" msgid "RAM size" -msgstr "Velikost pomnilnika RAM" +msgstr "Velikost pomnilnika" msgid "Initial RAM size" -msgstr "Začetna velikost pomnilnika RAM" +msgstr "Začetna velikost pomnilnika" msgid "Serial Number" msgstr "Serijska številka" @@ -1597,7 +1777,7 @@ msgid "FDC Address" msgstr "Naslov FDC" msgid "MPU-401 Address" -msgstr "MPU-401 Naslov" +msgstr "Naslov MPU-401" msgid "MPU-401 IRQ" msgstr "MPU-401 IRQ" @@ -1611,6 +1791,12 @@ msgstr "Nizki DMA" msgid "Enable Game port" msgstr "Omogočanje igralnih vrat" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Prostorski modul" @@ -1623,6 +1809,9 @@ msgstr "Dvigni prekinitev za CODEC ob nastavitvi CODEC-a (to potrebujejo nekater msgid "SB Address" msgstr "Naslov SB" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "IRQ WSS" @@ -1633,7 +1822,7 @@ msgid "Enable OPL" msgstr "Omogoči OPL" msgid "Receive MIDI input (MPU-401)" -msgstr "Sprejemaj vhod MIDI (MPU-401)" +msgstr "Vhod MIDI za sprejem (MPU-401)" msgid "SB low DMA" msgstr "Nizki DMA SB" @@ -1666,7 +1855,7 @@ msgid "Codec" msgstr "Kodek" msgid "GUS type" -msgstr "Tip GUS" +msgstr "Vrsta GUS" msgid "Enable 0x04 \"Exit 86Box\" command" msgstr "Omogoči ukaz 0x04 \"Zapusti 86Box\"" @@ -1681,7 +1870,7 @@ msgid "RGB type" msgstr "Vrsta RGB zaslona" msgid "Line doubling type" -msgstr "Vrsta podvojitve črt" +msgstr "Vrsta podvojevanja črt" msgid "Snow emulation" msgstr "Emulacija snega" @@ -1693,34 +1882,40 @@ msgid "Character set" msgstr "Nabor znakov" msgid "XGA type" -msgstr "Tip kartice XGA" +msgstr "Vrsta kartice XGA" msgid "Instance" -msgstr "Primer" +msgstr "Primerek" msgid "MMIO Address" msgstr "Naslov MMIO" msgid "RAMDAC type" -msgstr "Vrsta čipa RAMDAC" +msgstr "Vrsta RAMDAC" msgid "Blend" msgstr "Mešanica" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Bilinearno filtriranje" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Barvno stresanje" msgid "Enable NMI for CGA emulation" -msgstr "Omogočite NMI za emulacijo CGA" +msgstr "Omogoči NMI za emulacijo CGA" msgid "Voodoo type" -msgstr "Tip kartice Voodoo" +msgstr "Vrsta kartice Voodoo" msgid "Framebuffer memory size" -msgstr "Velikost pomnilnika predpomnilnika okvirja" +msgstr "Velikost videopomnilnika" msgid "Texture memory size" msgstr "Velikost pomnilnika tekstur" @@ -1732,7 +1927,7 @@ msgid "Screen Filter" msgstr "Filter zaslona" msgid "Render threads" -msgstr "Nitke za upodabljanje" +msgstr "Niti za upodabljanje" msgid "SLI" msgstr "SLI" @@ -1752,6 +1947,33 @@ msgstr "Hitrost prenosa" msgid "EMS mode" msgstr "Način EMS" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Naslov za > 2 MB" @@ -1770,11 +1992,11 @@ msgstr "Vedno pri izbrani hitrosti" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Nastavitev BIOS-a + Vroče tipke (izklopljeno med POST)" -msgid "64 kB starting from F0000" -msgstr "64 kB od F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB od F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB od E0000 (MSB naslova invertiran, najprej zadnjih 64 kB)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB od E0000 (MSB naslova invertiran, najprej zadnjih 64 KB)" msgid "Sine" msgstr "Sinusna" @@ -1795,7 +2017,7 @@ msgid "Non-timed (original)" msgstr "Brez časovnika (izvirnik)" msgid "45 Hz (JMP2 not populated)" -msgstr "45 Hz (brez mostička na JMP2)" +msgstr "45 Hz (brez mostička JMP2)" msgid "Two" msgstr "Dva" @@ -1804,13 +2026,13 @@ msgid "Three" msgstr "Tri" msgid "Wheel" -msgstr "Kolesa" +msgstr "Kolesce" msgid "Five + Wheel" -msgstr "Pet + kolo" +msgstr "Pet + kolesce" msgid "Five + 2 Wheels" -msgstr "" +msgstr "Pet + 2 kolesci" msgid "A3 - SMT2 Serial / SMT3(R)V" msgstr "A3 - SMT2 serijska / SMT3(R)V" @@ -1885,13 +2107,13 @@ msgid "Color (generic)" msgstr "Barvni (generični)" msgid "Green Monochrome" -msgstr "Zeleni enobvarni" +msgstr "Zeleni monokromatski" msgid "Amber Monochrome" -msgstr "Jantarni enobarvni" +msgstr "Jantarni monokromatski" msgid "Gray Monochrome" -msgstr "Sivi enobarvni" +msgstr "Sivi monokromatski" msgid "Color (no brown)" msgstr "Barvni (brez rjave)" @@ -1908,17 +2130,26 @@ msgstr "Interpolacija sRGB" msgid "Linear interpolation" msgstr "Linearna interpolacija" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" msgid "Monochrome (5151/MDA) (white)" -msgstr "Enobarvni (5151/MDA) (beli)" +msgstr "Monokromatski (5151/MDA) (beli)" msgid "Monochrome (5151/MDA) (green)" -msgstr "Enobarvni (5151/MDA) (zeleni)" +msgstr "Monokromatski (5151/MDA) (zeleni)" msgid "Monochrome (5151/MDA) (amber)" -msgstr "Enobarvni (5151/MDA) (jantarni)" +msgstr "Monokromatski (5151/MDA) (jantarni)" msgid "Color 40x25 (5153/CGA)" msgstr "Barvni 40x25 (5153/CGA)" @@ -1930,7 +2161,7 @@ msgid "Enhanced Color - Normal Mode (5154/ECD)" msgstr "Izboljšani barvni - običajni način (5154/ECD)" msgid "Enhanced Color - Enhanced Mode (5154/ECD)" -msgstr "Izboljšani barvni - Izboljšani način (5154/ECD)" +msgstr "Izboljšani barvni - izboljšani način (5154/ECD)" msgid "Green" msgstr "Zeleni" @@ -1941,6 +2172,9 @@ msgstr "Jantarni" msgid "Gray" msgstr "Sivi" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Barvni" @@ -1956,6 +2190,12 @@ msgstr "Drugi jeziki" msgid "Bochs latest" msgstr "Bochs najnovejše" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Enobarvni brez prepletanja" @@ -2008,7 +2248,7 @@ msgid "Generic PCL5e Printer" msgstr "Generični tiskalnik PCL5e" msgid "Parallel Line Internet Protocol" -msgstr "Internetni protokol za paralelno linijo" +msgstr "Internetni protokol za vzporedno linijo" msgid "Protection Dongle for Savage Quest" msgstr "Zaščitni ključek za Savage Quest" @@ -2029,7 +2269,7 @@ msgid "Data bits" msgstr "Podatkovni biti" msgid "Stop bits" -msgstr "Stop biti" +msgstr "Zaključni biti" msgid "Baud Rate of Passthrough" msgstr "Baudna hitrost prepusta" @@ -2037,8 +2277,11 @@ msgstr "Baudna hitrost prepusta" msgid "Named Pipe (Server)" msgstr "Poimenovana cev (Strežnik)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" -msgstr "Prepustno serijskih vrat gostitelja" +msgstr "Prepust serijskih vrat gostitelja" msgid "E&ject %1" msgstr "I&zvrzi %1" @@ -2053,7 +2296,7 @@ msgid "High performance impact" msgstr "Visok učinek na hitrost delovanja" msgid "[Generic] RAM Disk (max. speed)" -msgstr "[Generic] Pogon RAM (največja hitrost)" +msgstr "[Generic] Pomnilniški disk (največja hitrost)" msgid "[Generic] 1989 (3500 RPM)" msgstr "" @@ -2082,6 +2325,12 @@ msgstr "Klon IBM 8514/A (ISA)" msgid "Vendor" msgstr "Proizvajalec" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "Generična razširitev pomnilnika PC/XT" @@ -2089,28 +2338,25 @@ msgid "Generic PC/AT Memory Expansion" msgstr "Generična razširitev pomnilnika PC/AT" msgid "Unable to find Dot-Matrix fonts" -msgstr "Matričnih pisav ni bilo mogoče najti" +msgstr "Ni bilo mogoče najti matričnih pisav" msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for the emulation of the Generic ESC/P Dot-Matrix Printer." -msgstr "Matrične pisave v imeniku \"roms/printer/fonts\" so potrebne za emulacijo generičnega matričnega tiskalnika ESC/P." +msgstr "Za emulacijo generičnega ESC/P matričnega tiskalnika so potrebne TrueType pisave v imeniku \"roms/printer/fonts\"." msgid "Inhibit multimedia keys" -msgstr "" +msgstr "Blokiraj multimedijske tipke" msgid "Ask for confirmation before saving settings" -msgstr "" +msgstr "Vprašaj za potrditev pred shranjevanjem nastavitev" msgid "Ask for confirmation before hard resetting" -msgstr "" +msgstr "Vprašaj za potrditev pred ponovnim zagonom" msgid "Ask for confirmation before quitting" -msgstr "" - -msgid "Display hotkey message when entering full-screen mode" -msgstr "" +msgstr "Vprašaj za potrditev pred izhodom" msgid "Options" -msgstr "" +msgstr "Možnosti" msgid "Model" msgstr "" @@ -2119,40 +2365,124 @@ msgid "Model:" msgstr "" msgid "Failed to initialize Vulkan renderer." -msgstr "" +msgstr "Inicializacija upodobljevalnika Vulkan ni uspela." msgid "GLSL Error" -msgstr "" +msgstr "Napaka GLSL" msgid "Could not load shader: %1" -msgstr "" +msgstr "Ni bilo mogoče naložiti senčilnika: %1" msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "" +msgstr "Potrebna je OpenGL različica 3.0 ali novejša. Trenutna različica GLSL je %1.%2" msgid "Could not load texture: %1" -msgstr "" +msgstr "Ni bilo mogoče naložiti teksture: %1" msgid "Could not compile shader:\n\n%1" -msgstr "" +msgstr "Ni bilo mogoče prevesti senčilnika:\n\n%1" msgid "Program not linked:\n\n%1" -msgstr "" +msgstr "Program ni povezan:\n\n%1" msgid "Shader Manager" -msgstr "" +msgstr "Upravljalnik senčilnikov" msgid "Shader Configuration" -msgstr "" +msgstr "Nastavitve senčilnikov" msgid "Add" -msgstr "" +msgstr "Dodaj" msgid "Move up" -msgstr "" +msgstr "Premakni gor" msgid "Move down" -msgstr "" +msgstr "Premakni dol" msgid "Could not load file %1" +msgstr "Ni bilo mogoče naložiti datoteke %1" + +msgid "Key Bindings:" msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Krmilnik trdega diska:" + +#~ msgid "ZIP drives:" +#~ msgstr "Pogoni ZIP:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "ZIP slike" diff --git a/src/qt/languages/sv-SE.po b/src/qt/languages/sv-SE.po index 61152c663..3ec9c0b75 100644 --- a/src/qt/languages/sv-SE.po +++ b/src/qt/languages/sv-SE.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Pausa" -msgid "E&xit..." -msgstr "A&vsluta..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "A&vsluta" msgid "&View" msgstr "&Visa" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "Ange mått..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "Filtermetod" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "Skärmtyp för &VGA" msgid "RGB &Color" msgstr "RGB &färg" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "&RGB gråskala" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "&Bärnstensfärgad skärm" @@ -384,6 +393,15 @@ msgstr "Aktiverad (UTC)" msgid "Dynamic Recompiler" msgstr "Dynamisk omkompilering" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Bildskärmskort:" @@ -399,6 +417,9 @@ msgstr "IBM 8514/A-grafik" msgid "XGA Graphics" msgstr "XGA-grafik" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Mus:" @@ -498,18 +519,21 @@ msgstr "Parallellport 3" msgid "Parallel port 4" msgstr "Parallellport 4" -msgid "HD Controller:" -msgstr "Styrenhet för hårddisk:" - msgid "FD Controller:" msgstr "Styrenhet för diskett:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "Tertiär IDE-kontroller" msgid "Quaternary IDE Controller" msgstr "Kvartär IDE-kontroller" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Kassettband" msgid "Hard disks:" msgstr "Hårddiskar:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "&Ny..." @@ -588,8 +615,8 @@ msgstr "CD-ROM-enheter:" msgid "MO drives:" msgstr "MO-enheter:" -msgid "ZIP drives:" -msgstr "Zip-enheter:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA realtidsklocka:" msgid "ISA Memory Expansion" msgstr "ISA minnesexpansion" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Kort 1:" @@ -612,6 +642,15 @@ msgstr "Kort 3:" msgid "Card 4:" msgstr "Kort 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "ISABugger-enhet" @@ -630,17 +669,20 @@ msgstr "Allvarligt fel" msgid " - PAUSED" msgstr " - PAUSAD" -msgid "Press %s to return to windowed mode." -msgstr "Tryck på %s för att återvända till fönsterläge." - msgid "Speed" msgstr "Hastighet" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "Zip-avbildningar" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "86Box kunde inte hitta några användbara ROM-avbildningar.\n\nVänligen ladda ner en ROM-uppsättning och extrahera den till mappen \"roms\"." @@ -717,11 +759,11 @@ msgstr "Andra tillbehör" msgid "Click to capture mouse" msgstr "Klicka för att fånga upp musen" -msgid "Press %s to release mouse" -msgstr "Tryck på %s för att släppa musen" +msgid "Press %1 to release mouse" +msgstr "Tryck på %1 för att släppa musen" -msgid "Press %s or middle button to release mouse" -msgstr "Tryck på %s eller mellersta musknappen för att släppa musen" +msgid "Press %1 or middle button to release mouse" +msgstr "Tryck på %1 eller mellersta musknappen för att släppa musen" msgid "Bus" msgstr "Buss" @@ -780,12 +822,39 @@ msgstr "Styrspak med 4 axlar och 4 knappar" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Ingen" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Diskett %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Diskett %1 (%2): %3" + msgid "Advanced sector images" msgstr "Avancerade sektoravbildningar" @@ -816,6 +888,9 @@ msgstr "Ej möjligt att initialisera GhostPCL" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "MO-avbildningar" @@ -864,9 +939,6 @@ msgstr "%1 krävs för automatisk omvandling av PostScript-filer till PDF.\n\nAl msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 krävs för automatisk omvandling av PCL-filer till PDF.\n\nAlla dokument som skickas till den allmänna PCL-skrivaren kommer att sparas som Printer Command Language-filer (.pcl)." -msgid "Entering fullscreen mode" -msgstr "Startar helskärmsläge" - msgid "Don't show this message again" msgstr "Visa inte detta meddelande igen" @@ -903,12 +975,18 @@ msgstr "Fortsätt" msgid "Cassette: %1" msgstr "Kassettband: %1" +msgid "C&assette: %1" +msgstr "K&assettband: %1" + msgid "Cassette images" msgstr "Kassettbandsavbildningar" msgid "Cartridge %1: %2" msgstr "Kassett %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Ka&ssett %1: %2" + msgid "Cartridge images" msgstr "Kassettavbildningar" @@ -930,6 +1008,9 @@ msgstr "Hård omstart" msgid "ACPI shutdown" msgstr "ACPI-avstängning" +msgid "ACP&I shutdown" +msgstr "ACP&I-avstängning" + msgid "Hard disk (%1)" msgstr "Hårddisk (%1)" @@ -1215,40 +1296,40 @@ msgstr "MCA-enheter" msgid "List of MCA devices:" msgstr "Lista på MCA-enheter:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Plattverktyg" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "Om Qt" +msgid "About &Qt" +msgstr "Om &Qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "MCA-enheter..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Visa icke-primära skärmar" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Öppna skärmbildsmappen..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Tillämpa sträckläge för helskärm när den är maximerad" -msgid "Cursor/Puck" -msgstr "Pekare/puck" +msgid "&Cursor/Puck" +msgstr "&Pekare/puck" -msgid "Pen" -msgstr "Penna" +msgid "&Pen" +msgstr "P&enna" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Värdenhet för CD/DVD (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Värdenhet för CD/DVD (%1:)" msgid "&Connected" msgstr "&Ansluten" -msgid "Clear image history" +msgid "Clear image &history" msgstr "Rensa historik för avbildningar" msgid "Create..." @@ -1305,8 +1386,8 @@ msgstr "Fel vid initialisering av OpenGL" msgid "\nFalling back to software rendering." msgstr "\nFaller tillbaka på mjukvarurendering." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Vid val av medieavbildningar (CD-ROM, diskett, osv.) så kommer fönstret att börja i samma mapp som 86Box konfigurationsfil. Denna inställning kommer troligtvis endast göra en skillnad på macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Vid val av medieavbildningar (CD-ROM, diskett, osv.) så kommer fönstret att börja i samma mapp som 86Box konfigurationsfil. Denna inställning kommer troligtvis endast göra en skillnad på macOS.

" msgid "This machine might have been moved or copied." msgstr "Denna maskin kan ha flyttats eller kopierats." @@ -1371,9 +1452,27 @@ msgstr "Serieport passthrough 3" msgid "Serial port passthrough 4" msgstr "Serieport passthrough 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Renderingsalternativ..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Logitech/Microsoft-buss-mus" @@ -1383,18 +1482,30 @@ msgstr "Microsoft-buss-mus (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Mouse Systems seriemus" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Microsoft seriemus" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Logitech seriemus" msgid "PS/2 Mouse" msgstr "PS/2-mus" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (serie)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Standard Hayes-kompatibelt modem" @@ -1419,12 +1530,54 @@ msgstr "System-MIDI" msgid "MIDI Input Device" msgstr "Indataenhet för MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "BIOS-adress" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "Aktivera ROM-skrivningar för utökat BIOS" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Adress" @@ -1434,6 +1587,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "BIOS revision" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Översätt 26 -> 17" @@ -1449,6 +1614,18 @@ msgstr "Invertera färger" msgid "BIOS size" msgstr "Storlek på BIOS" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "Kartlägg C0000-C7FFF som UMB" @@ -1524,6 +1701,9 @@ msgstr "Reverb nivå" msgid "Interpolation Method" msgstr "Interpoleringsmetod" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Reverb utmatningsförstärkning" @@ -1611,6 +1791,12 @@ msgstr "Låg DMA" msgid "Enable Game port" msgstr "Aktivera spelport" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Sorround-modul" @@ -1623,6 +1809,9 @@ msgstr "Öka avbrottsnummer för CODEC vid CODEC-installation (krävs av vissa d msgid "SB Address" msgstr "Adress för SB" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "WSS IRQ" @@ -1707,9 +1896,15 @@ msgstr "RAMDAC-typ" msgid "Blend" msgstr "Blanda" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Bilinjär filtrering" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Dithering" @@ -1752,6 +1947,33 @@ msgstr "Överföringshastighet" msgid "EMS mode" msgstr "EMS-läge" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Adress till > 2 MB" @@ -1770,11 +1992,11 @@ msgstr "Alltid vid den valda hastigheten" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "BIOS-inställningar + Snabbtangenter (av under POST)" -msgid "64 kB starting from F0000" -msgstr "64 kB som börjar från F0000" +msgid "64 KB starting from F0000" +msgstr "64 KB som börjar från F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB som börjar från E0000 (adress MSB inverterad, de sista 64KB först)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB som börjar från E0000 (adress MSB inverterad, de sista 64 KB först)" msgid "Sine" msgstr "Sinus" @@ -1908,6 +2130,15 @@ msgstr "sRGB-interpolering" msgid "Linear interpolation" msgstr "Linjär interpolering" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2172,9 @@ msgstr "Bärnstensfärgad" msgid "Gray" msgstr "Grå" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Färg" @@ -1956,6 +2190,12 @@ msgstr "Andra språk" msgid "Bochs latest" msgstr "Bochs senaste" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Ej sammanflätad monokrom" @@ -2037,6 +2277,9 @@ msgstr "Passthroughns Baudhastighet" msgid "Named Pipe (Server)" msgstr "Namngiven pipe (server)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "Värd-seriepassthrough" @@ -2112,9 +2355,6 @@ msgstr "Bekräfta innan hård omstart" msgid "Ask for confirmation before quitting" msgstr "Bekräfta innan avslut" -msgid "Display hotkey message when entering full-screen mode" -msgstr "Visa meddelande om snabbtangenter när helskärmsläget startas" - msgid "Options" msgstr "Alternativ" @@ -2162,3 +2402,87 @@ msgstr "Flytta ner" msgid "Could not load file %1" msgstr "Kunde inte ladda fil %1" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Styrenhet för hårddisk:" + +#~ msgid "ZIP drives:" +#~ msgstr "Zip-enheter:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "Zip-avbildningar" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index de111c59b..748f6532a 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -16,7 +16,7 @@ msgid "&Right CTRL is left ALT" msgstr "&Sağ CTRL tuşunu sol ALT tuşu olarak ayarla" msgid "&Hard Reset..." -msgstr "Yeniden başlamaya &zorla" +msgstr "Yeniden başlamaya &zorla..." msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -27,8 +27,11 @@ msgstr "Ctrl+&Alt+Esc" msgid "&Pause" msgstr "&Duraklat" -msgid "E&xit..." -msgstr "&Çıkış..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "&Çıkış yap" msgid "&View" msgstr "&Görünüm" @@ -40,34 +43,34 @@ msgid "Hide &toolbar" msgstr "Araç &çubuğunu gizle" msgid "&Resizeable window" -msgstr "&Yeniden boyutlandırılabilir pencere" +msgstr "&Boyutlandırılabilir pencere" msgid "R&emember size && position" -msgstr "&Pencere boyut ve pozisyonunu hatırla" +msgstr "&Pencere boyut ve pozisyonunu kaydet" msgid "Re&nderer" -msgstr "&İşleyici" +msgstr "Derley&ici" msgid "&Qt (Software)" -msgstr "&Qt (Yazılım)" +msgstr "&Qt (Yazılım bazlı)" msgid "Qt (&OpenGL)" -msgstr "Qt (&OpenGL)" +msgstr "Qt (&OpenGL bazlı)" msgid "Open&GL (3.0 Core)" -msgstr "OpenG&L (3.0 bazlı)" +msgstr "OpenG&L (Sürüm 3.0)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "Pencere &boyutunu belirle..." msgid "F&orce 4:3 display ratio" msgstr "4:3 görüntü oranına &zorla" msgid "&Window scale factor" -msgstr "Pencere &ölçek çarpanı" +msgstr "Pencere &boyutu ölçeği" msgid "&0.5x" msgstr "&0.5x" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "&Filtreleme yöntemi" msgid "&Nearest" @@ -109,7 +112,7 @@ msgid "&Linear" msgstr "Doğ&rusal" msgid "Hi&DPI scaling" -msgstr "HiDPI ölçekle&mesi" +msgstr "HiDPI boyutlandır&ması" msgid "&Fullscreen" msgstr "Tam ekran" @@ -118,13 +121,13 @@ msgid "Fullscreen &stretch mode" msgstr "Tam e&kran germe modu" msgid "&Full screen stretch" -msgstr "&Tam ekrana ger" +msgstr "Ekranın &tamamına ger" msgid "&4:3" msgstr "&4:3" msgid "&Square pixels (Keep ratio)" -msgstr "&Kare piksel (ölçeği koru)" +msgstr "&Kare piksel (ölçeği değiştirme)" msgid "&Integer scale" msgstr "Tam &sayı ölçeklemesi" @@ -142,22 +145,28 @@ msgid "VGA screen &type" msgstr "VGA ekran &tipi" msgid "RGB &Color" -msgstr "RGB (&renkli)" +msgstr "RGB (&Çok renkli)" + +msgid "RGB (no brown)" +msgstr "" msgid "&RGB Grayscale" -msgstr "RGB (&gri tonlama)" +msgstr "RGB (&Gri tonlu)" + +msgid "Generic RGBI color monitor" +msgstr "" msgid "&Amber monitor" -msgstr "&Kehribar renkli monitör" +msgstr "&Kehribar monitör" msgid "&Green monitor" -msgstr "&Yeşil renkli monitör" +msgstr "&Yeşil monitör" msgid "&White monitor" -msgstr "&Beyaz renkli monitör" +msgstr "&Beyaz monitör" msgid "Grayscale &conversion type" -msgstr "&Gri tonlama dönüştürme türü" +msgstr "&Gri tonlu dönüşüm türü" msgid "BT&601 (NTSC/PAL)" msgstr "BT&601 (NTSC/PAL)" @@ -172,7 +181,7 @@ msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA aşırı taraması" msgid "Change contrast for &monochrome display" -msgstr "Gri to&nlamalı görüntü için kontrastı değiştir" +msgstr "Gri to&nlu görüntü için kontrastı değiştir" msgid "&Media" msgstr "&Medya" @@ -189,17 +198,17 @@ msgstr "Durum &çubuğu simgelerini güncelle" msgid "Take s&creenshot" msgstr "&Ekran görüntüsü al" +msgid "S&ound" +msgstr "&Ses" + msgid "&Preferences..." msgstr "&Tercihler..." msgid "Enable &Discord integration" msgstr "&Discord entegrasyonunu etkinleştir" -msgid "S&ound" -msgstr "&Ses" - msgid "Sound &gain..." -msgstr "&Ses düzeyi artışı..." +msgstr "&Sesi artır..." msgid "Begin trace" msgstr "İzlemeyi başlat" @@ -211,7 +220,7 @@ msgid "&Help" msgstr "&Yardım" msgid "&Documentation..." -msgstr "&Dökümanlar..." +msgstr "&Belgeler..." msgid "&About 86Box..." msgstr "&86Box hakkında..." @@ -232,22 +241,22 @@ msgid "&Play" msgstr "&Oynat" msgid "&Rewind to the beginning" -msgstr "&Başlangıca geri sar" +msgstr "&Başa geri sar" msgid "&Fast forward to the end" -msgstr "Sona doğru &ileri sar" +msgstr "Sona &doğru sar" msgid "E&ject" msgstr "&Çıkar" msgid "&Image..." -msgstr "&İmaj..." +msgstr "&İmaj seç..." msgid "E&xport to 86F..." -msgstr "&86F dosyası olarak kaydet..." +msgstr "&86F olarak kaydet..." msgid "&Mute" -msgstr "&Sesi kapat" +msgstr "&Sessize al" msgid "E&mpty" msgstr "İmajı &çıkar" @@ -256,7 +265,7 @@ msgid "Reload previous image" msgstr "Önceki imajı yeniden seç" msgid "&Folder..." -msgstr "&Klasör..." +msgstr "&Klasör seç..." msgid "Target &framerate" msgstr "Hedef &kare hızı oranı" @@ -292,7 +301,7 @@ msgid "Preferences" msgstr "Tercihler" msgid "Sound Gain" -msgstr "Ses düzeyi artışı" +msgstr "Ses Artışı" msgid "New Image" msgstr "Yeni imaj" @@ -301,13 +310,13 @@ msgid "Settings" msgstr "Ayarlar" msgid "Specify Main Window Dimensions" -msgstr "Ana pencere boyutunu belirle" +msgstr "Ana Pencere Boyutunu Belirle" msgid "OK" msgstr "Tamam" msgid "Cancel" -msgstr "İptal" +msgstr "İptal et" msgid "&Default" msgstr "&Varsayılan" @@ -316,7 +325,7 @@ msgid "Language:" msgstr "Dil:" msgid "Gain" -msgstr "Artış" +msgstr "Artış düzeyi" msgid "File name:" msgstr "Dosya adı:" @@ -358,7 +367,7 @@ msgid "Frequency:" msgstr "Saat hızı:" msgid "FPU:" -msgstr "Kayan Nokta Birimi (FPU):" +msgstr "FPU:" msgid "Wait states:" msgstr "Bekleme süreleri:" @@ -367,7 +376,7 @@ msgid "MB" msgstr "MB" msgid "Memory:" -msgstr "Bellek:" +msgstr "Bellek (RAM):" msgid "Time synchronization" msgstr "Zaman senkronizasyonu" @@ -382,58 +391,70 @@ msgid "Enabled (UTC)" msgstr "Etkin (UTC)" msgid "Dynamic Recompiler" -msgstr "Dinamik derleyici" +msgstr "Dinamik Derleyici" + +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" msgid "Video:" msgstr "Ekran kartı:" msgid "Video #2:" -msgstr "Ekran kartı 2:" +msgstr "İkincil ekran kartı:" msgid "Voodoo 1 or 2 Graphics" -msgstr "Voodoo 1 veya 2 grafikleri" +msgstr "Voodoo 1 veya 2 Grafikleri" msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A grafikleri" +msgstr "IBM 8514/A Grafikleri" msgid "XGA Graphics" -msgstr "XGA grafikleri" +msgstr "XGA Grafikleri" + +msgid "Keyboard:" +msgstr "" msgid "Mouse:" msgstr "Fare:" msgid "Joystick:" -msgstr "Oyun kolu:" +msgstr "Oyun Kolu:" msgid "Joystick 1..." -msgstr "Oyun kolu 1..." +msgstr "1. Oyun Kolu..." msgid "Joystick 2..." -msgstr "Oyun kolu 2..." +msgstr "2. Oyun Kolu..." msgid "Joystick 3..." -msgstr "Oyun kolu 3..." +msgstr "3. Oyun Kolu..." msgid "Joystick 4..." -msgstr "Oyun kolu 4..." +msgstr "4. Oyun Kolu..." msgid "Sound card #1:" -msgstr "Ses kartı 1:" +msgstr "1. Ses Kartı:" msgid "Sound card #2:" -msgstr "Ses kartı 2:" +msgstr "2. Ses Kartı:" msgid "Sound card #3:" -msgstr "Ses kartı 3:" +msgstr "3. Ses Kartı:" msgid "Sound card #4:" -msgstr "Ses kartı 4:" +msgstr "4. Ses Kartı:" msgid "MIDI Out Device:" -msgstr "MIDI çıkış cihazı:" +msgstr "MIDI Çıkış Cihazı:" msgid "MIDI In Device:" -msgstr "MIDI giriş cihazı:" +msgstr "MIDI Giriş Cihazı:" msgid "Standalone MPU-401" msgstr "Bağımsız MPU-401" @@ -451,79 +472,82 @@ msgid "YMFM (faster)" msgstr "YMFM (daha hızlı)" msgid "COM1 Device:" -msgstr "COM1 cihazı:" +msgstr "COM1 Cihazı:" msgid "COM2 Device:" -msgstr "COM2 cihazı:" +msgstr "COM2 Cihazı:" msgid "COM3 Device:" -msgstr "COM3 cihazı:" +msgstr "COM3 Cihazı:" msgid "COM4 Device:" -msgstr "COM4 cihazı:" +msgstr "COM4 Cihazı:" msgid "LPT1 Device:" -msgstr "LPT1 cihazı:" +msgstr "LPT1 Cihazı:" msgid "LPT2 Device:" -msgstr "LPT2 cihazı:" +msgstr "LPT2 Cihazı:" msgid "LPT3 Device:" -msgstr "LPT3 cihazı:" +msgstr "LPT3 Cihazı:" msgid "LPT4 Device:" -msgstr "LPT4 cihazı:" +msgstr "LPT4 Cihazı:" msgid "Serial port 1" -msgstr "Seri port 1" +msgstr "1. Seri Port" msgid "Serial port 2" -msgstr "Seri port 2" +msgstr "2. Seri Port" msgid "Serial port 3" -msgstr "Seri port 3" +msgstr "3. Seri Port" msgid "Serial port 4" -msgstr "Seri port 4" +msgstr "4. Seri Port" msgid "Parallel port 1" -msgstr "Paralel port 1" +msgstr "1. Paralel Port" msgid "Parallel port 2" -msgstr "Paralel port 2" +msgstr "2. Paralel Port" msgid "Parallel port 3" -msgstr "Paralel port 3" +msgstr "3. Paralel Port" msgid "Parallel port 4" -msgstr "Paralel port 4" - -msgid "HD Controller:" -msgstr "Hard disk kontrolcüsü:" +msgstr "4. Paralel Port" msgid "FD Controller:" -msgstr "Disket sürücü kontrolcüsü:" +msgstr "Disket Denetleyicisi:" + +msgid "CD-ROM Controller:" +msgstr "" msgid "Tertiary IDE Controller" -msgstr "Üçlü IDE kontrolcüsü" +msgstr "Üçlü IDE Denetleyici" msgid "Quaternary IDE Controller" -msgstr "Dörtlü IDE kontrolcüsü" +msgstr "Dörtlü IDE Denetleyici" + +msgid "Hard disk" +msgstr "" msgid "SCSI" msgstr "SCSI" msgid "Controller 1:" -msgstr "Kontrolcü 1:" +msgstr "1. Denetleyici:" msgid "Controller 2:" -msgstr "Kontrolcü 2:" +msgstr "2. Denetleyici:" msgid "Controller 3:" -msgstr "Kontrolcü 3:" +msgstr "3. Denetleyici:" msgid "Controller 4:" -msgstr "Kontrolcü 4:" +msgstr "4. Denetleyici:" msgid "Cassette" msgstr "Kaset" @@ -531,11 +555,14 @@ msgstr "Kaset" msgid "Hard disks:" msgstr "Hard diskler:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." -msgstr "&Yeni..." +msgstr "&Yeni imaj oluştur" msgid "&Existing..." -msgstr "&Var olanı seç..." +msgstr "&İmaj dosyası seç" msgid "&Remove" msgstr "&Kaldır" @@ -568,7 +595,7 @@ msgid "Type:" msgstr "Tür:" msgid "Image Format:" -msgstr "İmaj düzeni:" +msgstr "İmaj Türü:" msgid "Block Size:" msgstr "Blok boyutu:" @@ -577,7 +604,7 @@ msgid "Floppy drives:" msgstr "Disket sürücüleri:" msgid "Turbo timings" -msgstr "Turbo zamanlamaları" +msgstr "Turbo zamanlaması" msgid "Check BPB" msgstr "BPB'yi denetle" @@ -588,8 +615,8 @@ msgstr "CD-ROM sürücüleri:" msgid "MO drives:" msgstr "MO sürücüleri:" -msgid "ZIP drives:" -msgstr "ZIP sürücüleri:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -598,7 +625,10 @@ msgid "ISA RTC:" msgstr "ISA RTC:" msgid "ISA Memory Expansion" -msgstr "ISA bellek artırma" +msgstr "ISA Bellek Artırıcı" + +msgid "ISA ROM Cards" +msgstr "" msgid "Card 1:" msgstr "Kart 1:" @@ -612,6 +642,15 @@ msgstr "Kart 3:" msgid "Card 4:" msgstr "Kart 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "ISABugger cihazı" @@ -630,20 +669,23 @@ msgstr "Kritik hata" msgid " - PAUSED" msgstr " - DURAKLATILDI" -msgid "Press %s to return to windowed mode." -msgstr "Pencere moduna geri dönmek için %s tuşlarına basın." - msgid "Speed" msgstr "Hız" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "ZIP imajları" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box kullanılabilir hiçbir ROM imajı bulamadı.\n\nLütfen ROM setini indirin ve \"Roms\" klasörüne çıkarın." +msgstr "86Box kullanılabilir hiçbir ROM dosyası bulamadı.\n\nLütfen bir ROM seti indirip \"roms\" klasörüne çıkarın." msgid "(empty)" msgstr "(boş)" @@ -670,16 +712,16 @@ msgid "Surface images" msgstr "Yüzey imajları" msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -msgstr "\"%hs\" makinesi roms/machines klasöründe gerekli ROM imajlarının mevcut olmaması nedeniyle kullanılamıyor. Bundan dolayı kullanılabilen bir makineye geçiş yapılacaktır." +msgstr "\"%hs\" makinesi roms/machines klasöründe gerekli ROM dosyalarının mevcut olmaması nedeniyle kullanılamıyor. Kullanılabilen başka bir makineye geçiş yapılacaktır." msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." -msgstr "\"%hs\" ekran kartı roms/video klasöründe gerekli ROM imajlarının mevcut olmaması nedeniyle kullanılamıyor. Bundan dolayı kullanılabilen bir ekran kartına geçiş yapılacaktır." +msgstr "\"%hs\" ekran kartı roms/video klasöründe gerekli ROM dosyalarının mevcut olmaması nedeniyle kullanılamıyor. Kullanılabilen başka bir ekran kartına geçiş yapılacaktır." msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." -msgstr "\"%hs\" ikinci ekran kartı roms/video klasöründe gerekli ROM imajlarının mevcut olmaması nedeniyle kullanılamıyor. İkinci ekran kartı devre dışı bırakılır." +msgstr "\"%hs\" ikincil ekran kartı roms/video klasöründe gerekli ROM dosyalarının mevcut olmaması nedeniyle kullanılamıyor. Bu cihaz devre dışı bırakılacaktır." msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." -msgstr "\"%hs\" cihazı gerekli ROM imajlarının mevcut olmaması nedeniyle kullanılamıyor. Cihaz yok sayılıyor." +msgstr "\"%hs\" cihazı gerekli ROM dosyalarının mevcut olmaması nedeniyle kullanılamıyor. Bu cihaz yok sayılacaktır." msgid "Machine" msgstr "Makine" @@ -688,7 +730,7 @@ msgid "Display" msgstr "Görüntü" msgid "Input devices" -msgstr "Giriş aygıtları" +msgstr "Giriş cihazları" msgid "Sound" msgstr "Ses" @@ -700,7 +742,7 @@ msgid "Ports (COM & LPT)" msgstr "Portlar (COM & LPT)" msgid "Storage controllers" -msgstr "Depolama kontrolcüleri" +msgstr "Depolama denetleyicileri" msgid "Hard disks" msgstr "Hard diskler" @@ -717,11 +759,11 @@ msgstr "Diğer cihazlar" msgid "Click to capture mouse" msgstr "Farenin yakalanması için tıklayın" -msgid "Press %s to release mouse" -msgstr "Farenin bırakılması için %s tuşlarına basın" +msgid "Press %1 to release mouse" +msgstr "Farenin bırakılması için %1 tuşlarına basın" -msgid "Press %s or middle button to release mouse" -msgstr "Farenin bırakılması için %s tuşlarına veya tekerlek tuşuna basın" +msgid "Press %1 or middle button to release mouse" +msgstr "Farenin bırakılması için %1 veya tekerlek tuşuna basın" msgid "Bus" msgstr "Veri yolu" @@ -780,12 +822,39 @@ msgstr "4 eksenli, 4 düğmeli oyun kolu" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Hiçbiri" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Disket %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Disket %1 (%2): %3" + msgid "Advanced sector images" msgstr "Gelişmiş sektör imajları" @@ -816,6 +888,9 @@ msgstr "GhostPCL başlatılamadı" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&MO %1 (%2): %3" + msgid "MO images" msgstr "MO imajları" @@ -823,19 +898,19 @@ msgid "Welcome to 86Box!" msgstr "86Box'a hoşgeldiniz!" msgid "Internal device" -msgstr "Dahili cihazı" +msgstr "Dahili cihaz" msgid "Exit" -msgstr "Çıkış" +msgstr "Çıkış yap" msgid "No ROMs found" -msgstr "Hiçbir ROM imajı bulunamadı" +msgstr "Hiçbir ROM dosyası bulunamadı" msgid "Do you want to save the settings?" msgstr "Ayarları kaydetmek istediğinizden emin misiniz?" msgid "This will hard reset the emulated machine." -msgstr "Bu işlem makineyi zorla yeniden başlatacak." +msgstr "Bu işlem makineyi yeniden başlamaya zorlayacak." msgid "Save" msgstr "Kaydet" @@ -847,25 +922,22 @@ 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 "Bir eski bilgisayar emülatörü\n\nYapımcılar: 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\nSarah Walker, leilei, JohnElliott, greatpsycho, ve diğerlerinin önceki katkılarıyla birlikte.\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." +msgstr "Bir eski bilgisayar emülatörü\n\nYapımcılar: 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\nSarah Walker, leilei, JohnElliott, greatpsycho, ve diğerlerinin önceki katkılarıyla birlikte.\n\nGNU Genel Kamu Lisansı versiyon 2 veya sonrası altında yayınlanmıştır. Daha fazla bilgi için LICENSE kısmını gözden geçirin." msgid "Hardware not available" -msgstr "Donanım mevcut değil" +msgstr "Cihaz mevcut değil" -msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." -msgstr "%1 kurulu olduğundan ve libpcap uyumlu bir internet ağı kullandığınızdan emin olun." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "%1 kurulu olduğundan ve %1 uyumlu bir internet ağı kullandığınızdan emin olun." msgid "Invalid configuration" -msgstr "Geçersiz konfigürasyon" +msgstr "Geçersiz yapılandırma" msgid "%1 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 "%1 PostScript dosyalarının otomatik olarak PDF dosyalarına çevirilmesi için gereklidir.\n\nGenel PostScript yazıcısına gönderilen tüm dökümanlar PostScript (.ps) dosyaları olarak kaydedilecektir." +msgstr "%1 PostScript dosyalarının otomatik olarak PDF dosyasına çevirilmesi için gereklidir.\n\nGenel PostScript yazıcısına gönderilen tüm dökümanlar PostScript (.ps) dosyası olarak kaydedilecektir." -msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as Printer Command Language (.pcl) files." -msgstr "%1 PCL dosyalarının otomatik olarak PDF dosyalarına çevirilmesi için gereklidir.\n\nBu bulunmadığından dolayı genel PostScript yazıcısına gönderilen tüm dökümanlar Printer Command Language (.pcl) dosyası olarak kaydedilecektir." - -msgid "Entering fullscreen mode" -msgstr "Tam ekran moduna geçiş yapılıyor" +msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." +msgstr "%1 PCL dosyalarının otomatik olarak PDF dosyasına çevirilmesi için gereklidir.\n\nGenel PCL yazıcısına gönderilen tüm dökümanlar Printer Command Language (.pcl) dosyası olarak kaydedilecektir." msgid "Don't show this message again" msgstr "Bu mesajı bir daha gösterme" @@ -883,7 +955,7 @@ msgid "CD-ROM images" msgstr "CD-ROM imajları" msgid "%1 Device Configuration" -msgstr "%1 cihaz konfigürasyonu" +msgstr "%1 Cihaz Yapılandırması" msgid "Monitor in sleep mode" msgstr "Monitör uyku modunda" @@ -892,10 +964,10 @@ msgid "GLSL shaders" msgstr "GLSL gölgelendiricileri" msgid "You are loading an unsupported configuration" -msgstr "Desteklenmeyen bir konfigürasyon kullanıyorsunuz" +msgstr "Desteklenmeyen bir yapılandırma kullanıyorsunuz" 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 "Seçtiğiniz makineye uygun işlemci türü filtrelemesi bu emüle edilen makine için devre dışı bırakıldı.\n\nBu normalde makine ile uyumlu olmayan bir işlemci seçmenizi mümkün kılmaktadır. Ancak, bundan dolayı makinenin BIOS'u veya üzerinde kullanılan diğer yazılımlar ile uyumsuzluk sorunları yaşayabilirsiniz.\n\nBu filtrelemenin devre dışı bırakılması resmi olarak desteklenmemektedir ve açtığınız hata raporları geçersiz olarak kapatılabilir." +msgstr "Seçtiğiniz makineyle uygun işlemci filtresi bu yapılandırma için devre dışı bırakıldı.\n\nBu durum seçili makine ile uyumsuz bir işlemci kullanmanızı mümkün kılmaktadır. Ancak bundan dolayı makinenin BIOS'unda veya çalıştırılan diğer yazılımlarda uyumsuzluk sorunları meydana gelebilir.\n\nİşlemci filtresinin devre dışı bırakılması resmi olarak desteklenmemektedir ve bu esnada açtığınız hata raporları geçersiz sayılabilir." msgid "Continue" msgstr "Devam et" @@ -903,17 +975,23 @@ msgstr "Devam et" msgid "Cassette: %1" msgstr "Kaset: %1" +msgid "C&assette: %1" +msgstr "K&aset: %1" + msgid "Cassette images" msgstr "Kaset imajları" msgid "Cartridge %1: %2" msgstr "Kartuş %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Kar&tuş %1: %2" + msgid "Cartridge images" msgstr "Kartuş imajları" msgid "Resume execution" -msgstr "Çalıştırmaya devam et" +msgstr "Çalıştırmayı sürdür" msgid "Pause execution" msgstr "Çalıştırmayı duraklat" @@ -928,13 +1006,16 @@ msgid "Hard reset" msgstr "Makineyi yeniden başlat" msgid "ACPI shutdown" -msgstr "ACPI kapanma" +msgstr "Makineyi ACPI kullanarak kapat" + +msgid "ACP&I shutdown" +msgstr "Makineyi ACP&I kullanarak kapat" msgid "Hard disk (%1)" msgstr "Hard disk (%1)" msgid "MFM/RLL or ESDI CD-ROM drives never existed" -msgstr "MFM/RLL veya ESDI CD-ROM sürücüleri hiçbir zaman var olmamıştır" +msgstr "MFM/RLL veya ESDI CD-ROM sürücüleri hiçbir zaman kullanılmamıştır" msgid "Custom..." msgstr "Diğer..." @@ -943,13 +1024,13 @@ msgid "Custom (large)..." msgstr "Diğer (büyük)..." msgid "Add New Hard Disk" -msgstr "Yeni hard disk dosyası oluştur" +msgstr "Yeni Hard Disk İmajı Oluştur" msgid "Add Existing Hard Disk" -msgstr "Var olan bir hard disk dosyası ekle" +msgstr "Var Olan Hard Disk İmajı Ekleme" msgid "HDI disk images cannot be larger than 4 GB." -msgstr "HDI disk imajları 4 GB boyutundan daha büyük olamaz." +msgstr "HDI imajları 4 GB boyutundan daha büyük olamaz." msgid "Disk images cannot be larger than 127 GB." msgstr "Disk imajları 127 GB boyutundan daha büyük olamaz." @@ -964,10 +1045,10 @@ msgid "Unable to write file" msgstr "Dosyanın üzerine yazılamıyor" msgid "HDI or HDX images with a sector size other than 512 are not supported." -msgstr "512 dışında sektör boyutu olan HDI veya HDX imajları desteklenmemektedir." +msgstr "512 dışında sektör boyutu olan HDI ve HDX imajları desteklenmemektedir." msgid "Disk image file already exists" -msgstr "Bu disk imaj dosyası zaten mevcuttur" +msgstr "Bu imaj dosyası zaten mevcuttur" msgid "Please specify a valid file name." msgstr "Lütfen geçerli bir dosya ismi belirleyin." @@ -979,16 +1060,16 @@ msgid "Make sure the file exists and is readable." msgstr "Dosyanın var olduğuna ve okunabildiğine emin olun." msgid "Make sure the file is being saved to a writable directory." -msgstr "Dosyanın yazılabilir bir klasöre kaydedildiğinden emin olun." +msgstr "Dosyanın erişilebilir bir klasöre kaydedildiğinden emin olun." msgid "Disk image too large" msgstr "Disk imajı çok büyük" msgid "Remember to partition and format the newly-created drive." -msgstr "Yeni oluşturulan diskte bölümler oluşturmayı ve formatlamayı unutmayın." +msgstr "Yeni oluşturulan diskte bölümler oluşturmayı ve bu bölümleri biçimlendirmeyi unutmayın." msgid "The selected file will be overwritten. Are you sure you want to use it?" -msgstr "Seçili dosyanın üzerine yazılacaktır. Bunu yapmak istediğinizden emin misiniz?" +msgstr "Seçili dosyanın üzerine yazılacaktır. Bu dosyayı kullanmak istediğinizden emin misiniz?" msgid "Unsupported disk image" msgstr "Desteklenmeyen disk imajı" @@ -1009,13 +1090,13 @@ msgid "HDX image" msgstr "HDX imajı" msgid "Fixed-size VHD" -msgstr "Sabit-boyutlu VHD" +msgstr "Sabit boyutlu VHD" msgid "Dynamic-size VHD" -msgstr "Dinamik-boyutlu VHD" +msgstr "Dinamik boyutlu VHD" msgid "Differencing VHD" -msgstr "Farklandırılan VHD" +msgstr "Farklandıran VHD" msgid "(N/A)" msgstr "(yok)" @@ -1036,7 +1117,7 @@ msgid "Dynamic-size VHD (.vhd)" msgstr "Dinamik boyutlu VHD (.vhd)" msgid "Differencing VHD (.vhd)" -msgstr "Farklandırılan VHD (.vhd)" +msgstr "Farklandıran VHD (.vhd)" msgid "Large blocks (2 MB)" msgstr "Büyük bloklar (2 MB)" @@ -1051,13 +1132,13 @@ msgid "Select the parent VHD" msgstr "Ana VHD dosyasını seçin" 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 "Bu, farklandırılmış imaj dosyası oluşturulduktan sonra ana imaj dosyası üzerinde değişiklik yapıldığı anlamına geliyor olabilir.\n\nBu durum ayrıca imaj dosyaları kopyalandığında veya yerleri değiştirildiğinde veya imaj dosyalarını oluşturan programdaki bir hatadan dolayı da olmuş olabilir.\n\nZaman damgalarını düzeltmek ister misiniz?" +msgstr "Bu, farklandırmış imaj dosyası oluşturulduktan sonra ana imaj dosyasında bir değişiklik yapıldığı anlamına geliyor olabilir.\n\nBu durum ayrıca imaj dosyalarının kopyalanmasından, yerlerinin değiştirilmesinden veya dosyaları oluşturan programdaki bir hatadan dolayı da meydana gelmiş olabilir.\n\nZaman damgalarını düzeltmek ister misiniz?" msgid "Parent and child disk timestamps do not match" msgstr "Ana ve ek disklerin zaman damgaları uyuşmuyor" msgid "Could not fix VHD timestamp." -msgstr "VHD zaman damgası düzeltilemedi." +msgstr "VHD'nin zaman damgası düzeltilemedi." msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1150,16 +1231,16 @@ msgid "Perfect RPM" msgstr "Mükemmel RPM" msgid "1% below perfect RPM" -msgstr "mükemmel RPM değerinin 1% altı" +msgstr "Mükemmel RPM değerinin 1% altı" msgid "1.5% below perfect RPM" -msgstr "mükemmel RPM değerinin 1.5% altı" +msgstr "Mükemmel RPM değerinin 1.5% altı" msgid "2% below perfect RPM" -msgstr "mükemmel RPM değerinin 2% altı" +msgstr "Mükemmel RPM değerinin 2% altı" msgid "(System Default)" -msgstr "(Sistem varsayılanı)" +msgstr "(Sistem Varsayılanı)" msgid "Failed to initialize network driver" msgstr "Ağ sürücüsü başlatılamadı" @@ -1171,7 +1252,7 @@ msgid "Mouse sensitivity:" msgstr "Fare hassasiyeti:" msgid "Select media images from program working directory" -msgstr "Medya görüntülerini programın çalışma dizininden seç" +msgstr "Medya imajlarını programın çalışma dizininden seç" msgid "PIT mode:" msgstr "PIT modu:" @@ -1186,19 +1267,19 @@ msgid "Fast" msgstr "Hızlı" msgid "&Auto-pause on focus loss" -msgstr "Pencere &odağı kaybında otomatik olarak duraklat" +msgstr "Pencereye &odaklanmıyorken duraklat" msgid "WinBox is no longer supported" msgstr "WinBox artık desteklenmemektedir" msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." -msgstr "WinBox yöneticisinin geliştirilmesi 2022 yılında bakımcı eksikliği nedeniyle durduruldu. Çabalarımızı 86Box'ı daha da iyi hale getirmeye yönlendirdiğimiz için bu yöneticiyi artık desteklememe kararı aldık.\n\nArtık WinBox aracılığıyla güncellemeler sağlanmayacaktır ve onu 86Box'ın yeni sürümleriyle kullanmaya devam etmeniz halinde hatalarla karşılaşabilirsiniz. Bunun yanı sıra WinBox ile ilgili tüm hata raporları geçersiz olarak kapatılacaktır.\n\nKullanabileceğiniz diğer yöneticilerin listesi için 86box.net adresini ziyaret edebilirsiniz." +msgstr "WinBox yöneticisinin geliştirilmesi geliştirici eksikliği nedeniyle 2022 yılında durduruldu. 86Box'ı daha iyi hale getirmeye odaklanmak amacıyla bu yöneticiyi artık desteklememe kararı aldık.\n\nArtık WinBox aracılığıyla güncellemeler yayınlanmayacaktır ve bu yöneticiyi 86Box'ın yeni sürümleriyle kullanmanız halinde hatalarla karşılaşabilirsiniz. WinBox'ın kullanımıyla ilgili tüm hata raporları geçersiz sayılacaktır.\n\nKullanabileceğiniz diğer yöneticilerin bir listesi için lütfen 86box.net adresini ziyaret edin." msgid "Generate" msgstr "Oluştur" msgid "Joystick configuration" -msgstr "Oyun kolu yapılandırması" +msgstr "Oyun kolu seçenekleri" msgid "Device" msgstr "Cihaz" @@ -1215,41 +1296,41 @@ msgstr "MCA cihazları" msgid "List of MCA devices:" msgstr "MCA cihazlarının listesi:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Tablet aracı" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "Qt hakkında" +msgid "About &Qt" +msgstr "&Qt hakkında" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "MCA cihazları..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Birincil olmayan monitörleri göster" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Ekran görüntüsü klasörünü aç..." -msgid "Apply fullscreen stretch mode when maximized" -msgstr "Büyütüldüğünde tam ekran genişletme modu uygula" +msgid "Appl&y fullscreen stretch mode when maximized" +msgstr "Büyütüldüğünde tam ekran germe modunu uygula" -msgid "Cursor/Puck" -msgstr "İmleç/Puck" +msgid "&Cursor/Puck" +msgstr "&İmleç/Puck" -msgid "Pen" -msgstr "Kalem" +msgid "&Pen" +msgstr "&Kalem" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Ana bilgisayar CD/DVD sürücüsü (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Ana Sistemin CD/DVD Sürücüsü (%1:)" msgid "&Connected" msgstr "&Bağlı" -msgid "Clear image history" -msgstr "İmaj geçmişini temizleyin" +msgid "Clear image &history" +msgstr "İmaj geçmişini temizle" msgid "Create..." msgstr "Oluştur..." @@ -1303,16 +1384,16 @@ msgid "Error initializing OpenGL" msgstr "OpenGL başlatılırken hata oluştu" msgid "\nFalling back to software rendering." -msgstr "\nYazılım işleyicisine geri dönülüyor." +msgstr "\nYazılım derleyicisine geri dönülüyor." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Medya görüntüsü (CD-ROM, disket, vb.) seçme diyaloğu 86Box yapılandırma dosyasıyla aynı dizinde başlayacaktır. Bu ayar muhtemelen sadece macOS üzerinde bir fark meydana getirecektir.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Medya görüntüsü (CD-ROM, disket, vb.) seçme diyaloğu 86Box yapılandırma dosyasının bulunduğu dizinde başlayacaktır. Bu ayar muhtemelen sadece macOS üzerinde bir değişiklik meydana getirecektir.

" msgid "This machine might have been moved or copied." msgstr "Bu makine taşınmış veya kopyalanmış olabilir." msgid "In order to ensure proper networking functionality, 86Box needs to know if this machine was moved or copied.\n\nSelect \"I Copied It\" if you are not sure." -msgstr "Ağ bağlantısı özelliğinin doğru şekilde çalışmasını sağlamak amacıyla 86Box'ın bu makinenin taşındığını mı yoksa kopyalandığını mı bilmesi gerekmektedir.\n\nEğer bundan emin değilseniz \"Kopyalandı\" seçeneğini seçiniz." +msgstr "Ağ bağlantısı özelliğinin doğru bir şekilde çalışması için 86Box'ın bu makinenin başka bir konuma taşındığını mı yoksa kopyalandığını mı belirlemesi gerekmektedir.\n\nBundan emin değilseniz \"Kopyalandı\" seçeneğini seçin." msgid "I Moved It" msgstr "Taşındı" @@ -1321,7 +1402,7 @@ msgid "I Copied It" msgstr "Kopyalandı" msgid "86Box Monitor #" -msgstr "86Box monitör " +msgstr "86Box Monitör #" msgid "No MCA devices." msgstr "MCA cihazı yok." @@ -1330,16 +1411,16 @@ msgid "MiB" msgstr "MiB" msgid "Network Card #1" -msgstr "Ağ kartı 1" +msgstr "1. Ağ Kartı" msgid "Network Card #2" -msgstr "Ağ kartı 2" +msgstr "2. Ağ Kartı" msgid "Network Card #3" -msgstr "Ağ kartı 3" +msgstr "3. Ağ Kartı" msgid "Network Card #4" -msgstr "Ağ kartı 4" +msgstr "4. Ağ Kartı" msgid "Mode:" msgstr "Mod:" @@ -1351,79 +1432,151 @@ msgid "Adapter:" msgstr "Adaptör:" msgid "VDE Socket:" -msgstr "VDE soketi:" +msgstr "VDE Soketi:" msgid "86Box Unit Tester" -msgstr "86Box birim test cihazı" +msgstr "86Box Test Cihazı" msgid "Novell NetWare 2.x Key Card" -msgstr "Novell NetWare 2.x anahtar kartı" +msgstr "Novell NetWare 2.x Anahtar Kartı" msgid "Serial port passthrough 1" -msgstr "Seri port geçişi 1" +msgstr "1. Seri Port geçişi" msgid "Serial port passthrough 2" -msgstr "Seri port geçişi 2" +msgstr "2. Seri Port geçişi" msgid "Serial port passthrough 3" -msgstr "Seri port geçişi 3" +msgstr "3. Seri Port geçişi" msgid "Serial port passthrough 4" -msgstr "Seri port geçişi 4" +msgstr "4. Seri Port geçişi" -msgid "Renderer options..." -msgstr "İşleyici seçenekleri..." +msgid "Renderer &options..." +msgstr "Derleyici seçenekleri..." + +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" msgid "Logitech/Microsoft Bus Mouse" -msgstr "Logitech/Microsoft veri yolu bağlantılı fare" +msgstr "Logitech/Microsoft Bus Fare" msgid "Microsoft Bus Mouse (InPort)" -msgstr "Microsoft veri yolu bağlantılı fare (InPort)" +msgstr "Microsoft Bus Fare (InPort)" msgid "Mouse Systems Serial Mouse" -msgstr "Mouse Systems seri fare" +msgstr "Mouse Systems Seri Fare" + +msgid "Mouse Systems Bus Mouse" +msgstr "Mouse Systems Bus Fare" msgid "Microsoft Serial Mouse" -msgstr "Microsoft seri fare" +msgstr "Microsoft Seri Fare" + +msgid "Microsoft Serial BallPoint" +msgstr "" msgid "Logitech Serial Mouse" -msgstr "Logitech seri fare" +msgstr "Logitech Seri Fare" msgid "PS/2 Mouse" msgstr "PS/2 fare" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (seri)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" -msgstr "[COM] Standart Hayes uyumlu modem" +msgstr "[COM] Standart Hayes Uyumlu Modem" msgid "Roland MT-32 Emulation" -msgstr "Roland MT-32 emülasyonu" +msgstr "Roland MT-32 Emülasyonu" msgid "Roland MT-32 (New) Emulation" -msgstr "Roland MT-32 (yeni) emülasyonu" +msgstr "Roland MT-32 (Yeni) Emülasyonu" msgid "Roland CM-32L Emulation" -msgstr "Roland CM-32L emülasyonu" +msgstr "Roland CM-32L Emülasyonu" msgid "Roland CM-32LN Emulation" -msgstr "Roland CM-32LN emülasyonu" +msgstr "Roland CM-32LN Emülasyonu" msgid "OPL4-ML Daughterboard" -msgstr "OPL4-ML yankartı" +msgstr "OPL4-ML Yankartı" msgid "System MIDI" msgstr "Sistem MIDI'si" msgid "MIDI Input Device" -msgstr "MIDI giriş cihazı" +msgstr "MIDI Giriş Cihazı" -msgid "BIOS Address" -msgstr "BIOS adresi" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" +msgstr "BIOS Adresi" + +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" msgid "Enable BIOS extension ROM Writes" -msgstr "BIOS uzantı ROM'larına yazmayı etkinleştir" +msgstr "BIOS uzantı ROM yazımlarını etkinleştir" + +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" msgid "Address" msgstr "Adres" @@ -1432,7 +1585,19 @@ msgid "IRQ" msgstr "IRQ" msgid "BIOS Revision" -msgstr "BIOS sürümü" +msgstr "BIOS Sürümü" + +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" msgid "Translate 26 -> 17" msgstr "26 -> 17 olarak çevir" @@ -1444,91 +1609,106 @@ msgid "Enable backlight" msgstr "Arka ışığı etkinleştir" msgid "Invert colors" -msgstr "Renkleri ters çevir" +msgstr "Renkleri tersine çevir" msgid "BIOS size" msgstr "BIOS boyutu" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" -msgstr "C0000-C7FFF'yi UMB olarak eşleyin" +msgstr "C0000-C7FFF'yi UMB olarak eşle" msgid "Map C8000-CFFFF as UMB" -msgstr "C8000-CFFFF'yi UMB olarak eşleyin" +msgstr "C8000-CFFFF'yi UMB olarak eşle" msgid "Map D0000-D7FFF as UMB" -msgstr "D0000-D7FFF'yi UMB olarak eşleyin" +msgstr "D0000-D7FFF'yi UMB olarak eşle" msgid "Map D8000-DFFFF as UMB" -msgstr "D8000-DFFFF'yi UMB olarak eşleyin" +msgstr "D8000-DFFFF'yi UMB olarak eşle" msgid "Map E0000-E7FFF as UMB" -msgstr "E0000-E7FFF'yi UMB olarak eşleyin" +msgstr "E0000-E7FFF'yi UMB olarak eşle" msgid "Map E8000-EFFFF as UMB" -msgstr "E8000-EFFFF'yi UMB olarak eşleyin" +msgstr "E8000-EFFFF'yi UMB olarak eşle" msgid "JS9 Jumper (JIM)" -msgstr "JS9 jumper'ı (JIM)" +msgstr "JS9 Jumper'ı (JIM)" msgid "MIDI Output Device" -msgstr "MIDI çıkış cihazı" +msgstr "MIDI Çıkış Cihazı" msgid "MIDI Real time" -msgstr "Gerçek zamanlı MIDI" +msgstr "MIDI Gerçek Zamanı" msgid "MIDI Thru" -msgstr "MIDI geçişi" +msgstr "MIDI Geçişi" msgid "MIDI Clockout" -msgstr "MIDI saat çıkışı" +msgstr "MIDI Saat Çıkışı" msgid "SoundFont" msgstr "SoundFont" msgid "Output Gain" -msgstr "Çıkış ses düzeyi kazancı" +msgstr "Çıkış Sesi Artışı" msgid "Chorus" msgstr "Koro" msgid "Chorus Voices" -msgstr "Koro sesleri" +msgstr "Koro Sesleri" msgid "Chorus Level" msgstr "Koro seviyesi" msgid "Chorus Speed" -msgstr "Koro hızı" +msgstr "Koro Hızı" msgid "Chorus Depth" -msgstr "Koro derinliği" +msgstr "Koro Derinliği" msgid "Chorus Waveform" -msgstr "Koro dalga biçimi" +msgstr "Koro Dalga Biçimi" msgid "Reverb" msgstr "Yankı" msgid "Reverb Room Size" -msgstr "Yankı odası boyutu" +msgstr "Yankı Odası Boyutu" msgid "Reverb Damping" -msgstr "Yankı sönümleme" +msgstr "Yankı Sönümleme" msgid "Reverb Width" -msgstr "Yankı genişliği" +msgstr "Yankı Genişliği" msgid "Reverb Level" -msgstr "Yankı seviyesi" +msgstr "Yankı Seviyesi" msgid "Interpolation Method" -msgstr "İnterpolasyon yöntemi" +msgstr "İnterpolasyon Yöntemi" + +msgid "Dynamic Sample Loading" +msgstr "" msgid "Reverb Output Gain" -msgstr "Yankı çıkış ses düzeyi artışı" +msgstr "Yankı Çıkış Sesi Artışı" msgid "Reversed stereo" -msgstr "Tersine çevrilmiş stereo" +msgstr "Tersine çevirilmiş stereo" msgid "Nice ramp" msgstr "Güzel rampa" @@ -1540,34 +1720,34 @@ msgid "Buttons" msgstr "Düğmeler" msgid "Serial Port" -msgstr "Seri port" +msgstr "Seri Port" msgid "RTS toggle" -msgstr "RTS geçişi" +msgstr "RTS ayarı" msgid "Revision" msgstr "Sürüm" msgid "Controller" -msgstr "Kontrolcü" +msgstr "Denetleyici" msgid "Show Crosshair" -msgstr "Nişangahı göster" +msgstr "Nişangahı Göster" msgid "DMA" msgstr "DMA" msgid "MAC Address" -msgstr "MAC adresi" +msgstr "MAC Adresi" msgid "MAC Address OUI" -msgstr "MAC adresinin OUI'si" +msgstr "MAC Adresinin OUI'ı" msgid "Enable BIOS" -msgstr "BIOS'u etkinleştir" +msgstr "BIOS'u Etkinleştir" msgid "Baud Rate" -msgstr "Baud hızı" +msgstr "Baud Hızı" msgid "TCP/IP listening port" msgstr "TCP/IP dinleme portu" @@ -1579,37 +1759,43 @@ msgid "Telnet emulation" msgstr "Telnet emülasyonu" msgid "RAM Address" -msgstr "RAM adresi" +msgstr "Bellek (RAM) Adresi" msgid "RAM size" -msgstr "RAM boyutu" +msgstr "Bellek (RAM) Boyutu" msgid "Initial RAM size" -msgstr "İlk RAM boyutu" +msgstr "İlk Bellek (RAM) boyutu" msgid "Serial Number" -msgstr "Seri numarası" +msgstr "Seri Numarası" msgid "Host ID" -msgstr "Ana bilgisayar kimliği" +msgstr "Ana sistemin kimliği" msgid "FDC Address" -msgstr "FDC adresi" +msgstr "FDC Adresi" msgid "MPU-401 Address" -msgstr "MPU-401 adresi" +msgstr "MPU-401 Adresi" msgid "MPU-401 IRQ" msgstr "MPU-401 IRQ" msgid "Receive MIDI input" -msgstr "MIDI girişi al" +msgstr "MIDI girişini dinle" msgid "Low DMA" msgstr "Düşük DMA" msgid "Enable Game port" -msgstr "Gameport girişini etkinleştir" +msgstr "Gameport'ı etkinleştir" + +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" msgid "Surround module" msgstr "Surround modülü" @@ -1623,6 +1809,9 @@ msgstr "CODEC kurulumunda CODEC kesmesini yükselt (bazı sürücüler tarafınd msgid "SB Address" msgstr "SB adresi" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "WSS IRQ" @@ -1660,7 +1849,7 @@ msgid "EMU8000 Address" msgstr "EMU8000 adresi" msgid "IDE Controller" -msgstr "IDE Kontrolcüsü" +msgstr "IDE Denetleyicisi" msgid "Codec" msgstr "Codec" @@ -1707,9 +1896,15 @@ msgstr "RAMDAC türü" msgid "Blend" msgstr "Karışım" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Bilineer filtreleme" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Dithering" @@ -1726,13 +1921,13 @@ msgid "Texture memory size" msgstr "Doku bellek boyutu" msgid "Dither subtraction" -msgstr "Dither çıkarma" +msgstr "Dither çıkarışı" msgid "Screen Filter" msgstr "Ekran filtresi" msgid "Render threads" -msgstr "İşleme için iş parçacığı sayısı" +msgstr "Derleme için iş parçacığı sayısı" msgid "SLI" msgstr "SLI" @@ -1752,6 +1947,33 @@ msgstr "Transfer hızı" msgid "EMS mode" msgstr "EMS modu" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "> 2 MB için adres" @@ -1770,11 +1992,11 @@ msgstr "Her zaman seçilen hızda" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "BIOS ayarı + Kısayol tuşları (POST sırasında kapalı)" -msgid "64 kB starting from F0000" +msgid "64 KB starting from F0000" msgstr "F0000'dan başlayarak 64 KB" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "E0000'dan başlayarak 128 kB (adres MSB ters çevrilmiş, önce son 64KB)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "E0000'dan başlayarak 128 KB (adresin MSB'si ters çevirilmiş, önce sondaki 64 KB)" msgid "Sine" msgstr "Sinüs" @@ -1792,10 +2014,10 @@ msgid "7th Order" msgstr "7. sıra" msgid "Non-timed (original)" -msgstr "Zamanlayıcı olmadan (orijinal)" +msgstr "Zamanlanmamış (orijinal)" msgid "45 Hz (JMP2 not populated)" -msgstr "45 Hz (JMP2'de jumper yok)" +msgstr "45 Hz (JMP2 kullanılmadan)" msgid "Two" msgstr "İki" @@ -1807,16 +2029,16 @@ msgid "Wheel" msgstr "Tekerlek" msgid "Five + Wheel" -msgstr "Beş + tekerlek" +msgstr "Beş +Tekerlek" msgid "Five + 2 Wheels" msgstr "" msgid "A3 - SMT2 Serial / SMT3(R)V" -msgstr "A3 - SMT2 seri / SMT3(R)V" +msgstr "A3 - SMT2 Seri / SMT3(R)V" msgid "Q1 - SMT3(R) Serial" -msgstr "Q1 - SMT3(R) seri" +msgstr "Q1 - SMT3(R) Seri" msgid "8 KB" msgstr "8 KB" @@ -1831,7 +2053,7 @@ msgid "64 KB" msgstr "64 KB" msgid "Disable BIOS" -msgstr "BIOS'u devre dışı bırak" +msgstr "BIOS'u Devre Dışı Bırak" msgid "512 KB" msgstr "512 KB" @@ -1882,25 +2104,25 @@ msgid "New" msgstr "Yeni" msgid "Color (generic)" -msgstr "Renk (sıradan)" +msgstr "Çok Renkli (genel)" msgid "Green Monochrome" -msgstr "Yeşil monokrom" +msgstr "Yeşil Renkli" msgid "Amber Monochrome" -msgstr "Kehribar monokrom" +msgstr "Kehribar Renkli" msgid "Gray Monochrome" -msgstr "Gri monokrom" +msgstr "Gri Renkli" msgid "Color (no brown)" -msgstr "Renk (kahverengi yok)" +msgstr "Çok Renkli (kahverengi yok)" msgid "Color (IBM 5153)" -msgstr "Renkli (IBM 5153)" +msgstr "Çok Renkli (IBM 5153)" msgid "Simple doubling" -msgstr "Basit ikiye katlama" +msgstr "Basit katlama" msgid "sRGB interpolation" msgstr "sRGB interpolasyonu" @@ -1908,29 +2130,38 @@ msgstr "sRGB interpolasyonu" msgid "Linear interpolation" msgstr "Doğrusal interpolasyon" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" msgid "Monochrome (5151/MDA) (white)" -msgstr "Monokrom (5151/MDA) (beyaz)" +msgstr "Tek Renkli (5151/MDA) (beyaz)" msgid "Monochrome (5151/MDA) (green)" -msgstr "Monokrom (5151/MDA) (yeşil)" +msgstr "Tek Renkli (5151/MDA) (yeşil)" msgid "Monochrome (5151/MDA) (amber)" -msgstr "Monokrom (5151/MDA) (kehribar)" +msgstr "Tek Renkli (5151/MDA) (kehribar)" msgid "Color 40x25 (5153/CGA)" -msgstr "Renkli 40x25 (5153/CGA)" +msgstr "Çok Renkli 40x25 (5153/CGA)" msgid "Color 80x25 (5153/CGA)" -msgstr "Renkli 80x25 (5153/CGA)" +msgstr "Çok Renkli 80x25 (5153/CGA)" msgid "Enhanced Color - Normal Mode (5154/ECD)" -msgstr "Geliştirilmiş renkli - Normal mod (5154/ECD)" +msgstr "Gelişmiş Renkli - Normal Mod (5154/ECD)" msgid "Enhanced Color - Enhanced Mode (5154/ECD)" -msgstr "Geliştirilmiş renkli - Geliştirilmiş mod (5154/ECD)" +msgstr "Gelişmiş Renkli - Gelişmiş Mod (5154/ECD)" msgid "Green" msgstr "Yeşil" @@ -1941,6 +2172,9 @@ msgstr "Kehribar" msgid "Gray" msgstr "Gri" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Renk" @@ -1954,16 +2188,22 @@ msgid "Other languages" msgstr "Diğer diller" msgid "Bochs latest" -msgstr "Bochs en son sürümü" +msgstr "Bochs'un en son sürümü" + +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" msgid "Mono Non-Interlaced" -msgstr "Monokrom (geçmeli tarama yok)" +msgstr "Tek Renkli (Geçiş Taramasız)" msgid "Color Interlaced" -msgstr "Renkli (geçmeli tarama var)" +msgstr "Çok Renkli (Geçiş Taramalı)" msgid "Color Non-Interlaced" -msgstr "Renkli (geçmeli tarama yok)" +msgstr "Çok Renkli (Geçiş Taramasız)" msgid "3Dfx Voodoo Graphics" msgstr "3Dfx Voodoo Grafikleri" @@ -1996,31 +2236,31 @@ msgid "Stereo LPT DAC" msgstr "Stereo LPT DAC" msgid "Generic Text Printer" -msgstr "Sıradan metin yazıcı" +msgstr "Genel Metin Yazıcı" msgid "Generic ESC/P Dot-Matrix Printer" -msgstr "Sıradan ESC/P Dot Matrix yazıcı" +msgstr "Genel ESC/P Dot-Matrix Yazıcı" msgid "Generic PostScript Printer" -msgstr "Sıradan PostScript yazıcı" +msgstr "Genel PostScript Yazıcı" msgid "Generic PCL5e Printer" -msgstr "Sıradan PCL5e yazıcı" +msgstr "Genel PCL5e Yazıcı" msgid "Parallel Line Internet Protocol" msgstr "Paralel Hat İnternet Protokolü" msgid "Protection Dongle for Savage Quest" -msgstr "Savage Quest için koruma dongle'ı" +msgstr "Savage Quest için Koruma Kilidi" msgid "Serial Passthrough Device" -msgstr "Seri port geçiş cihazı" +msgstr "Seri Geçiş Cihazı" msgid "Passthrough Mode" -msgstr "Geçişli mod" +msgstr "Geçiş Modu" msgid "Host Serial Device" -msgstr "Ana bilgisayar seri cihazı" +msgstr "Ana Sistemdeki Seri Cihaz" msgid "Name of pipe" msgstr "Boru adı" @@ -2032,16 +2272,19 @@ msgid "Stop bits" msgstr "Dur bitleri" msgid "Baud Rate of Passthrough" -msgstr "Geçiş Baud hızı" +msgstr "Geçişin Baud Hızı" msgid "Named Pipe (Server)" -msgstr "Adlandırılmış boru (Sunucu)" +msgstr "Adlandırılmış Boru (Sunucu)" + +msgid "Named Pipe (Client)" +msgstr "" msgid "Host Serial Passthrough" -msgstr "Ana bilgisayar seri port geçişi" +msgstr "Ana Sistem Seri Geçişi" msgid "E&ject %1" -msgstr "%1 diskini &çıkar" +msgstr "%1 imajını &çıkar" msgid "&Unmute" msgstr "&Sesi aç" @@ -2050,31 +2293,31 @@ msgid "Softfloat FPU" msgstr "Softfloat FPU" msgid "High performance impact" -msgstr "Ciddi performans düşüklüğüne neden olabilir" +msgstr "Ciddi performans azalışına neden olabilir" msgid "[Generic] RAM Disk (max. speed)" -msgstr "[Generic] RAM Disk (maks. hız)" +msgstr "[Genel] RAM Disk (maks. hız)" msgid "[Generic] 1989 (3500 RPM)" -msgstr "" +msgstr "[Genel] 1989 (3500 RPM)" msgid "[Generic] 1992 (3600 RPM)" -msgstr "" +msgstr "[Genel] 1992 (3600 RPM)" msgid "[Generic] 1994 (4500 RPM)" -msgstr "" +msgstr "[Genel] 1994 (4500 RPM)" msgid "[Generic] 1996 (5400 RPM)" -msgstr "" +msgstr "[Genel] 1996 (5400 RPM)" msgid "[Generic] 1997 (5400 RPM)" -msgstr "" +msgstr "[Genel] 1997 (5400 RPM)" msgid "[Generic] 1998 (5400 RPM)" -msgstr "" +msgstr "[Genel] 1998 (5400 RPM)" msgid "[Generic] 2000 (7200 RPM)" -msgstr "" +msgstr "[Genel] 2000 (7200 RPM)" msgid "IBM 8514/A clone (ISA)" msgstr "IBM 8514/A klonu (ISA)" @@ -2082,77 +2325,164 @@ msgstr "IBM 8514/A klonu (ISA)" msgid "Vendor" msgstr "Üretici" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" -msgstr "Sıradan PC/XT bellek artırma" +msgstr "Genel PC/XT Bellek Artırıcı" msgid "Generic PC/AT Memory Expansion" -msgstr "Sıradan PC/AT bellek artırma" +msgstr "Genel PC/AT Bellek Artırıcı" msgid "Unable to find Dot-Matrix fonts" -msgstr "Dot Matrix yazı tipleri bulunamıyor" +msgstr "Dot-Matrix yazı tipleri bulunamıyor" msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for the emulation of the Generic ESC/P Dot-Matrix Printer." -msgstr "Sıradan ESC/P Dot Matrix Yazıcının emülasyonu için \"roms/printer/fonts\" dizinindeki TrueType yazı tipleri gereklidir." +msgstr "Genel ESC/P Dot-Matrix yazıcısının emülasyonu için \"roms/printer/fonts\" dizininde TrueType yazı tiplerinin bulunması gereklidir." msgid "Inhibit multimedia keys" -msgstr "" +msgstr "Multimedya tuşlarını engelle" msgid "Ask for confirmation before saving settings" -msgstr "" +msgstr "Ayarları kaydetmeden once onay için sor" msgid "Ask for confirmation before hard resetting" -msgstr "" +msgstr "Yeniden başlamaya zorlamadan önce onay için sor" msgid "Ask for confirmation before quitting" -msgstr "" - -msgid "Display hotkey message when entering full-screen mode" -msgstr "" +msgstr "Çıkış yapmadan once onay için sor" msgid "Options" -msgstr "" +msgstr "Seçenekler" msgid "Model" -msgstr "" +msgstr "Model" msgid "Model:" -msgstr "" +msgstr "Model:" msgid "Failed to initialize Vulkan renderer." -msgstr "" +msgstr "Vulkan derleyicisi başlatılamadı." msgid "GLSL Error" -msgstr "" +msgstr "GLSL Hatası" msgid "Could not load shader: %1" -msgstr "" +msgstr "%1 gölgelendiricisi yüklenemedi" msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "" +msgstr "OpenGL sürüm 3.0 veya daha yükseği gereklidir. Şu anki GLSL sürümü %1.%2" msgid "Could not load texture: %1" -msgstr "" +msgstr "%1 dokusu yüklenemedi" msgid "Could not compile shader:\n\n%1" -msgstr "" +msgstr "%1 gölgelendiricisi derlenemedi" msgid "Program not linked:\n\n%1" -msgstr "" +msgstr "%1 programı bağlanamadı" msgid "Shader Manager" -msgstr "" +msgstr "Gölgelendirici Yöneticisi" msgid "Shader Configuration" -msgstr "" +msgstr "Gölgelendirici Seçenekleri" msgid "Add" -msgstr "" +msgstr "Ekle" msgid "Move up" -msgstr "" +msgstr "Yukarı taşı" msgid "Move down" -msgstr "" +msgstr "Aşağı taşı" msgid "Could not load file %1" +msgstr "%1 dosyası yüklenemedi" + +msgid "Key Bindings:" msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Hard Disk Denetleyicisi:" + +#~ msgid "ZIP drives:" +#~ msgstr "ZIP sürücüleri:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "ZIP imajları" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index db9b73491..8303ca2c2 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "&Пауза" -msgid "E&xit..." -msgstr "&Вихід..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "&Вихід" msgid "&View" msgstr "&Вигляд" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "&Вказати розміри..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "Метод фільтрації" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "&Тип екрана VGA" msgid "RGB &Color" msgstr "RGB &кольоровий" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "&RGB монохромний" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "&Бурштиновий відтінок" @@ -384,6 +393,15 @@ msgstr "Увімкнути (UTC)" msgid "Dynamic Recompiler" msgstr "Динамічний рекомпілятор" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Відеокарта:" @@ -399,6 +417,9 @@ msgstr "Прискорювач IBM 8514/A" msgid "XGA Graphics" msgstr "Прискорювач XGA" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Миша:" @@ -498,18 +519,21 @@ msgstr "Паралельний порт LPT3" msgid "Parallel port 4" msgstr "Паралельний порт LPT4" -msgid "HD Controller:" -msgstr "Контролер HD:" - msgid "FD Controller:" msgstr "Контролер FD:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "Третинний IDE контролер" msgid "Quaternary IDE Controller" msgstr "Четвертинний IDE контролер" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Касета" msgid "Hard disks:" msgstr "Жорсткі диски:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "&Створити..." @@ -588,8 +615,8 @@ msgstr "Дисководи CD-ROM:" msgid "MO drives:" msgstr "Магнітооптичні дисководи:" -msgid "ZIP drives:" -msgstr "ZIP дисководи:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA RTC:" msgid "ISA Memory Expansion" msgstr "Карта розширення пам'яті (ISA)" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Карта 1:" @@ -612,6 +642,15 @@ msgstr "Карта 3:" msgid "Card 4:" msgstr "Карта 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "Пристрій ISABugger" @@ -630,17 +669,20 @@ msgstr "Непереробна помилка" msgid " - PAUSED" msgstr " - ПРИЗУПИНЕННЯ" -msgid "Press %s to return to windowed mode." -msgstr "Натисніть %s для повернення у віконний режим." - msgid "Speed" msgstr "Швидкість" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "Образи ZIP" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "86Box не зміг знайти жодного відповідного для використання файлу з ПЗУ.\n\nБудь ласка завантажте набір ПЗУ і витягніть його в каталог \"roms\"." @@ -717,11 +759,11 @@ msgstr "Інша периферія" msgid "Click to capture mouse" msgstr "Клацніть мишею для захвату курсора" -msgid "Press %s to release mouse" -msgstr "Натисніть %s, щоб звільнити курсор" +msgid "Press %1 to release mouse" +msgstr "Натисніть %1, щоб звільнити курсор" -msgid "Press %s or middle button to release mouse" -msgstr "Натисніть %s або середню кнопку миші, щоб звільнити курсор" +msgid "Press %1 or middle button to release mouse" +msgstr "Натисніть %1 або середню кнопку миші, щоб звільнити курсор" msgid "Bus" msgstr "Шина" @@ -780,12 +822,39 @@ msgstr "4-осьовий, 4-кнопковий джойстик" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Система управління польотом Thrustmaster" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Ні" @@ -795,6 +864,9 @@ msgstr "%1 МБ (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Дисковод %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "&Дисковод %1 (%2): %3" + msgid "Advanced sector images" msgstr "Розширені образи секторів" @@ -816,6 +888,9 @@ msgstr "Неможливо ініціалізувати GhostPCL" msgid "MO %1 (%2): %3" msgstr "Магнітооптичний %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "&Магнітооптичний %1 (%2): %3" + msgid "MO images" msgstr "Образи магнітооптичних дисків" @@ -852,8 +927,8 @@ msgstr "Емулятор старих комп'ютерів\n\nАвтори: Mir msgid "Hardware not available" msgstr "Обладнання недоступне" -msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." -msgstr "Переконайтесь, що %1 встановлений і ваше мережеве з'єднання, сумісне з libpcap." +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Переконайтесь, що %1 встановлений і ваше мережеве з'єднання, сумісне з %1." msgid "Invalid configuration" msgstr "Неприпустима конфігурація" @@ -864,9 +939,6 @@ msgstr "%1 потрібно для автоматичного перетворе msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 потрібно для автоматичного перетворення файлів PCL в PDF.\n\nВсі документи, відправлені на загальний принтер PCL, будуть збережені у вигляді файлів Printer Command Language (.ps)." -msgid "Entering fullscreen mode" -msgstr "Вхід у повноекранний режим" - msgid "Don't show this message again" msgstr "Більше не показувати це повідомлення" @@ -903,12 +975,18 @@ msgstr "Продовжити" msgid "Cassette: %1" msgstr "Касета: %1" +msgid "C&assette: %1" +msgstr "К&асета: %1" + msgid "Cassette images" msgstr "Образи касет" msgid "Cartridge %1: %2" msgstr "Картридж %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Кар&тридж %1: %2" + msgid "Cartridge images" msgstr "Образи картриджів" @@ -930,6 +1008,9 @@ msgstr "Холодне перезавантаження" msgid "ACPI shutdown" msgstr "Сигнал завершення ACPI" +msgid "ACP&I shutdown" +msgstr "Сигнал завершення ACP&I" + msgid "Hard disk (%1)" msgstr "Жорсткий диск (%1)" @@ -1051,7 +1132,10 @@ 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 "Тимчасові мітки батьківського та дочірнього дисків не співпадають" @@ -1215,40 +1299,40 @@ msgstr "Пристрої MCA" msgid "List of MCA devices:" msgstr "Список пристроїв MCA:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Інструмент для планшета" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "Про Qt" +msgid "About &Qt" +msgstr "Про &Qt" -msgid "MCA devices..." -msgstr "Пристрої MCA..." +msgid "&MCA devices..." +msgstr "Пристрої &MCA..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Показати неосновні монітори" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Відкрийте папку скріншотів..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Застосовувати розстягування у повноекранному режимі у максимізованому стані" -msgid "Cursor/Puck" -msgstr "Курсор/шайба" +msgid "&Cursor/Puck" +msgstr "&Курсор/шайба" -msgid "Pen" -msgstr "Ручка" +msgid "&Pen" +msgstr "&Ручка" -msgid "Host CD/DVD Drive (%1:)" -msgstr "CD/DVD привід хоста (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "CD/DVD &привід хоста (%1:)" msgid "&Connected" msgstr "&Підключено" -msgid "Clear image history" +msgid "Clear image &history" msgstr "Очистити історію образів" msgid "Create..." @@ -1305,8 +1389,8 @@ msgstr "Помилка ініціалізації OpenGL" msgid "\nFalling back to software rendering." msgstr "\nПовернення до програмного рендерингу." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>При виборі медіа-образів (CD-ROM, дискета і т.д.) діалогове вікно буде відкриватися в тому ж каталозі, що і файл конфігурації 86Box. Цей параметр, швидше за все, матиме значення лише на macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

При виборі медіа-образів (CD-ROM, дискета і т.д.) діалогове вікно буде відкриватися в тому ж каталозі, що і файл конфігурації 86Box. Цей параметр, швидше за все, матиме значення лише на macOS.

" msgid "This machine might have been moved or copied." msgstr "Цю машину могли перемістити або скопіювати." @@ -1371,9 +1455,27 @@ msgstr "Пропуск послідовного порту 3" msgid "Serial port passthrough 4" msgstr "Пропуск послідовного порту 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Параметри рендерингу..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Шинна миша Logitech/Microsoft" @@ -1383,18 +1485,30 @@ msgstr "Шинна миша Microsoft (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Послідовна миша Mouse Systems" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Послідовна миша Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Послідовна миша Logitech" msgid "PS/2 Mouse" msgstr "Миша PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (послідовна)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Стандартний модем, сумісний зі стандартом Hayes" @@ -1419,12 +1533,54 @@ msgstr "MIDI системи" msgid "MIDI Input Device" msgstr "Пристрій введення MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "Адреса BIOS" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "Увімкнути розширення BIOS Записи в ПЗУ" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Адреса" @@ -1434,6 +1590,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "Ревізія BIOS" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Перекладіть 26 -> 17" @@ -1449,6 +1617,18 @@ msgstr "Інвертувати кольори" msgid "BIOS size" msgstr "Розмір BIOS" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "Зіставлення C0000-C7FFF як UMB" @@ -1524,6 +1704,9 @@ msgstr "Рівень реверберації" msgid "Interpolation Method" msgstr "Метод інтерполяції" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Посилення виходу реверберації" @@ -1611,6 +1794,12 @@ msgstr "Низький рівень DMA" msgid "Enable Game port" msgstr "Увімкнути ігровий порт" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Модуль об'ємного звучання" @@ -1623,6 +1812,9 @@ msgstr "Піднімати переривання CODEC під час встан msgid "SB Address" msgstr "Адреса SB" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "IRQ WSS" @@ -1707,9 +1899,15 @@ msgstr "Тип RAMDAC" msgid "Blend" msgstr "Суміш" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Білінійна фільтрація" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Дизеринг" @@ -1752,6 +1950,33 @@ msgstr "Швидкість передачі даних" msgid "EMS mode" msgstr "Режим EMS" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Адреса для > 2 МБ" @@ -1770,11 +1995,11 @@ msgstr "Завжди на обраній швидкості" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Налаштування BIOS + Гарячі клавіші (вимкнено під час POST)" -msgid "64 kB starting from F0000" -msgstr "64 кБ, починаючи з F0000" +msgid "64 KB starting from F0000" +msgstr "64 KБ, починаючи з F0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 кБ, починаючи з E0000 (адреса MSB інвертована, останні 64 кБ першими)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KБ, починаючи з E0000 (адреса MSB інвертована, останні 64 KБ першими)" msgid "Sine" msgstr "Синусоїдальна" @@ -1908,6 +2133,15 @@ msgstr "sRGB інтерполяція" msgid "Linear interpolation" msgstr "Лінійна інтерполяція" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 КБ" @@ -1941,6 +2175,9 @@ msgstr "Бурштиновий" msgid "Gray" msgstr "Сірий" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Кольоровий" @@ -1956,6 +2193,12 @@ msgstr "Інші мови" msgid "Bochs latest" msgstr "Bochs останній" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Монохромний неінтерлейсний" @@ -2037,6 +2280,9 @@ msgstr "Швидкість передачі даних пропуску" msgid "Named Pipe (Server)" msgstr "Іменований пайп (сервер)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "Пропуск послідовного порту хоста" @@ -2112,9 +2358,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2162,3 +2405,87 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Контролер HD:" + +#~ msgid "ZIP drives:" +#~ msgstr "ZIP дисководи:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "Образи ZIP" diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index e21466a18..a8fc098c2 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+&Esc" msgid "&Pause" msgstr "Tạm &dừng" -msgid "E&xit..." -msgstr "Th&oát..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "Th&oát" msgid "&View" msgstr "&Xem" @@ -60,7 +63,7 @@ msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" -msgid "Specify dimensions..." +msgid "Specify &dimensions..." msgstr "Tự nhập độ &phân giải..." msgid "F&orce 4:3 display ratio" @@ -99,7 +102,7 @@ msgstr "&7x" msgid "&8x" msgstr "&8x" -msgid "Filter method" +msgid "Fi<er method" msgstr "&Bộ lọc hình ảnh" msgid "&Nearest" @@ -144,9 +147,15 @@ msgstr "L&oại màn VGA" msgid "RGB &Color" msgstr "Màu R&GB" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "Thang xám RG&B" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "Màn hình vàng hổ phách (amber)" @@ -384,6 +393,15 @@ msgstr "Bật (UTC)" msgid "Dynamic Recompiler" msgstr "Bộ tái biên dịch động (Dynamic Recompiler)" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "Video:" @@ -399,6 +417,9 @@ msgstr "Đồ họa IBM 8514/A" msgid "XGA Graphics" msgstr "Đồ họa XGA" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "Chuột:" @@ -498,18 +519,21 @@ msgstr "Cổng parallel 3" msgid "Parallel port 4" msgstr "Cổng parallel 4" -msgid "HD Controller:" -msgstr "Bộ điều khiển ổ cứng:" - msgid "FD Controller:" msgstr "Bộ điều khiển ổ mềm:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "Bộ điều khiển IDE thứ ba" msgid "Quaternary IDE Controller" msgstr "Bộ điều khiển IDE thứ tư" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "Cassette" msgid "Hard disks:" msgstr "Đĩa cứng:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "Tạ&o mới..." @@ -588,8 +615,8 @@ msgstr "Ổ đĩa CD-ROM:" msgid "MO drives:" msgstr "Ổ đĩa MO:" -msgid "ZIP drives:" -msgstr "Ổ đĩa ZIP:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA RTC:" msgid "ISA Memory Expansion" msgstr "Mở rộng bộ nhớ qua ISA" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "Thẻ 1:" @@ -612,6 +642,15 @@ msgstr "Thẻ 3:" msgid "Card 4:" msgstr "Thẻ 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "Thiết bị ISABugger" @@ -630,17 +669,20 @@ msgstr "Lỗi nghiêm trọng" msgid " - PAUSED" msgstr " - TẠM DỪNG" -msgid "Press %s to return to windowed mode." -msgstr "Bấm %s để quay lại chế độ cửa sổ." - msgid "Speed" msgstr "Vận tốc" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "Ảnh đĩa ZIP" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." msgstr "86Box không tìm được bản ROM nào.\n\nVui lòng tải về bộ ROM và trích xuất về thư mục \"roms\"." @@ -717,11 +759,11 @@ msgstr "Thiết bị ngoại vi khác" msgid "Click to capture mouse" msgstr "Nhấp vào khung hình để 'nhốt' chuột vào" -msgid "Press %s to release mouse" -msgstr "Nhấn %s để thả chuột" +msgid "Press %1 to release mouse" +msgstr "Nhấn %1 để thả chuột" -msgid "Press %s or middle button to release mouse" -msgstr "Nhấn %s hoặc nhấp chuột giữa để thả chuột" +msgid "Press %1 or middle button to release mouse" +msgstr "Nhấn %1 hoặc nhấp chuột giữa để thả chuột" msgid "Bus" msgstr "Bus" @@ -780,12 +822,39 @@ msgstr "Cần điều khiển bốn trục, bốn nút" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "Không có" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "Đĩa mềm %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "Đĩa &mềm %1 (%2): %3" + msgid "Advanced sector images" msgstr "Ảnh (đĩa) sector nâng cao" @@ -816,6 +888,9 @@ msgstr "Không thể khởi tạo GhostPCL" msgid "MO %1 (%2): %3" msgstr "MO %1 (%2): %3" +msgid "M&O %1 (%2): %3" +msgstr "M&O %1 (%2): %3" + msgid "MO images" msgstr "Ảnh đĩa MO" @@ -864,9 +939,6 @@ msgstr "Cần có %1 để tự động chuyển đổi file PostScript qua PDF. msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "Cần có %1 để tự động chuyển đổi file PCL qua PDF.\n\nMọi tài liệu được đưa qua máy in generic PCL sẽ lưu ở dạng Printer Command Language (.pcl)." -msgid "Entering fullscreen mode" -msgstr "Đang tiến vào chế độ toàn màn hình" - msgid "Don't show this message again" msgstr "Không hiện thông báo này nữa" @@ -903,12 +975,18 @@ msgstr "Tiếp tục" msgid "Cassette: %1" msgstr "Cassette: %1" +msgid "C&assette: %1" +msgstr "C&assette: %1" + msgid "Cassette images" msgstr "Ảnh đĩa Cassette" msgid "Cartridge %1: %2" msgstr "Băng cartridge %1: %2" +msgid "Car&tridge %1: %2" +msgstr "Băng car&tridge %1: %2" + msgid "Cartridge images" msgstr "Ảnh đĩa băng cartridge" @@ -930,6 +1008,9 @@ msgstr "Buộc khởi động lại" msgid "ACPI shutdown" msgstr "Tắt máy theo ACPI" +msgid "ACP&I shutdown" +msgstr "Tắt máy theo ACP&I" + msgid "Hard disk (%1)" msgstr "Ổ cứng (%1)" @@ -1215,40 +1296,40 @@ msgstr "Thiết bị MCA" msgid "List of MCA devices:" msgstr "Danh sách các thiết bị MCA:" -msgid "Tablet tool" +msgid "&Tablet tool" msgstr "Công cụ bảng nhập liệu" msgid "Qt (OpenGL &ES)" msgstr "QT (OpenGL &ES)" -msgid "About Qt" -msgstr "Về qt" +msgid "About &Qt" +msgstr "Về &qt" -msgid "MCA devices..." +msgid "&MCA devices..." msgstr "Thiết bị MCA..." -msgid "Show non-primary monitors" +msgid "Show non-&primary monitors" msgstr "Hiển thị các màn hình phụ" -msgid "Open screenshots folder..." +msgid "Open screenshots &folder..." msgstr "Mở thư mục ảnh chụp màn hình..." -msgid "Apply fullscreen stretch mode when maximized" +msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Co giãn toàn màn hình khi cực đại hóa cửa sổ" -msgid "Cursor/Puck" -msgstr "Con trỏ/puck" +msgid "&Cursor/Puck" +msgstr "&Con trỏ/puck" -msgid "Pen" -msgstr "Bút" +msgid "&Pen" +msgstr "&Bút" -msgid "Host CD/DVD Drive (%1:)" -msgstr "Máy chủ CD/DVD ổ đĩa (%1 :)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "&Máy chủ CD/DVD ổ đĩa (%1 :)" msgid "&Connected" msgstr "&Đã kết nối" -msgid "Clear image history" +msgid "Clear image &history" msgstr "Xóa lịch sử ảnh đĩa" msgid "Create..." @@ -1305,8 +1386,8 @@ msgstr "Lỗi khởi tạo OpenGL" msgid "\nFalling back to software rendering." msgstr "\nQuay trở lại kết xuất phần mềm." -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>Khi chọn hình ảnh phương tiện (CD-ROM, ổ mềm, v.v.), hộp thoại mở sẽ bắt đầu trong cùng thư mục với tệp cấu hình 86box. Cài đặt này có thể sẽ chỉ tạo ra sự khác biệt trên macOS.</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

Khi chọn hình ảnh phương tiện (CD-ROM, ổ mềm, v.v.), hộp thoại mở sẽ bắt đầu trong cùng thư mục với tệp cấu hình 86box. Cài đặt này có thể sẽ chỉ tạo ra sự khác biệt trên macOS.

" msgid "This machine might have been moved or copied." msgstr "Cấu hình máy này có thể đã được di chuyển hoặc sao chép." @@ -1371,9 +1452,27 @@ msgstr "Thông qua cổng serial 3" msgid "Serial port passthrough 4" msgstr "Thông qua cổng serial 4" -msgid "Renderer options..." +msgid "Renderer &options..." msgstr "Tùy chọn kết xuất ..." +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" + msgid "Logitech/Microsoft Bus Mouse" msgstr "Chuột bus Logitech/Microsoft" @@ -1383,18 +1482,30 @@ msgstr "Chuột bus Microsoft (INPORT)" msgid "Mouse Systems Serial Mouse" msgstr "Chuột serial Mouse Systems" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Chuột serial Microsoft" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Chuột serial Logitech" msgid "PS/2 Mouse" msgstr "Chuột PS/2" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (Serial)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] Modem tuân thủ tiêu chuẩn Hayes" @@ -1419,12 +1530,54 @@ msgstr "MIDI của hệ thống" msgid "MIDI Input Device" msgstr "Thiết bị nhập MIDI" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "Địa chỉ BIOS" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "Kích hoạt ghi ROM mở rộng BIOS" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "Địa chỉ" @@ -1434,6 +1587,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "Sửa đổi BIOS" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "Dịch 26 -> 17" @@ -1449,6 +1614,18 @@ msgstr "Đảo ngược màu sắc" msgid "BIOS size" msgstr "Kích thước BIOS" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "Map C0000-C7FFF dưới dạng UMB" @@ -1524,6 +1701,9 @@ msgstr "Mức độ hồi âm" msgid "Interpolation Method" msgstr "Phương pháp nội suy" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "Tăng đầu ra hồi âm" @@ -1611,6 +1791,12 @@ msgstr "DMA thấp" msgid "Enable Game port" msgstr "Bật cổng trò chơi" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "Mô đun vòm" @@ -1623,6 +1809,9 @@ msgstr "Tăng ngắt CODEC trên thiết lập CODEC (cần bởi một số tr msgid "SB Address" msgstr "Địa chỉ SB" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "WSS IRQ" @@ -1707,9 +1896,15 @@ msgstr "Loại RAMDAC" msgid "Blend" msgstr "Trộn" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "Lọc song tuyến" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "Ngân tán" @@ -1752,6 +1947,33 @@ msgstr "Tốc độ truyền tải" msgid "EMS mode" msgstr "Chế độ EMS" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "Địa chỉ cho > 2 MB" @@ -1770,11 +1992,11 @@ msgstr "Luôn ở tốc độ đã chọn" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "Cài đặt BIOS + phím nóng (TẮT trong POST)" -msgid "64 kB starting from F0000" -msgstr "64 kb bắt đầu từ f0000" +msgid "64 KB starting from F0000" +msgstr "64 KB bắt đầu từ f0000" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kb bắt đầu từ E0000 (địa chỉ MSB đảo ngược, 64kb cuối cùng)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB bắt đầu từ E0000 (địa chỉ MSB đảo ngược, 64 KB cuối cùng)" msgid "Sine" msgstr "Sin" @@ -1908,6 +2130,15 @@ msgstr "Nội suy SRGB" msgid "Linear interpolation" msgstr "Nội suy tuyến tính" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2172,9 @@ msgstr "Màu hổ phách" msgid "Gray" msgstr "Màu xám" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "Màu sắc" @@ -1956,6 +2190,12 @@ msgstr "Các ngôn ngữ khác" msgid "Bochs latest" msgstr "Bochs mới nhất" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "Đơn sắc không xen kẽ" @@ -2037,6 +2277,9 @@ msgstr "Tốc độ baud của đường thông" msgid "Named Pipe (Server)" msgstr "Đường ống có tên (máy chủ)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "Thông qua cổng serial của máy chủ" @@ -2082,6 +2325,12 @@ msgstr "IBM 8514/A bản nhái (ISA)" msgid "Vendor" msgstr "Nhà sản xuất" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "Chung mở rộng bộ nhớ qua PC/XT" @@ -2106,9 +2355,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2156,3 +2402,87 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "Bộ điều khiển ổ cứng:" + +#~ msgid "ZIP drives:" +#~ msgstr "Ổ đĩa ZIP:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "Ảnh đĩa ZIP" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index c29e40dfb..c00a82d9e 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+Esc(&E)" msgid "&Pause" msgstr "暂停(&P)" -msgid "E&xit..." -msgstr "退出(&X)..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "退出(&X)" msgid "&View" msgstr "查看(&V)" @@ -60,8 +63,8 @@ msgstr "OpenGL (3.0 Core)(&G)" msgid "&VNC" msgstr "VNC(&V)" -msgid "Specify dimensions..." -msgstr "指定窗口大小..." +msgid "Specify &dimensions..." +msgstr "指定窗口大小...(&D)" msgid "F&orce 4:3 display ratio" msgstr "强制 4:3 显示比例(&O)" @@ -99,8 +102,8 @@ msgstr "7x(&7)" msgid "&8x" msgstr "8x(&8)" -msgid "Filter method" -msgstr "过滤方式" +msgid "Fi<er method" +msgstr "过滤方式(&L)" msgid "&Nearest" msgstr "邻近(&N)" @@ -144,9 +147,15 @@ msgstr "VGA 屏幕类型(&T)" msgid "RGB &Color" msgstr "RGB 彩色(&C)" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "RGB 灰度(&R)" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "琥珀色单色显示器(&A)" @@ -384,6 +393,15 @@ msgstr "启用 (UTC)" msgid "Dynamic Recompiler" msgstr "动态重编译器" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "显卡:" @@ -399,6 +417,9 @@ msgstr "IBM 8514/A 图形" msgid "XGA Graphics" msgstr "XGA 图形" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "鼠标:" @@ -498,18 +519,21 @@ msgstr "并口 3" msgid "Parallel port 4" msgstr "并口 4" -msgid "HD Controller:" -msgstr "硬盘控制器:" - msgid "FD Controller:" msgstr "软盘控制器:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "第三 IDE 控制器" msgid "Quaternary IDE Controller" msgstr "第四 IDE 控制器" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "磁带" msgid "Hard disks:" msgstr "硬盘:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "新建(&N)..." @@ -588,8 +615,8 @@ msgstr "光盘驱动器:" msgid "MO drives:" msgstr "磁光盘驱动器:" -msgid "ZIP drives:" -msgstr "ZIP 驱动器:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA 实时时钟:" msgid "ISA Memory Expansion" msgstr "ISA 内存扩展" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "扩展卡 1:" @@ -612,6 +642,15 @@ msgstr "扩展卡 3:" msgid "Card 4:" msgstr "扩展卡 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "ISABugger 设备" @@ -630,17 +669,20 @@ msgstr "致命错误" msgid " - PAUSED" msgstr " - 已暂停" -msgid "Press Ctrl+Alt+PgDn to return to windowed mode." -msgstr "按下 Ctrl+Alt+PgDn 返回到窗口模式。" - msgid "Speed" msgstr "速度" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "ZIP 映像" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" 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\" 文件夹中。" @@ -717,11 +759,11 @@ msgstr "其他外围设备" msgid "Click to capture mouse" msgstr "单击窗口捕捉鼠标" -msgid "Press %s to release mouse" -msgstr "按下 %s 释放鼠标" +msgid "Press %1 to release mouse" +msgstr "按下 %1 释放鼠标" -msgid "Press %s or middle button to release mouse" -msgstr "按下 %s 或鼠标中键释放鼠标" +msgid "Press %1 or middle button to release mouse" +msgstr "按下 %1 或鼠标中键释放鼠标" msgid "Bus" msgstr "总线" @@ -780,12 +822,39 @@ msgstr "4 轴, 4 键操纵杆" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "无" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "软盘 %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "软盘 %1 (%2): %3(&F)" + msgid "Advanced sector images" msgstr "高级扇区映像" @@ -816,6 +888,9 @@ msgstr "无法初始化 GhostPCL" msgid "MO %1 (%2): %3" msgstr "磁光盘 %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "磁光盘 %1 (%2): %3(&M)" + msgid "MO images" msgstr "磁光盘映像" @@ -852,8 +927,8 @@ msgstr "一个旧式计算机模拟器\n\n作者: Miran Grča (OBattler)、Richa msgid "Hardware not available" msgstr "硬件不可用" -msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." -msgstr "请确认 %1 已安装且使用兼容 libpcap 的网络连接。" +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "请确认 %1 已安装且使用兼容 %1 的网络连接。" msgid "Invalid configuration" msgstr "无效配置" @@ -864,9 +939,6 @@ msgstr "%1 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通 msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 是将 PCL 文件转换为 PDF 所需要的库。\n\n使用通用 PCL 打印机打印的文档将被保存为 Printer Command Language (.pcl) 文件。" -msgid "Entering fullscreen mode" -msgstr "正在进入全屏模式" - msgid "Don't show this message again" msgstr "不要再显示此消息" @@ -903,12 +975,18 @@ msgstr "继续" msgid "Cassette: %1" msgstr "磁带: %1" +msgid "C&assette: %1" +msgstr "磁带: %1(&A)" + msgid "Cassette images" msgstr "磁带映像" msgid "Cartridge %1: %2" msgstr "卡带 %1: %2" +msgid "Car&tridge %1: %2" +msgstr "卡带 %1: %2(&A)" + msgid "Cartridge images" msgstr "卡带映像" @@ -930,6 +1008,9 @@ msgstr "硬重置" msgid "ACPI shutdown" msgstr "ACPI 关机" +msgid "ACP&I shutdown" +msgstr "ACP&I 关机" + msgid "Hard disk (%1)" msgstr "硬盘 (%1)" @@ -1215,41 +1296,41 @@ msgstr "MCA 设备" msgid "List of MCA devices:" msgstr "MCA 设备清单:" -msgid "Tablet tool" -msgstr "平板工具" +msgid "&Tablet tool" +msgstr "平板工具(&T)" msgid "Qt (OpenGL &ES)" msgstr "Qt(OpenGL &ES)" -msgid "About Qt" -msgstr "关于 Qt" +msgid "About &Qt" +msgstr "关于 &Qt" -msgid "MCA devices..." -msgstr "MCA 设备..." +msgid "&MCA devices..." +msgstr "&MCA 设备..." -msgid "Show non-primary monitors" -msgstr "显示非主要显示器" +msgid "Show non-&primary monitors" +msgstr "显示非主要显示器(&P)" -msgid "Open screenshots folder..." -msgstr "打开屏幕截图文件夹..." +msgid "Open screenshots &folder..." +msgstr "打开屏幕截图文件夹...(&F)" -msgid "Apply fullscreen stretch mode when maximized" -msgstr "最大化时应用全屏拉伸模式" +msgid "Appl&y fullscreen stretch mode when maximized" +msgstr "最大化时应用全屏拉伸模式(&Y)" -msgid "Cursor/Puck" -msgstr "光标/冰球" +msgid "&Cursor/Puck" +msgstr "光标/冰球(&C)" -msgid "Pen" -msgstr "笔" +msgid "&Pen" +msgstr "笔(&P)" -msgid "Host CD/DVD Drive (%1:)" -msgstr "主机 CD/DVD 驱动器 (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "主机 CD/DVD 驱动器 (%1:) (&H)" msgid "&Connected" -msgstr "" +msgstr "已连接(&C)" -msgid "Clear image history" -msgstr "清除映像历史记录" +msgid "Clear image &history" +msgstr "清除映像历史记录(&H)" msgid "Create..." msgstr "创建..." @@ -1305,8 +1386,8 @@ msgstr "初始化 OpenGL 时出错" msgid "\nFalling back to software rendering." msgstr "\n回到软件渲染。" -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>选择媒体图像(光盘、软盘等)时,打开对话框将从与 86Box 配置文件相同的目录开始。这一设置可能只会在 macOS 上产生影响。</p></body></html>;" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

选择媒体图像(光盘、软盘等)时,打开对话框将从与 86Box 配置文件相同的目录开始。这一设置可能只会在 macOS 上产生影响。

" msgid "This machine might have been moved or copied." msgstr "这台机器可能被移动或复制过。" @@ -1321,7 +1402,7 @@ msgid "I Copied It" msgstr "我已复制这台机器" msgid "86Box Monitor #" -msgstr "86Box 监测器 " +msgstr "86Box 监测器 #" msgid "No MCA devices." msgstr "无 MCA 设备。" @@ -1371,8 +1452,26 @@ msgstr "串行端口直通 3" msgid "Serial port passthrough 4" msgstr "串行端口直通 4" -msgid "Renderer options..." -msgstr "渲染器选项..." +msgid "Renderer &options..." +msgstr "渲染器选项...(&O)" + +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" msgid "Logitech/Microsoft Bus Mouse" msgstr "Logitech/Microsoft 总线鼠标" @@ -1383,18 +1482,30 @@ msgstr "Microsoft 总线鼠标(InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Mouse Systems 串行鼠标" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Microsoft 串行鼠标" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Logitech 串行鼠标" msgid "PS/2 Mouse" msgstr "PS/2 鼠标" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (串行)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] 标准 Hayes 兼容调制解调器" @@ -1419,12 +1530,54 @@ msgstr "系统 MIDI" msgid "MIDI Input Device" msgstr "MIDI 输入设备" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "BIOS 地址" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "启用 BIOS 扩展 ROM 写入功能" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "地址" @@ -1434,6 +1587,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "BIOS 修订版" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "翻译 26 -> 17" @@ -1449,6 +1614,18 @@ msgstr "反转颜色" msgid "BIOS size" msgstr "BIOS 大小" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "将 C0000-C7FFF 映射为 UMB" @@ -1524,6 +1701,9 @@ msgstr "混响电平" msgid "Interpolation Method" msgstr "插值法" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "混响输出的增益" @@ -1611,6 +1791,12 @@ msgstr "低 DMA" msgid "Enable Game port" msgstr "启用游戏端口" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "环绕声模块" @@ -1623,6 +1809,9 @@ msgstr "在 CODEC 设置时引发 CODEC 中断(某些驱动程序需要)。" msgid "SB Address" msgstr "SB 地址" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "WSS IRQ" @@ -1707,9 +1896,15 @@ msgstr "RAMDAC 类型" msgid "Blend" msgstr "混合" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "双线性滤波" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "抖动" @@ -1752,6 +1947,33 @@ msgstr "传输速度" msgid "EMS mode" msgstr "EMS (扩展内存)模式" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "地址 > 2 MB" @@ -1770,11 +1992,11 @@ msgstr "始终保持选定速度" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "BIOS 设置 + 热键 (开机自检期间关闭)" -msgid "64 kB starting from F0000" -msgstr "64 kB,从 F0000 开始" +msgid "64 KB starting from F0000" +msgstr "64 KB,从 F0000 开始" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB,从 E0000 开始 (地址 MSB 反相,最后 64KB 优先)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB,从 E0000 开始 (地址 MSB 反相,最后 64 KB 优先)" msgid "Sine" msgstr "正弦" @@ -1810,7 +2032,7 @@ msgid "Five + Wheel" msgstr "五键+滚轮" msgid "Five + 2 Wheels" -msgstr "" +msgstr "五键+双滚轮" msgid "A3 - SMT2 Serial / SMT3(R)V" msgstr "A3 - SMT2 串行 / SMT3(R)V" @@ -1908,6 +2130,15 @@ msgstr "sRGB 插值" msgid "Linear interpolation" msgstr "线性插值" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2172,9 @@ msgstr "琥珀色" msgid "Gray" msgstr "灰色" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "彩色" @@ -1956,6 +2190,12 @@ msgstr "其他语言" msgid "Bochs latest" msgstr "Bochs 最新版本" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "单色非隔行扫描" @@ -2037,6 +2277,9 @@ msgstr "直通波特率" msgid "Named Pipe (Server)" msgstr "命名管道(服务器)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "主机串行端口直通" @@ -2056,25 +2299,25 @@ msgid "[Generic] RAM Disk (max. speed)" msgstr "[Generic] RAM 磁盘 (最大速度)" msgid "[Generic] 1989 (3500 RPM)" -msgstr "" +msgstr "[Generic] 1989 (3500 RPM)" msgid "[Generic] 1992 (3600 RPM)" -msgstr "" +msgstr "[Generic] 1992 (3600 RPM)" msgid "[Generic] 1994 (4500 RPM)" -msgstr "" +msgstr "[Generic] 1994 (4500 RPM)" msgid "[Generic] 1996 (5400 RPM)" -msgstr "" +msgstr "[Generic] 1996 (5400 RPM)" msgid "[Generic] 1997 (5400 RPM)" -msgstr "" +msgstr "[Generic] 1997 (5400 RPM)" msgid "[Generic] 1998 (5400 RPM)" -msgstr "" +msgstr "[Generic] 1998 (5400 RPM)" msgid "[Generic] 2000 (7200 RPM)" -msgstr "" +msgstr "[Generic] 2000 (7200 RPM)" msgid "IBM 8514/A clone (ISA)" msgstr "IBM 8514/A 克隆 (ISA)" @@ -2082,6 +2325,12 @@ msgstr "IBM 8514/A 克隆 (ISA)" msgid "Vendor" msgstr "制造商" +msgid "30 Hz (JMP2 = 1)" +msgstr "30 Hz (JMP2 = 1)" + +msgid "60 Hz (JMP2 = 2)" +msgstr "60 Hz (JMP2 = 2)" + msgid "Generic PC/XT Memory Expansion" msgstr "通用 PC/XT 内存扩展" @@ -2095,64 +2344,145 @@ msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for t msgstr "仿真通用 ESC/P 点阵打印机需要使用 \"roms/printer/fonts\" 目录中的 TrueType 字体。" msgid "Inhibit multimedia keys" -msgstr "" +msgstr "禁止多媒体按键" msgid "Ask for confirmation before saving settings" -msgstr "" +msgstr "保存设置前要求用户确认" msgid "Ask for confirmation before hard resetting" -msgstr "" +msgstr "硬重置前要求用户确认" msgid "Ask for confirmation before quitting" -msgstr "" - -msgid "Display hotkey message when entering full-screen mode" -msgstr "" +msgstr "退出前要求用户确认" msgid "Options" -msgstr "" +msgstr "选项" msgid "Model" -msgstr "" +msgstr "模型" msgid "Model:" -msgstr "" +msgstr "模型:" msgid "Failed to initialize Vulkan renderer." -msgstr "" +msgstr "Vulkan 渲染器初始化失败。" msgid "GLSL Error" -msgstr "" +msgstr "GLSL 错误" msgid "Could not load shader: %1" -msgstr "" +msgstr "无法加载着色器:%1" msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "" +msgstr "OpenGL 版本需要达到 3.0 或更高。当前 GLSL 版本为 %1.%2" msgid "Could not load texture: %1" -msgstr "" +msgstr "无法加载材质:%1" msgid "Could not compile shader:\n\n%1" -msgstr "" +msgstr "无法编译着色器:\n\n%1" msgid "Program not linked:\n\n%1" -msgstr "" +msgstr "程序未链接:\n\n%1" msgid "Shader Manager" -msgstr "" +msgstr "着色器管理器" msgid "Shader Configuration" -msgstr "" +msgstr "着色器配置" msgid "Add" -msgstr "" +msgstr "添加" msgid "Move up" -msgstr "" +msgstr "上移" msgid "Move down" -msgstr "" +msgstr "下移" msgid "Could not load file %1" +msgstr "无法加载文件 %1" + +msgid "Key Bindings:" msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "硬盘控制器:" + +#~ msgid "ZIP drives:" +#~ msgstr "ZIP 驱动器:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "ZIP 映像" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 7de6f8cd3..36810d342 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -27,8 +27,11 @@ msgstr "Ctrl+Alt+Esc(&E)" msgid "&Pause" msgstr "暫停(&P)" -msgid "E&xit..." -msgstr "退出(&X)..." +msgid "Re&sume" +msgstr "" + +msgid "E&xit" +msgstr "退出(&X)" msgid "&View" msgstr "檢視(&V)" @@ -60,8 +63,8 @@ msgstr "OpenGL (3.0 Core)(&G)" msgid "&VNC" msgstr "VNC(&V)" -msgid "Specify dimensions..." -msgstr "指定視窗大小..." +msgid "Specify &dimensions..." +msgstr "指定視窗大小...(&D)" msgid "F&orce 4:3 display ratio" msgstr "強制 4:3 顯示比例(&O)" @@ -99,8 +102,8 @@ msgstr "7x(&7)" msgid "&8x" msgstr "8x(&8)" -msgid "Filter method" -msgstr "過濾方式" +msgid "Fi<er method" +msgstr "過濾方式(&L)" msgid "&Nearest" msgstr "鄰近(&N)" @@ -144,9 +147,15 @@ msgstr "VGA 螢幕類型(&T)" msgid "RGB &Color" msgstr "RGB 彩色(&C)" +msgid "RGB (no brown)" +msgstr "" + msgid "&RGB Grayscale" msgstr "RGB 灰度(&R)" +msgid "Generic RGBI color monitor" +msgstr "" + msgid "&Amber monitor" msgstr "琥珀色單色顯示器(&A)" @@ -384,6 +393,15 @@ msgstr "啟用 (UTC)" msgid "Dynamic Recompiler" msgstr "動態重編譯器" +msgid "CPU frame size" +msgstr "" + +msgid "Larger frames (less smooth)" +msgstr "" + +msgid "Smaller frames (smoother)" +msgstr "" + msgid "Video:" msgstr "顯示卡:" @@ -399,6 +417,9 @@ msgstr "IBM 8514/A Graphics" msgid "XGA Graphics" msgstr "XGA Graphics" +msgid "Keyboard:" +msgstr "" + msgid "Mouse:" msgstr "滑鼠:" @@ -498,18 +519,21 @@ msgstr "並列埠 3" msgid "Parallel port 4" msgstr "並列埠 4" -msgid "HD Controller:" -msgstr "硬碟控制器:" - msgid "FD Controller:" msgstr "軟碟控制器:" +msgid "CD-ROM Controller:" +msgstr "" + msgid "Tertiary IDE Controller" msgstr "第三 IDE 控制器" msgid "Quaternary IDE Controller" msgstr "第四 IDE 控制器" +msgid "Hard disk" +msgstr "" + msgid "SCSI" msgstr "SCSI" @@ -531,6 +555,9 @@ msgstr "磁帶" msgid "Hard disks:" msgstr "硬碟:" +msgid "Firmware Version" +msgstr "" + msgid "&New..." msgstr "新增(&N)..." @@ -588,8 +615,8 @@ msgstr "光碟機:" msgid "MO drives:" msgstr "磁光碟機:" -msgid "ZIP drives:" -msgstr "ZIP 磁碟機:" +msgid "Removable disk drives:" +msgstr "" msgid "ZIP 250" msgstr "ZIP 250" @@ -600,6 +627,9 @@ msgstr "ISA 實時時鐘:" msgid "ISA Memory Expansion" msgstr "ISA 記憶體擴充" +msgid "ISA ROM Cards" +msgstr "" + msgid "Card 1:" msgstr "擴充卡 1:" @@ -612,6 +642,15 @@ msgstr "擴充卡 3:" msgid "Card 4:" msgstr "擴充卡 4:" +msgid "Generic ISA ROM Board" +msgstr "" + +msgid "Generic Dual ISA ROM Board" +msgstr "" + +msgid "Generic Quad ISA ROM Board" +msgstr "" + msgid "ISABugger device" msgstr "ISABugger 裝置" @@ -630,17 +669,20 @@ msgstr "致命錯誤" msgid " - PAUSED" msgstr " - 已暫停" -msgid "Press Ctrl+Alt+PgDn to return to windowed mode." -msgstr "按下 Ctrl+Alt+PgDn 返回到視窗模式。" - msgid "Speed" msgstr "速度" -msgid "ZIP %1 %2 (%3): %4" -msgstr "ZIP %1 %2 (%3): %4" +msgid "Removable disk %1 (%2): %3" +msgstr "" -msgid "ZIP images" -msgstr "ZIP 映像" +msgid "&Removable disk %1 (%2): %3" +msgstr "" + +msgid "Removable disk images" +msgstr "" + +msgid "Image %1" +msgstr "" 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\" 資料夾。" @@ -717,11 +759,11 @@ msgstr "其他周邊裝置" msgid "Click to capture mouse" msgstr "點擊視窗捕捉滑鼠" -msgid "Press %s to release mouse" -msgstr "按下 %s 釋放滑鼠" +msgid "Press %1 to release mouse" +msgstr "按下 %1 釋放滑鼠" -msgid "Press %s or middle button to release mouse" -msgstr "按下 %s 或滑鼠中鍵釋放滑鼠" +msgid "Press %1 or middle button to release mouse" +msgstr "按下 %1 或滑鼠中鍵釋放滑鼠" msgid "Bus" msgstr "匯流排" @@ -780,12 +822,39 @@ msgstr "4 軸, 4 鍵搖桿" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" msgstr "Thrustmaster Flight Control System" +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "2-button gamepad(s)" +msgstr "" + +msgid "2-button flight yoke" +msgstr "" + +msgid "4-button gamepad" +msgstr "" + +msgid "4-button flight yoke" +msgstr "" + +msgid "2-button flight yoke with throttle" +msgstr "" + +msgid "4-button flight yoke with throttle" +msgstr "" + +msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgstr "" + msgid "None" msgstr "無" @@ -795,6 +864,9 @@ msgstr "%1 MB (CHS: %2, %3, %4)" msgid "Floppy %1 (%2): %3" msgstr "軟碟 %1 (%2): %3" +msgid "&Floppy %1 (%2): %3" +msgstr "軟碟 %1 (%2): %3(&F)" + msgid "Advanced sector images" msgstr "進階磁區映像" @@ -816,6 +888,9 @@ msgstr "無法初始化 GhostPCL" msgid "MO %1 (%2): %3" msgstr "磁光碟 %1 (%2): %3" +msgid "&MO %1 (%2): %3" +msgstr "磁光碟 %1 (%2): %3(&M)" + msgid "MO images" msgstr "磁光碟映像" @@ -852,8 +927,8 @@ msgstr "一個舊式電腦模擬器\n\n作者: Miran Grča (OBattler)、RichardG msgid "Hardware not available" msgstr "硬體不可用" -msgid "Make sure %1 is installed and that you are on a libpcap-compatible network connection." -msgstr "請確認 %1 已安裝且使用相容 libpcap 的網路連線。" +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "請確認 %1 已安裝且使用相容 %1 的網路連線。" msgid "Invalid configuration" msgstr "無效設定" @@ -864,9 +939,6 @@ msgstr "%1 是將 PostScript 檔案轉換為 PDF 所需要的庫。\n\n使用通 msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." msgstr "%1 是將 PCL 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PCL 印表機列印的文件將被儲存為 Printer Command Language (.pcl) 檔案。" -msgid "Entering fullscreen mode" -msgstr "正在進入全螢幕模式" - msgid "Don't show this message again" msgstr "不要再顯示此消息" @@ -903,12 +975,18 @@ msgstr "繼續" msgid "Cassette: %1" msgstr "磁帶: %1" +msgid "C&assette: %1" +msgstr "磁帶: %1(&A)" + msgid "Cassette images" msgstr "磁帶映像" msgid "Cartridge %1: %2" msgstr "卡帶 %1: %2" +msgid "Car&tridge %1: %2" +msgstr "卡帶 %1: %2(&A)" + msgid "Cartridge images" msgstr "卡帶映像" @@ -930,6 +1008,9 @@ msgstr "硬重設" msgid "ACPI shutdown" msgstr "ACPI 關機" +msgid "ACP&I shutdown" +msgstr "ACP&I 關機" + msgid "Hard disk (%1)" msgstr "硬碟 (%1)" @@ -1215,41 +1296,41 @@ msgstr "MCA 裝置" msgid "List of MCA devices:" msgstr "MCA 裝置清單:" -msgid "Tablet tool" -msgstr "平板工具" +msgid "&Tablet tool" +msgstr "平板工具(&T)" msgid "Qt (OpenGL &ES)" msgstr "Qt (OpenGL &ES)" -msgid "About Qt" -msgstr "關於 Qt" +msgid "About &Qt" +msgstr "關於 &Qt" -msgid "MCA devices..." -msgstr "MCA 裝置..." +msgid "&MCA devices..." +msgstr "&MCA 裝置..." -msgid "Show non-primary monitors" -msgstr "顯示非主要顯示器" +msgid "Show non-&primary monitors" +msgstr "顯示非主要顯示器(&P)" -msgid "Open screenshots folder..." -msgstr "開啟螢幕截圖資料夾..." +msgid "Open screenshots &folder..." +msgstr "開啟螢幕截圖資料夾...(&F)" -msgid "Apply fullscreen stretch mode when maximized" -msgstr "最大化時套用全螢幕拉伸模式" +msgid "Appl&y fullscreen stretch mode when maximized" +msgstr "最大化時套用全螢幕拉伸模式(&Y)" -msgid "Cursor/Puck" -msgstr "游標/球棒" +msgid "&Cursor/Puck" +msgstr "游標/球棒(&C)" -msgid "Pen" -msgstr "筆" +msgid "&Pen" +msgstr "筆(&P)" -msgid "Host CD/DVD Drive (%1:)" -msgstr "主機 CD/DVD 光碟機 (%1:)" +msgid "&Host CD/DVD Drive (%1:)" +msgstr "主機 CD/DVD 光碟機 (%1:) (&H)" msgid "&Connected" msgstr "已連線" -msgid "Clear image history" -msgstr "清除映像歷史記錄" +msgid "Clear image &history" +msgstr "清除映像歷史記錄(&H)" msgid "Create..." msgstr "建立..." @@ -1305,8 +1386,8 @@ msgstr "初始化 OpenGL 出錯" msgid "\nFalling back to software rendering." msgstr "\n回退到軟體渲染。" -msgid "<html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html>" -msgstr "<html><head/><body><p>當選擇媒體映像 (CD-ROM、軟碟等) 時,開啟對話方塊會在與 86Box 設定檔相同的目錄中開始。此設定可能只會在 macOS 上有所影響。</p></body></html>" +msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" +msgstr "

當選擇媒體映像 (CD-ROM、軟碟等) 時,開啟對話方塊會在與 86Box 設定檔相同的目錄中開始。此設定可能只會在 macOS 上有所影響。

" msgid "This machine might have been moved or copied." msgstr "這台機器可能已被移動或複製。" @@ -1371,8 +1452,26 @@ msgstr "序列埠的直通 3" msgid "Serial port passthrough 4" msgstr "序列埠的直通 4" -msgid "Renderer options..." -msgstr "渲染器選項..." +msgid "Renderer &options..." +msgstr "渲染器選項...(&O)" + +msgid "PC/XT Keyboard" +msgstr "" + +msgid "AT Keyboard" +msgstr "" + +msgid "AX Keyboard" +msgstr "" + +msgid "PS/2 Keyboard" +msgstr "" + +msgid "PS/55 Keyboard" +msgstr "" + +msgid "Keys" +msgstr "" msgid "Logitech/Microsoft Bus Mouse" msgstr "Logitech/Microsoft 匯流排滑鼠" @@ -1383,18 +1482,30 @@ msgstr "Microsoft 匯流排滑鼠 (InPort)" msgid "Mouse Systems Serial Mouse" msgstr "Mouse Systems 序列滑鼠" +msgid "Mouse Systems Bus Mouse" +msgstr "" + msgid "Microsoft Serial Mouse" msgstr "Microsoft 序列滑鼠" +msgid "Microsoft Serial BallPoint" +msgstr "" + msgid "Logitech Serial Mouse" msgstr "Logitech 序列滑鼠" msgid "PS/2 Mouse" msgstr "PS/2 滑鼠" +msgid "PS/2 QuickPort Mouse" +msgstr "" + msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (序列)" +msgid "Default Baud rate" +msgstr "" + msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] 標準 Hayes 相容的數據機" @@ -1419,12 +1530,54 @@ msgstr "系統的 MIDI" msgid "MIDI Input Device" msgstr "MIDI 輸入裝置" -msgid "BIOS Address" +msgid "BIOS file" +msgstr "" + +msgid "BIOS file (ROM #1)" +msgstr "" + +msgid "BIOS file (ROM #2)" +msgstr "" + +msgid "BIOS file (ROM #3)" +msgstr "" + +msgid "BIOS file (ROM #4)" +msgstr "" + +msgid "BIOS address" msgstr "BIOS 位址" +msgid "BIOS address (ROM #1)" +msgstr "" + +msgid "BIOS address (ROM #2)" +msgstr "" + +msgid "BIOS address (ROM #3)" +msgstr "" + +msgid "BIOS address (ROM #4)" +msgstr "" + msgid "Enable BIOS extension ROM Writes" msgstr "啟用 BIOS 擴充 ROM 寫入" +msgid "Enable BIOS extension ROM Writes (ROM #1)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #2)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #3)" +msgstr "" + +msgid "Enable BIOS extension ROM Writes (ROM #4)" +msgstr "" + +msgid "Linear framebuffer base" +msgstr "" + msgid "Address" msgstr "位址" @@ -1434,6 +1587,18 @@ msgstr "IRQ" msgid "BIOS Revision" msgstr "BIOS 版本" +msgid "BIOS Version" +msgstr "" + +msgid "BIOS Language" +msgstr "" + +msgid "IBM 5161 Expansion Unit" +msgstr "" + +msgid "IBM Cassette Basic" +msgstr "" + msgid "Translate 26 -> 17" msgstr "轉換 26 -> 17" @@ -1449,6 +1614,18 @@ msgstr "反轉顏色" msgid "BIOS size" msgstr "BIOS 大小" +msgid "BIOS size (ROM #1)" +msgstr "" + +msgid "BIOS size (ROM #2)" +msgstr "" + +msgid "BIOS size (ROM #3)" +msgstr "" + +msgid "BIOS size (ROM #4)" +msgstr "" + msgid "Map C0000-C7FFF as UMB" msgstr "映射 C0000-C7FFF 為 UMB" @@ -1524,6 +1701,9 @@ msgstr "混響電平" msgid "Interpolation Method" msgstr "插值方法" +msgid "Dynamic Sample Loading" +msgstr "" + msgid "Reverb Output Gain" msgstr "迴響輸出增益" @@ -1611,6 +1791,12 @@ msgstr "低 DMA" msgid "Enable Game port" msgstr "啟用遊戲埠" +msgid "SID Model" +msgstr "" + +msgid "SID Filter Strength" +msgstr "" + msgid "Surround module" msgstr "環繞聲模組" @@ -1623,6 +1809,9 @@ msgstr "在 CODEC 設定時啟動 CODEC 中斷 (某些驅動程式需要)" msgid "SB Address" msgstr "SB 位址" +msgid "Use EEPROM setting" +msgstr "" + msgid "WSS IRQ" msgstr "WSS IRQ" @@ -1707,9 +1896,15 @@ msgstr "RAMDAC 類型" msgid "Blend" msgstr "混合" +msgid "Font" +msgstr "" + msgid "Bilinear filtering" msgstr "雙線性濾波" +msgid "Video chroma-keying" +msgstr "" + msgid "Dithering" msgstr "抖動" @@ -1752,6 +1947,33 @@ msgstr "傳輸速度" msgid "EMS mode" msgstr "EMS 模式" +msgid "EMS Address" +msgstr "" + +msgid "EMS 1 Address" +msgstr "" + +msgid "EMS 2 Address" +msgstr "" + +msgid "EMS Memory Size" +msgstr "" + +msgid "EMS 1 Memory Size" +msgstr "" + +msgid "EMS 2 Memory Size" +msgstr "" + +msgid "Enable EMS" +msgstr "" + +msgid "Enable EMS 1" +msgstr "" + +msgid "Enable EMS 2" +msgstr "" + msgid "Address for > 2 MB" msgstr "> 2 MB 的位址" @@ -1770,11 +1992,11 @@ msgstr "永遠以所選速度運作" msgid "BIOS setting + Hotkeys (off during POST)" msgstr "BIOS 設定 + 熱鍵 (POST 期間關閉)" -msgid "64 kB starting from F0000" -msgstr "64 kB 從 F0000 開始" +msgid "64 KB starting from F0000" +msgstr "64 KB 從 F0000 開始" -msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" -msgstr "128 kB 從 E0000 開始 (位址 MSB 反轉,後 64KB 為先)" +msgid "128 KB starting from E0000 (address MSB inverted, last 64 KB first)" +msgstr "128 KB 從 E0000 開始 (位址 MSB 反轉,後 64 KB 為先)" msgid "Sine" msgstr "正弦" @@ -1908,6 +2130,15 @@ msgstr "sRGB 插值" msgid "Linear interpolation" msgstr "線性插補" +msgid "Has secondary 8x8 character set" +msgstr "" + +msgid "Has Quadcolor II daughter board" +msgstr "" + +msgid "Alternate monochrome contrast" +msgstr "" + msgid "128 KB" msgstr "128 KB" @@ -1941,6 +2172,9 @@ msgstr "琥珀色" msgid "Gray" msgstr "灰色" +msgid "Grayscale" +msgstr "" + msgid "Color" msgstr "顏色" @@ -1956,6 +2190,12 @@ msgstr "其他語言" msgid "Bochs latest" msgstr "Bochs 最新" +msgid "Apply overscan deltas" +msgstr "" + +msgid "Mono Interlaced" +msgstr "" + msgid "Mono Non-Interlaced" msgstr "單色非隔行掃描" @@ -2037,6 +2277,9 @@ msgstr "直通的鮑率" msgid "Named Pipe (Server)" msgstr "已命名管道 (伺服器)" +msgid "Named Pipe (Client)" +msgstr "" + msgid "Host Serial Passthrough" msgstr "主機序列埠的直通" @@ -2082,6 +2325,12 @@ msgstr "IBM 8514/A 克隆 (ISA)" msgid "Vendor" msgstr "製造商" +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + msgid "Generic PC/XT Memory Expansion" msgstr "通用 PC/XT 記憶體擴充" @@ -2106,9 +2355,6 @@ msgstr "" msgid "Ask for confirmation before quitting" msgstr "" -msgid "Display hotkey message when entering full-screen mode" -msgstr "" - msgid "Options" msgstr "" @@ -2156,3 +2402,87 @@ msgstr "" msgid "Could not load file %1" msgstr "" + +msgid "Key Bindings:" +msgstr "" + +msgid "Action" +msgstr "" + +msgid "Keybind" +msgstr "" + +msgid "Clear binding" +msgstr "" + +msgid "Bind" +msgstr "" + +msgid "Bind Key" +msgstr "" + +msgid "Enter key combo:" +msgstr "" + +msgid "Bind conflict" +msgstr "" + +msgid "This key combo is already in use." +msgstr "" + +msgid "Send Control+Alt+Del" +msgstr "" + +msgid "Send Control+Alt+Escape" +msgstr "" + +msgid "Toggle fullscreen" +msgstr "" + +msgid "Screenshot" +msgstr "" + +msgid "Release mouse pointer" +msgstr "" + +msgid "Toggle pause" +msgstr "" + +msgid "Toggle mute" +msgstr "" + +msgid "Text files" +msgstr "" + +msgid "ROM files" +msgstr "" + +msgid "SoundFont files" +msgstr "" + +msgid "Local Switch" +msgstr "" + +msgid "Remote Switch" +msgstr "" + +msgid "Switch:" +msgstr "" + +msgid "Hub Mode" +msgstr "" + +msgid "Hostname:" +msgstr "" + +#~ msgid "HD Controller:" +#~ msgstr "硬碟控制器:" + +#~ msgid "ZIP drives:" +#~ msgstr "ZIP 磁碟機:" + +#~ msgid "ZIP %1 %2 (%3): %4" +#~ msgstr "ZIP %1 %2 (%3): %4" + +#~ msgid "ZIP images" +#~ msgstr "ZIP 映像" diff --git a/src/qt/qt.c b/src/qt/qt.c index 9ec907f33..e19cf1aac 100644 --- a/src/qt/qt.c +++ b/src/qt/qt.c @@ -28,6 +28,7 @@ #include <86box/plat.h> #include <86box/timer.h> #include <86box/nvr.h> +#include <86box/renderdefs.h> int qt_nvr_save(void) @@ -38,21 +39,16 @@ qt_nvr_save(void) int plat_vidapi(const char *api) { - if (!strcasecmp(api, "default") || !strcasecmp(api, "system")) { - return 0; - } else if (!strcasecmp(api, "qt_software")) { - return 0; - } else if (!strcasecmp(api, "qt_opengl")) { - return 1; - } else if (!strcasecmp(api, "qt_opengles")) { - return 2; - } else if (!strcasecmp(api, "qt_opengl3")) { - return 3; - } else if (!strcasecmp(api, "qt_vulkan")) { - return 4; - } else if (!strcasecmp(api, "vnc")) { - return 5; - } + if (!strcasecmp(api, RENDERER_NAME_DEFAULT) || !strcasecmp(api, RENDERER_NAME_SYSTEM)) + return RENDERER_SOFTWARE; + else if (!strcasecmp(api, RENDERER_NAME_QT_SOFTWARE)) + return RENDERER_SOFTWARE; + else if (!strcasecmp(api, RENDERER_NAME_QT_OPENGL) || !strcasecmp(api, RENDERER_NAME_QT_OPENGLES) || !strcasecmp(api, RENDERER_NAME_QT_OPENGL3)) + return RENDERER_OPENGL3; + else if (!strcasecmp(api, RENDERER_NAME_QT_VULKAN)) + return RENDERER_VULKAN; + else if (!strcasecmp(api, RENDERER_NAME_VNC)) + return RENDERER_VNC; return 0; } @@ -60,26 +56,20 @@ plat_vidapi(const char *api) char * plat_vidapi_name(int api) { - char *name = "default"; + char *name = RENDERER_NAME_DEFAULT; switch (api) { - case 0: - name = "qt_software"; + case RENDERER_SOFTWARE: + name = RENDERER_NAME_QT_SOFTWARE; break; - case 1: - name = "qt_opengl"; + case RENDERER_OPENGL3: + name = RENDERER_NAME_QT_OPENGL3; break; - case 2: - name = "qt_opengles"; + case RENDERER_VULKAN: + name = RENDERER_NAME_QT_VULKAN; break; - case 3: - name = "qt_opengl3"; - break; - case 4: - name = "qt_vulkan"; - break; - case 5: - name = "vnc"; + case RENDERER_VNC: + name = RENDERER_NAME_VNC; break; default: fatal("Unknown renderer: %i\n", api); @@ -87,4 +77,4 @@ plat_vidapi_name(int api) } return name; -} \ No newline at end of file +} diff --git a/src/qt/qt_about.cpp b/src/qt/qt_about.cpp new file mode 100644 index 000000000..96cde8522 --- /dev/null +++ b/src/qt/qt_about.cpp @@ -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. + * + * About dialog module. + * + * + * + * Authors: Joakim L. Gilje + * Cacodemon345 + * Teemu Korhonen + * dob205 + * + * Copyright 2021 Joakim L. Gilje + * Copyright 2021-2022 Cacodemon345 + * Copyright 2021-2022 Teemu Korhonen + * Copyright 2022 dob205 + */ +#include "qt_about.hpp" + +extern "C" { +#include <86box/86box.h> +#include <86box/version.h> +} + +#include +#include +#include +#include +#include + +About::About(QWidget *parent) +{ + setTextFormat(Qt::RichText); + QString versioninfo; +#ifdef EMU_GIT_HASH + versioninfo = QString(" [%1]").arg(EMU_GIT_HASH); +#endif +#ifdef USE_DYNAREC +# ifdef USE_NEW_DYNAREC +# define DYNAREC_STR "new dynarec" +# else +# define DYNAREC_STR "old dynarec" +# endif +#else +# define DYNAREC_STR "no dynarec" +#endif + versioninfo.append(QString(" [%1, %2]").arg(QSysInfo::buildCpuArchitecture(), tr(DYNAREC_STR))); + setText(QString("%3%1%2").arg(EMU_VERSION_FULL, versioninfo, tr("86Box v"))); + 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.")); + setWindowTitle(tr("About 86Box")); + const auto closeButton = addButton("OK", QMessageBox::ButtonRole::AcceptRole); + setEscapeButton(closeButton); + const auto webSiteButton = addButton(EMU_SITE, QMessageBox::ButtonRole::HelpRole); + webSiteButton->connect(webSiteButton, &QPushButton::released, []() { + QDesktopServices::openUrl(QUrl("https://" EMU_SITE)); + }); +#ifdef RELEASE_BUILD + setIconPixmap(QIcon(":/settings/qt/icons/86Box-green.ico").pixmap(32, 32)); +#elif defined ALPHA_BUILD + setIconPixmap(QIcon(":/settings/qt/icons/86Box-red.ico").pixmap(32, 32)); +#elif defined BETA_BUILD + setIconPixmap(QIcon(":/settings/qt/icons/86Box-yellow.ico").pixmap(32, 32)); +#else + setIconPixmap(QIcon(":/settings/qt/icons/86Box-gray.ico").pixmap(32, 32)); +#endif + setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); +} + +About::~About() + = default; diff --git a/src/qt/qt_about.hpp b/src/qt/qt_about.hpp new file mode 100644 index 000000000..206aab37b --- /dev/null +++ b/src/qt/qt_about.hpp @@ -0,0 +1,13 @@ +#ifndef QT_ABOUT_HPP +#define QT_ABOUT_HPP + +#include + +class About final : public QMessageBox { + Q_OBJECT + +public: + explicit About(QWidget *parent = nullptr); + ~About() override; +}; +#endif // QT_ABOUT_HPP \ No newline at end of file diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index cda52e722..33572c99c 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -31,6 +31,7 @@ #include #include #include +#include extern "C" { #include <86box/86box.h> @@ -45,6 +46,7 @@ extern "C" { #include "qt_filefield.hpp" #include "qt_models_common.hpp" +#include "qt_util.hpp" #ifdef Q_OS_LINUX # include # include @@ -276,11 +278,35 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) } case CONFIG_FNAME: { - auto *fileField = new FileField(); + auto *fileField = new FileField(this); fileField->setObjectName(config->name); fileField->setFileName(selected); - fileField->setFilter(QString(config->file_filter).left(static_cast(strcspn(config->file_filter, - "|")))); + /* Get the actually used part of the filter */ +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + QString filter = QString(config->file_filter).left(static_cast(strcspn(config->file_filter, "|"))); +#else + QString filter = QString(config->file_filter).split("|").at(0); +#endif + /* Extract the description and the extension list */ + QRegularExpressionMatch match = QRegularExpression("(.+) \\((.+)\\)$").match(filter); + QString description = match.captured(1); + QString extensions = match.captured(2); + /* Split the extension list up and strip the filename globs */ + QRegularExpression re("\\*\\.(.*)"); +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + QStringList extensionList; + int i = 0; + while (extensions.section(' ', i, i) != "") { + QString extension = re.match(extensions.section(' ', i, i)).captured(1); + extensionList.append(extension); + i++; + } +#else + QStringList extensionList = extensions.split(" "); + for (int i = 0; i < extensionList.count(); i++) + extensionList[i] = re.match(extensionList[i]).captured(1); +#endif + fileField->setFilter(tr(description.toUtf8().constData()) % util::DlgFilter(extensionList) % tr("All files") % util::DlgFilter({ "*" }, true)); this->ui->formLayout->addRow(tr(config->description), fileField); break; } @@ -388,6 +414,7 @@ DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *se } case CONFIG_MIDI_OUT: case CONFIG_MIDI_IN: + case CONFIG_INT: case CONFIG_SELECTION: { auto *cbox = dc.findChild(config->name); diff --git a/src/qt/qt_downloader.cpp b/src/qt/qt_downloader.cpp new file mode 100644 index 000000000..329aeeafb --- /dev/null +++ b/src/qt/qt_downloader.cpp @@ -0,0 +1,95 @@ +/* + * 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. + * + * Downloader module + * + * + * + * Authors: cold-brewed + * + * Copyright 2024 cold-brewed + */ + +#include +#include +#include +#include + +#include "qt_downloader.hpp" + +extern "C" { +#include <86box/plat.h> +} + +Downloader:: +Downloader(const DownloadLocation downloadLocation, QObject *parent) + : QObject(parent) + , file(nullptr) + , reply(nullptr) + , variantData(QVariant::Invalid) +{ + char PATHBUF[256]; + switch (downloadLocation) { + case DownloadLocation::Data: + plat_get_global_data_dir(PATHBUF, 255); + break; + case DownloadLocation::Config: + plat_get_global_config_dir(PATHBUF, 255); + break; + case DownloadLocation::Temp: + plat_get_temp_dir(PATHBUF, 255); + break; + } + downloadDirectory = QDir(PATHBUF); +} + +Downloader::~Downloader() { delete file; } + +void Downloader::download(const QUrl &url, const QString &filepath, const QVariant &varData) { + + variantData = varData; + // temporary until I get the plat stuff fixed + // const auto global_dir = temporaryGetGlobalDataDir(); + // qDebug() << "I was passed filepath " << filepath; + // Join with filename to create final file + // const auto final_path = QDir(global_dir).filePath(filepath); + const auto final_path = downloadDirectory.filePath(filepath); + + file = new QFile(final_path); + if(!file->open(QIODevice::WriteOnly)) { + qWarning() << "Unable to open file " << final_path; + return; + } + + const auto nam = new QNetworkAccessManager(this); + // Create the network request and execute + const auto request = QNetworkRequest(url); + reply = nam->get(request); + // Connect to the finished signal + connect(reply, &QNetworkReply::finished, this, &Downloader::onResult); +} + +void +Downloader::onResult() +{ + if (reply->error()) { + qWarning() << "Error returned from QNetworkRequest: " << reply->errorString(); + emit errorOccurred(reply->errorString()); + reply->deleteLater(); + return; + } + + file->write(reply->readAll()); + file->flush(); + file->close(); + + reply->deleteLater(); + qDebug() << Q_FUNC_INFO << "Downloaded complete: file written to " << file->fileName(); + emit downloadCompleted(file->fileName(), variantData); +} + diff --git a/src/qt/qt_downloader.hpp b/src/qt/qt_downloader.hpp new file mode 100644 index 000000000..2164ba59c --- /dev/null +++ b/src/qt/qt_downloader.hpp @@ -0,0 +1,57 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header for the downloader module + * + * + * + * Authors: cold-brewed + * + * Copyright 2024 cold-brewed + */ + +#ifndef QT_DOWNLOADER_HPP +#define QT_DOWNLOADER_HPP + +#include +#include +#include +#include + + +class Downloader final : public QObject { + Q_OBJECT +public: + enum class DownloadLocation { + Data, // AppDataLocation via plat_get_global_data_dir() + Config, // AppConfigLocation via plat_get_global_config_dir() + Temp // TempLocation via plat_get_temp_dir() + }; + explicit Downloader(DownloadLocation downloadLocation = DownloadLocation::Data, QObject *parent = nullptr); + ~Downloader() final; + + void download(const QUrl &url, const QString &filepath, const QVariant &varData = QVariant::Invalid); + +signals: + // Signal emitted when the download is successful + void downloadCompleted(QString filename, QVariant varData); + // Signal emitted when an error occurs + void errorOccurred(const QString&); + +private slots: + void onResult(); + +private: + QFile *file; + QNetworkAccessManager nam; + QNetworkReply *reply; + QVariant variantData; + QDir downloadDirectory; +}; + +#endif diff --git a/src/qt/qt_glsl_parser.cpp b/src/qt/qt_glsl_parser.cpp index 6e107bc19..934dd2052 100644 --- a/src/qt/qt_glsl_parser.cpp +++ b/src/qt/qt_glsl_parser.cpp @@ -69,13 +69,12 @@ static inline int wx_config_has_entry(void *config, const char *name) { return i static inline void wx_config_free(void *config) { ini_close(config); }; static int endswith(const char *str, const char *ext) { - int i; const char *p; int elen = strlen(ext); int slen = strlen(str); if (slen >= elen) { p = &str[slen - elen]; - for (i = 0; i < elen; ++i) { + for (int i = 0; i < elen; ++i) { if (tolower(p[i]) != tolower(ext[i])) return 0; } @@ -104,26 +103,32 @@ glsl_detect_bom(const char *fn) static char *load_file(const char *fn) { int bom = glsl_detect_bom(fn); - FILE *f = plat_fopen(fn, "rb"); - if (!f) + FILE *fp = plat_fopen(fn, "rb"); + if (!fp) return 0; - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); + fseek(fp, 0, SEEK_END); + long fsize = ftell(fp); + fseek(fp, 0, SEEK_SET); if (bom) { fsize -= 3; - fseek(f, 3, SEEK_SET); + fseek(fp, 3, SEEK_SET); } char *data = (char*)malloc(fsize + 1); - fread(data, fsize, 1, f); - fclose(f); + size_t read_bytes = fread(data, fsize, 1, fp); + if (read_bytes != 1) { + fclose(fp); + free(data); + return nullptr; + } else { + fclose(fp); - data[fsize] = 0; + data[fsize] = 0; - return data; + return data; + } } static void strip_lines(const char *program, const char *starts_with) { @@ -147,17 +152,15 @@ static void strip_defines(const char *program) { } static int has_parameter(glslp_t *glsl, char *id) { - int i; - for (i = 0; i < glsl->num_parameters; ++i) + for (int i = 0; i < glsl->num_parameters; ++i) if (!strcmp(glsl->parameters[i].id, id)) return 1; return 0; } static int get_parameters(glslp_t *glsl) { - int i; struct parameter p; - for (i = 0; i < glsl->num_shaders; ++i) { + for (int i = 0; i < glsl->num_shaders; ++i) { size_t size = 0; char* line = NULL; struct shader *shader = &glsl->shaders[i]; @@ -197,8 +200,7 @@ static int get_parameters(glslp_t *glsl) { } static struct parameter *get_parameter(glslp_t *glslp, const char *id) { - int i; - for (i = 0; i < glslp->num_parameters; ++i) { + for (int i = 0; i < glslp->num_parameters; ++i) { if (!strcmp(glslp->parameters[i].id, id)) { return &glslp->parameters[i]; } @@ -207,8 +209,7 @@ static struct parameter *get_parameter(glslp_t *glslp, const char *id) { } static glslp_t *glsl_parse(const char *f) { - glslp_t *glslp = (glslp_t*)malloc(sizeof(glslp_t)); - memset(glslp, 0, sizeof(glslp_t)); + glslp_t *glslp = (glslp_t*) calloc(1, sizeof(glslp_t)); glslp->num_shaders = 1; struct shader *shader = &glslp->shaders[0]; strcpy(shader->shader_fn, f); @@ -233,7 +234,9 @@ extern "C" { void get_glslp_name(const char *f, char *s, int size) { safe_strncpy(s, path_get_filename((char *)f), size); } glslp_t *glslp_parse(const char *f) { - int i, j, len, sublen; + int j; + int len; + int sublen; char s[513], t[513], z[540]; memset(s, 0, sizeof(s)); @@ -247,8 +250,7 @@ glslp_t *glslp_parse(const char *f) { return 0; } - glslp_t *glslp = (glslp_t*)malloc(sizeof(glslp_t)); - memset(glslp, 0, sizeof(glslp_t)); + glslp_t *glslp = (glslp_t*) calloc(1, sizeof(glslp_t)); get_glslp_name(f, glslp->name, sizeof(glslp->name)); @@ -256,7 +258,7 @@ glslp_t *glslp_parse(const char *f) { wx_config_get_bool(cfg, "filter_linear0", &glslp->input_filter_linear, -1); - for (i = 0; i < glslp->num_shaders; ++i) { + for (int i = 0; i < glslp->num_shaders; ++i) { struct shader *shader = &glslp->shaders[i]; snprintf(s, sizeof(s) - 1, "shader%d", i); @@ -267,12 +269,31 @@ glslp_t *glslp_parse(const char *f) { } strcpy(s, f); *path_get_filename(s) = 0; - snprintf(shader->shader_fn, sizeof(shader->shader_fn) - 1, "%s%s", s, t); + + size_t max_len = sizeof(shader->shader_fn); + size_t s_len = strlen(s); + + if (s_len >= max_len) { + // s alone fills or overflows the buffer, truncate and null-terminate + size_t copy_len = max_len - 1 < s_len ? max_len - 1 : s_len; + memcpy(shader->shader_fn, s, copy_len); + shader->shader_fn[copy_len] = '\0'; + } else { + // Copy s fully + memcpy(shader->shader_fn, s, s_len); + // Copy as much of t as fits after s + size_t avail = max_len - 1 - s_len; // space left for t + null terminator + // Copy as much of t as fits into the remaining space + memcpy(shader->shader_fn + s_len, t, avail); + // Null-terminate + shader->shader_fn[s_len + avail] = '\0'; + } + shader->shader_program = load_file(shader->shader_fn); if (!shader->shader_program) { - fprintf(stderr, "GLSLP Error: Could not load shader %s\n", shader->shader_fn); - glslp_free(glslp); - return 0; + fprintf(stderr, "GLSLP Error: Could not load shader %s\n", shader->shader_fn); + glslp_free(glslp); + return 0; } strip_parameters(shader->shader_program); strip_defines(shader->shader_program); @@ -327,7 +348,7 @@ glslp_t *glslp_parse(const char *f) { len = strlen(t); j = 0; sublen = 0; - for (i = 0; i < len; ++i) { + for (int i = 0; i < len; ++i) { if (t[i] == ';' || i == len - 1) { sublen = (i - j) + ((i == len - 1) ? 1 : 0) + 1; safe_strncpy(s, t + j, sublen); @@ -361,7 +382,7 @@ glslp_t *glslp_parse(const char *f) { len = strlen(t); j = 0; sublen = 0; - for (i = 0; i < len; ++i) { + for (int i = 0; i < len; ++i) { if (t[i] == ';' || i == len - 1) { sublen = (i - j) + ((i == len - 1) ? 1 : 0) + 1; safe_strncpy(s, t + j, sublen); @@ -382,8 +403,7 @@ glslp_t *glslp_parse(const char *f) { } void glslp_free(glslp_t *p) { - int i; - for (i = 0; i < p->num_shaders; ++i) + for (int i = 0; i < p->num_shaders; ++i) if (p->shaders[i].shader_program) free(p->shaders[i].shader_program); free(p); @@ -391,10 +411,9 @@ void glslp_free(glslp_t *p) { void glslp_read_shader_config(glslp_t *shader) { char s[512]; - int i; char *name = shader->name; - sprintf(s, "GL3 Shaders - %s", name); - for (i = 0; i < shader->num_parameters; ++i) { + snprintf(s, sizeof(s) -1, "GL3 Shaders - %s", name); + for (int i = 0; i < shader->num_parameters; ++i) { struct parameter *param = &shader->parameters[i]; param->value = config_get_double(s, param->id, param->default_value); } @@ -402,12 +421,11 @@ void glslp_read_shader_config(glslp_t *shader) { void glslp_write_shader_config(glslp_t *shader) { char s[512]; - int i; char *name = shader->name; startblit(); - sprintf(s, "GL3 Shaders - %s", name); - for (i = 0; i < shader->num_parameters; ++i) { + snprintf(s, sizeof(s) - 1, "GL3 Shaders - %s", name); + for (int i = 0; i < shader->num_parameters; ++i) { struct parameter *param = &shader->parameters[i]; config_set_double(s, param->id, param->value); } diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index 9e5563536..ae1c60971 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -199,7 +199,7 @@ HarddiskDialog::on_comboBoxFormat_currentIndexChanged(int index) * than a tenth of a percent change in size. */ static void -adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry) +adjust_86box_geometry_for_vhd(_86BoxGeom *_86box_geometry, MVHDGeom *vhd_geometry) { if (_86box_geometry->cyl <= 65535) { vhd_geometry->cyl = _86box_geometry->cyl; @@ -226,10 +226,10 @@ adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry) } static HarddiskDialog *callbackPtr = nullptr; -static MVHDGeom -create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint16_t cyl, uint8_t heads, uint8_t spt) +static _86BoxGeom +create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint32_t cyl, uint32_t heads, uint32_t spt) { - MVHDGeom _86box_geometry = { + _86BoxGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt @@ -256,10 +256,10 @@ create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint16_t cyl, return _86box_geometry; } -static MVHDGeom -create_drive_vhd_dynamic(const QString &fileName, uint16_t cyl, uint8_t heads, uint8_t spt, int blocksize) +static _86BoxGeom +create_drive_vhd_dynamic(const QString &fileName, uint32_t cyl, uint32_t heads, uint32_t spt, int blocksize) { - MVHDGeom _86box_geometry = { + _86BoxGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt @@ -287,7 +287,7 @@ create_drive_vhd_dynamic(const QString &fileName, uint16_t cyl, uint8_t heads, u return _86box_geometry; } -static MVHDGeom +static _86BoxGeom create_drive_vhd_diff(const QString &fileName, const QString &parentFileName, int blocksize) { int vhd_error = 0; @@ -299,25 +299,31 @@ create_drive_vhd_diff(const QString &fileName, const QString &parentFileName, in options.parent_path = parentFilenameBytes.data(); options.type = MVHD_TYPE_DIFF; - MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); - MVHDGeom vhd_geometry; + MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); + MVHDGeom vhd_geometry; + _86BoxGeom _86box_geometry; if (vhd == NULL) { - vhd_geometry.cyl = 0; - vhd_geometry.heads = 0; - vhd_geometry.spt = 0; + _86box_geometry.cyl = 0; + _86box_geometry.heads = 0; + _86box_geometry.spt = 0; } else { vhd_geometry = mvhd_get_geometry(vhd); if (vhd_geometry.spt > 63) { - vhd_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63); - vhd_geometry.heads = 16; - vhd_geometry.spt = 63; + _86box_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63); + _86box_geometry.heads = 16; + _86box_geometry.spt = 63; + } else { + _86box_geometry.cyl = vhd_geometry.cyl; + _86box_geometry.heads = vhd_geometry.heads; + _86box_geometry.spt = vhd_geometry.spt; } + mvhd_close(vhd); } - return vhd_geometry; + return _86box_geometry; } void @@ -409,7 +415,7 @@ HarddiskDialog::onCreateNewFile() } else if (img_format >= IMG_FMT_VHD_FIXED) { /* VHD file */ file.close(); - MVHDGeom _86box_geometry {}; + _86BoxGeom _86box_geometry {}; int block_size = ui->comboBoxBlockSize->currentIndex() == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; switch (img_format) { case IMG_FMT_VHD_FIXED: @@ -493,10 +499,14 @@ HarddiskDialog::onCreateNewFile() } static void -adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry) +adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry, _86BoxGeom *_86box_geometry) { - if (vhd_geometry->spt <= 63) + if (vhd_geometry->spt <= 63) { + _86box_geometry->cyl = vhd_geometry->cyl; + _86box_geometry->heads = vhd_geometry->heads; + _86box_geometry->spt = vhd_geometry->spt; return; + } int desired_sectors = vhd_geometry->cyl * vhd_geometry->heads * vhd_geometry->spt; if (desired_sectors > 267321600) @@ -506,9 +516,9 @@ adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry) if (remainder > 0) desired_sectors -= remainder; - vhd_geometry->cyl = desired_sectors / (16 * 63); - vhd_geometry->heads = 16; - vhd_geometry->spt = 63; + _86box_geometry->cyl = desired_sectors / (16 * 63); + _86box_geometry->heads = 16; + _86box_geometry->spt = 63; } void @@ -602,11 +612,12 @@ HarddiskDialog::onExistingFileSelected(const QString &fileName, bool precheck) } } - MVHDGeom vhd_geom = mvhd_get_geometry(vhd); - adjust_vhd_geometry_for_86box(&vhd_geom); - cylinders = vhd_geom.cyl; - heads = vhd_geom.heads; - sectors = vhd_geom.spt; + MVHDGeom vhd_geom = mvhd_get_geometry(vhd); + _86BoxGeom _86box_geom; + adjust_vhd_geometry_for_86box(&vhd_geom, &_86box_geom); + cylinders = _86box_geom.cyl; + heads = _86box_geom.heads; + sectors = _86box_geom.spt; size = static_cast(cylinders * heads * sectors * 512); mvhd_close(vhd); } else { diff --git a/src/qt/qt_harddiskdialog.hpp b/src/qt/qt_harddiskdialog.hpp index 9de61c51b..62ec6e963 100644 --- a/src/qt/qt_harddiskdialog.hpp +++ b/src/qt/qt_harddiskdialog.hpp @@ -64,4 +64,10 @@ private: void recalcSelection(); }; +typedef struct _86BoxGeom { + uint32_t cyl; + uint32_t heads; + uint32_t spt; +} _86BoxGeom; + #endif // QT_HARDDISKDIALOG_HPP diff --git a/src/qt/qt_harddiskdialog.ui b/src/qt/qt_harddiskdialog.ui index cba835134..e2dea0220 100644 --- a/src/qt/qt_harddiskdialog.ui +++ b/src/qt/qt_harddiskdialog.ui @@ -32,87 +32,24 @@ Dialog - - - - false - - - 0 - - - true - - - - - + + - Sectors: - - - - - - - Image Format: - - - - - - - 30 - - - - - - - Bus: + File name: - - + + - Type: + Cylinders: - - - - - 0 - 0 - - - - - 64 - 16777215 - - - - 32767 - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - + @@ -128,58 +65,14 @@ - + Heads: - - - - - 0 - 0 - - - - - 64 - 16777215 - - - - - - - - 30 - - - - - - - Cylinders: - - - - - - - File name: - - - - - - - Size (MB): - - - - + @@ -198,28 +91,153 @@ - - + + - Channel: + Sectors: - + + + + + 0 + 0 + + + + + 64 + 16777215 + + + + 32767 + + + + + + + Size (MB): + + + + + + + + 0 + 0 + + + + + 64 + 16777215 + + + + + + + + Type: + + + + 30 - + + + + Bus: + + + + + + + 30 + + + + + + + Channel: + + + + + + + 30 + + + + + + + Model: + + + + + + + 30 + + + + + + + Image Format: + + + + + + + 30 + + + + Block Size: - + + + + 30 + + + + + + + false + + + 0 + + + true + + + + Qt::Vertical @@ -232,31 +250,13 @@ - - - - Model: + + + + Qt::Horizontal - - - - - - 30 - - - - - - - 30 - - - - - - - 30 + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -270,17 +270,6 @@ 1 - - lineEditCylinders - lineEditHeads - lineEditSectors - lineEditSize - comboBoxType - comboBoxBus - comboBoxChannel - comboBoxFormat - comboBoxBlockSize - diff --git a/src/qt/qt_harddrive_common.cpp b/src/qt/qt_harddrive_common.cpp index 52ae10a98..b0c8e0ea9 100644 --- a/src/qt/qt_harddrive_common.cpp +++ b/src/qt/qt_harddrive_common.cpp @@ -32,6 +32,7 @@ Harddrives::populateBuses(QAbstractItemModel *model) { model->removeRows(0, model->rowCount()); model->insertRows(0, 6); + model->setData(model->index(0, 0), "MFM/RLL"); model->setData(model->index(1, 0), "XTA"); model->setData(model->index(2, 0), "ESDI"); @@ -48,19 +49,23 @@ Harddrives::populateBuses(QAbstractItemModel *model) } void -Harddrives::populateRemovableBuses(QAbstractItemModel *model) +Harddrives::populateCDROMBuses(QAbstractItemModel *model) { model->removeRows(0, model->rowCount()); #ifdef USE_CDROM_MITSUMI - model->insertRows(0, 4); + model->insertRows(0, 5); #else - model->insertRows(0, 3); + model->insertRows(0, 4); #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")); #ifdef USE_CDROM_MITSUMI model->setData(model->index(3, 0), QObject::tr("Mitsumi")); + model->setData(model->index(4, 0), QObject::tr("Panasonic/MKE")); +#else + model->setData(model->index(3, 0), QObject::tr("Panasonic/MKE")); #endif model->setData(model->index(0, 0), HDD_BUS_DISABLED, Qt::UserRole); @@ -68,9 +73,27 @@ Harddrives::populateRemovableBuses(QAbstractItemModel *model) model->setData(model->index(2, 0), HDD_BUS_SCSI, Qt::UserRole); #ifdef USE_CDROM_MITSUMI model->setData(model->index(3, 0), CDROM_BUS_MITSUMI, Qt::UserRole); + model->setData(model->index(4, 0), CDROM_BUS_MKE, Qt::UserRole); +#else + model->setData(model->index(3, 0), CDROM_BUS_MKE, Qt::UserRole); #endif } +void +Harddrives::populateRemovableBuses(QAbstractItemModel *model) +{ + model->removeRows(0, model->rowCount()); + model->insertRows(0, 3); + + 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")); + + 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); +} + void Harddrives::populateSpeeds(QAbstractItemModel *model, int bus) { @@ -138,6 +161,12 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusT subChannelWidth = 2; busesToCheck.append(HDD_BUS_SCSI); break; + case CDROM_BUS_MKE: + shifter = 2; + orer = 3; + busRows = 4; + busesToCheck.append(CDROM_BUS_MKE); + break; default: break; } @@ -186,9 +215,12 @@ Harddrives::BusChannelName(uint8_t bus, uint8_t channel) case HDD_BUS_SCSI: busName = QString("SCSI (%1:%2)").arg(channel >> 4).arg(channel & 15, 2, 10, QChar('0')); break; - case CDROM_BUS_MITSUMI: - busName = QString("Mitsumi"); - break; + case CDROM_BUS_MITSUMI: + busName = QString("Mitsumi"); + break; + case CDROM_BUS_MKE: + busName = QString("Panasonic/MKE (%1:%2)").arg(channel >> 2).arg(channel & 3); + break; } return busName; diff --git a/src/qt/qt_harddrive_common.hpp b/src/qt/qt_harddrive_common.hpp index 28189f328..f989711f2 100644 --- a/src/qt/qt_harddrive_common.hpp +++ b/src/qt/qt_harddrive_common.hpp @@ -9,6 +9,7 @@ class SettingsBusTracking; namespace Harddrives { void populateBuses(QAbstractItemModel *model); +void populateCDROMBuses(QAbstractItemModel *model); void populateRemovableBuses(QAbstractItemModel *model); void populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusTracking *sbt = nullptr); void populateSpeeds(QAbstractItemModel *model, int bus); diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp deleted file mode 100644 index fb84606b0..000000000 --- a/src/qt/qt_hardwarerenderer.cpp +++ /dev/null @@ -1,257 +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. - * - * Hardware renderer module. - * - * - * - * Authors: Joakim L. Gilje - * Cacodemon345 - * Teemu Korhonen - * - * Copyright 2021 Joakim L. Gilje - * Copyright 2021-2022 Cacodemon345 - * Copyright 2021-2022 Teemu Korhonen - */ -#include "qt_hardwarerenderer.hpp" -#include -#include -#include - -#include -#include -#include - -extern "C" { -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/video.h> -} - -void -HardwareRenderer::resizeGL(int w, int h) -{ - m_context->makeCurrent(this); - glViewport(0, 0, qRound(w * devicePixelRatioF()), qRound(h * devicePixelRatioF())); -} - -#define PROGRAM_VERTEX_ATTRIBUTE 0 -#define PROGRAM_TEXCOORD_ATTRIBUTE 1 - -void -HardwareRenderer::initializeGL() -{ - m_context->makeCurrent(this); - initializeOpenGLFunctions(); - auto image = QImage(2048, 2048, QImage::Format_RGB32); - image.fill(0xff000000); - m_texture = new QOpenGLTexture(image); - m_blt = new QOpenGLTextureBlitter; - m_blt->setRedBlueSwizzle(true); - m_blt->create(); - QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this); - const char *vsrc = "attribute highp vec4 VertexCoord;\n" - "attribute mediump vec4 TexCoord;\n" - "varying mediump vec4 texc;\n" - "uniform mediump mat4 MVPMatrix;\n" - "void main(void)\n" - "{\n" - " gl_Position = MVPMatrix * VertexCoord;\n" - " texc = TexCoord;\n" - "}\n"; - QString vsrccore = "in highp vec4 VertexCoord;\n" - "in mediump vec4 TexCoord;\n" - "out mediump vec4 texc;\n" - "uniform mediump mat4 MVPMatrix;\n" - "void main(void)\n" - "{\n" - " gl_Position = MVPMatrix * VertexCoord;\n" - " texc = TexCoord;\n" - "}\n"; - if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) { - vsrccore.prepend("#version 300 es\n"); - vshader->compileSourceCode(vsrccore); - } else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) { - vsrccore.prepend("#version 130\n"); - vshader->compileSourceCode(vsrccore); - } else - vshader->compileSourceCode(vsrc); - - QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this); - const char *fsrc = "uniform sampler2D texture;\n" - "varying mediump vec4 texc;\n" - "void main(void)\n" - "{\n" - " gl_FragColor = texture2D(texture, texc.st).bgra;\n" - "}\n"; - QString fsrccore = "uniform sampler2D texture;\n" - "in mediump vec4 texc;\n" - "out highp vec4 FragColor;\n" - "void main(void)\n" - "{\n" - " FragColor = texture2D(texture, texc.st).bgra;\n" - "}\n"; - if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) { - fsrccore.prepend("#version 300 es\n"); - fshader->compileSourceCode(fsrccore); - } else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) { - fsrccore.prepend("#version 130\n"); - fshader->compileSourceCode(fsrccore); - } else - fshader->compileSourceCode(fsrc); - - m_prog = new QOpenGLShaderProgram; - m_prog->addShader(vshader); - m_prog->addShader(fshader); - m_prog->bindAttributeLocation("VertexCoord", PROGRAM_VERTEX_ATTRIBUTE); - m_prog->bindAttributeLocation("TexCoord", PROGRAM_TEXCOORD_ATTRIBUTE); - m_prog->link(); - - m_prog->bind(); - m_prog->setUniformValue("texture", 0); - - if (m_context->format().version() >= qMakePair(3, 0) && m_vao.create()) { - m_vao.bind(); - } - - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].create(); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].allocate(sizeof(QVector2D) * 4); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].create(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].allocate(sizeof(QVector2D) * 4); - - pclog("OpenGL vendor: %s\n", glGetString(GL_VENDOR)); - pclog("OpenGL renderer: %s\n", glGetString(GL_RENDERER)); - pclog("OpenGL version: %s\n", glGetString(GL_VERSION)); - pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); - glClearColor(0, 0, 0, 1); - m_texture->setWrapMode(QOpenGLTexture::ClampToEdge); - glClear(GL_COLOR_BUFFER_BIT); - m_context->swapBuffers(this); -} - -void -HardwareRenderer::paintGL() -{ - m_context->makeCurrent(this); - glClear(GL_COLOR_BUFFER_BIT); - QVector verts; - QVector texcoords; - QMatrix4x4 mat; - mat.setToIdentity(); - mat.ortho(QRectF(0, 0, (qreal) width() * (qreal) devicePixelRatioF(), (qreal) height() * (qreal) devicePixelRatioF())); - verts.push_back(QVector2D((float) destination.x(), (float) destination.y())); - verts.push_back(QVector2D((float) destination.x(), (float) destination.y() + (float) destination.height())); - verts.push_back(QVector2D((float) destination.x() + (float) destination.width(), (float) destination.y() + (float) destination.height())); - verts.push_back(QVector2D((float) destination.x() + (float) destination.width(), (float) destination.y())); - texcoords.push_back(QVector2D((float) source.x() / 2048.f, (float) (source.y()) / 2048.f)); - texcoords.push_back(QVector2D((float) source.x() / 2048.f, (float) (source.y() + source.height()) / 2048.f)); - texcoords.push_back(QVector2D((float) (source.x() + source.width()) / 2048.f, (float) (source.y() + source.height()) / 2048.f)); - texcoords.push_back(QVector2D((float) (source.x() + source.width()) / 2048.f, (float) (source.y()) / 2048.f)); - - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].write(0, verts.data(), sizeof(QVector2D) * 4); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].write(0, texcoords.data(), sizeof(QVector2D) * 4); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); - - m_prog->setUniformValue("MVPMatrix", mat); - m_prog->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE); - m_prog->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE); - - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); - m_prog->setAttributeBuffer(PROGRAM_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 2, 0); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); - m_prog->setAttributeBuffer(PROGRAM_TEXCOORD_ATTRIBUTE, GL_FLOAT, 0, 2, 0); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); - m_texture->bind(); - m_texture->setMinMagFilters(video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest, video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); -} - -void -HardwareRenderer::setRenderType(RenderType type) -{ - QSurfaceFormat format; - switch (type) { - case RenderType::OpenGL3: - format.setVersion(3, 0); - format.setProfile(QSurfaceFormat::CoreProfile); - case RenderType::OpenGL: - format.setRenderableType(QSurfaceFormat::OpenGL); - break; - case RenderType::OpenGLES: - format.setRenderableType(QSurfaceFormat::OpenGLES); - break; - } - format.setSwapInterval(0); - setFormat(format); -} - -void -HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) -{ - auto tval = this; - void *nuldata = 0; - if (memcmp(&tval, &nuldata, sizeof(void *)) == 0) - return; - auto origSource = source; - if (!m_texture || !m_texture->isCreated()) { - buf_usage[buf_idx].clear(); - source.setRect(x, y, w, h); - return; - } - m_context->makeCurrent(this); -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - m_texture->setData(x, y, 0, w, h, 0, QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void *) ((uintptr_t) imagebufs[buf_idx].get() + (uintptr_t) (2048 * 4 * y + x * 4)), &m_transferOptions); -#else - m_texture->bind(); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 2048); - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void *) ((uintptr_t) imagebufs[buf_idx].get() + (uintptr_t) (2048 * 4 * y + x * 4))); - m_texture->release(); -#endif - buf_usage[buf_idx].clear(); - source.setRect(x, y, w, h); - if (origSource != source) { - this->pixelRatio = devicePixelRatioF(); - onResize(this->width(), this->height()); - } - update(); -} - -void -HardwareRenderer::resizeEvent(QResizeEvent *event) -{ - this->pixelRatio = devicePixelRatioF(); - onResize(width(), height()); - - QOpenGLWindow::resizeEvent(event); -} - -bool -HardwareRenderer::event(QEvent *event) -{ - bool res = false; - if (!eventDelegate(event, res)) - return QOpenGLWindow::event(event); - return res; -} - -std::vector> -HardwareRenderer::getBuffers() -{ - std::vector> buffers; - - buffers.push_back(std::make_tuple(imagebufs[0].get(), &buf_usage[0])); - buffers.push_back(std::make_tuple(imagebufs[1].get(), &buf_usage[1])); - - return buffers; -} diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp deleted file mode 100644 index f7861d2bd..000000000 --- a/src/qt/qt_hardwarerenderer.hpp +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "qt_renderercommon.hpp" - -#ifdef WAYLAND -# include "wl_mouse.hpp" -#endif - -class HardwareRenderer : public QOpenGLWindow, protected QOpenGLFunctions, public RendererCommon { - Q_OBJECT - -private: - bool wayland = false; - QOpenGLContext *m_context; - QOpenGLTexture *m_texture { nullptr }; - QOpenGLShaderProgram *m_prog { nullptr }; - QOpenGLTextureBlitter *m_blt { nullptr }; - QOpenGLBuffer m_vbo[2]; - QOpenGLVertexArrayObject m_vao; - QOpenGLPixelTransferOptions m_transferOptions; - -public: - enum class RenderType { - OpenGL, - OpenGLES, - OpenGL3, - }; - void resizeGL(int w, int h) override; - void initializeGL() override; - void paintGL() override; - void exposeEvent(QExposeEvent *event) override - { - onResize(size().width(), size().height()); - } - - std::vector> getBuffers() override; - HardwareRenderer(QWidget *parent = nullptr, RenderType rtype = RenderType::OpenGL) - : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()) - , QOpenGLFunctions() - { - imagebufs[0] = std::unique_ptr(new uint8_t[2048 * 2048 * 4]); - imagebufs[1] = std::unique_ptr(new uint8_t[2048 * 2048 * 4]); - - buf_usage = std::vector(2); - buf_usage[0].clear(); - buf_usage[1].clear(); - - setMinimumSize(QSize(16, 16)); - setFlags(Qt::FramelessWindowHint); - parentWidget = parent; - setRenderType(rtype); - - m_transferOptions.setRowLength(2048); - - m_context = new QOpenGLContext(); - m_context->setFormat(format()); - m_context->create(); - update(); - } - ~HardwareRenderer() - { - m_context->makeCurrent(this); - if (m_blt) - m_blt->destroy(); - m_prog->release(); - delete m_prog; - m_prog = nullptr; - m_context->doneCurrent(); - delete m_context; - } - - void setRenderType(RenderType type); - -public slots: - void onBlit(int buf_idx, int x, int y, int w, int h); - -protected: - std::array, 2> imagebufs; - - void resizeEvent(QResizeEvent *event) override; - bool event(QEvent *event) override; -}; diff --git a/src/qt/qt_iconindicators.cpp b/src/qt/qt_iconindicators.cpp index d5d22c78d..169910b21 100644 --- a/src/qt/qt_iconindicators.cpp +++ b/src/qt/qt_iconindicators.cpp @@ -12,6 +12,16 @@ getIndicatorIcon(IconIndicator indicator) return QIcon(":/settings/qt/icons/write_active.ico"); case Disabled: return QIcon(":/settings/qt/icons/disabled.ico"); + case WriteProtected: + return QIcon(":/settings/qt/icons/write_protected.ico"); + case New: + return QIcon(":/settings/qt/icons/new.ico"); + case Browse: + return QIcon(":/settings/qt/icons/browse.ico"); + case Eject: + return QIcon(":/settings/qt/icons/eject.ico"); + case Export: + return QIcon(":/settings/qt/icons/eject.ico"); default: return QIcon(); } @@ -26,14 +36,20 @@ getIconWithIndicator(const QIcon &icon, const QSize &size, QIcon::Mode iconMode, return iconPixmap; auto painter = QPainter(&iconPixmap); - auto indicatorPixmap = getIndicatorIcon(indicator == ReadWriteActive ? Active : indicator).pixmap(size); + auto indicatorPixmap = getIndicatorIcon((indicator == ReadWriteActive || indicator == WriteProtectedActive) ? Active : indicator).pixmap(size); + + if (indicator == WriteProtectedBrowse) + indicatorPixmap = getIndicatorIcon(WriteProtected).pixmap(size); painter.drawPixmap(0, 0, indicatorPixmap); - if (indicator == ReadWriteActive) { - auto writeIndicatorPixmap = getIndicatorIcon(WriteActive).pixmap(size); + if ((indicator == ReadWriteActive) || (indicator == WriteProtectedActive)) { + auto writeIndicatorPixmap = getIndicatorIcon(indicator == WriteProtectedActive ? WriteProtected : WriteActive).pixmap(size); painter.drawPixmap(0, 0, writeIndicatorPixmap); + } else if (indicator == WriteProtectedBrowse) { + auto browseIndicatorPixmap = getIndicatorIcon(Browse).pixmap(size); + painter.drawPixmap(0, 0, browseIndicatorPixmap); } painter.end(); return iconPixmap; -} \ No newline at end of file +} diff --git a/src/qt/qt_iconindicators.hpp b/src/qt/qt_iconindicators.hpp index 12f82f259..c3c8946ad 100644 --- a/src/qt/qt_iconindicators.hpp +++ b/src/qt/qt_iconindicators.hpp @@ -10,6 +10,13 @@ enum IconIndicator { WriteActive, ReadWriteActive, Disabled, + WriteProtected, + WriteProtectedActive, + New, + Browse, + WriteProtectedBrowse, + Export, + Eject }; QPixmap getIconWithIndicator(const QIcon &icon, const QSize &size, QIcon::Mode iconMode, IconIndicator indicator); diff --git a/src/qt/qt_keybind.cpp b/src/qt/qt_keybind.cpp index c7ed894b3..e6e87a5e2 100644 --- a/src/qt/qt_keybind.cpp +++ b/src/qt/qt_keybind.cpp @@ -90,7 +90,7 @@ KeyBinder::BindKey(QWidget* widget, QString CurValue) KeyBinder kb(widget); kb.setWindowTitle(tr("Bind Key")); kb.setFixedSize(kb.minimumSizeHint()); - kb.findChild()->setKeySequence(QKeySequence::fromString(CurValue)); + kb.findChild()->setKeySequence(QKeySequence::fromString(CurValue, QKeySequence::NativeText)); kb.setEnabled(true); if (kb.exec() == QDialog::Accepted) { diff --git a/src/qt/qt_keybind.hpp b/src/qt/qt_keybind.hpp index 393ee0f5c..25f4a9168 100644 --- a/src/qt/qt_keybind.hpp +++ b/src/qt/qt_keybind.hpp @@ -26,8 +26,8 @@ public: private: Ui::KeyBinder *ui; - bool eventFilter(QObject *obj, QEvent *event); - void showEvent( QShowEvent* event ); + bool eventFilter(QObject *obj, QEvent *event) override; + void showEvent( QShowEvent* event ) override; }; #endif // QT_KeyBinder_HPP diff --git a/src/qt/qt_keybind.ui b/src/qt/qt_keybind.ui index 835e12020..7bd8a8a62 100644 --- a/src/qt/qt_keybind.ui +++ b/src/qt/qt_keybind.ui @@ -22,7 +22,7 @@ Enter key combo: - Qt::AlignmentFlag::AlignCenter + Qt::AlignCenter @@ -31,17 +31,17 @@ - Qt::Orientation::Horizontal + Qt::Horizontal - Qt::Orientation::Horizontal + Qt::Horizontal - QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::Ok diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index db32569f3..6ff25d60f 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -31,7 +31,7 @@ extern "C" { #include <86box/hdc.h> #include <86box/scsi.h> #include <86box/scsi_device.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/mo.h> #include <86box/plat.h> #include <86box/machine.h> @@ -91,6 +91,8 @@ struct PixmapSetEmptyActive { QPixmap read_write_active; QPixmap empty_write_active; QPixmap empty_read_write_active; + QPixmap wp; + QPixmap wp_active; void load(const QIcon &icon); }; struct Pixmaps { @@ -100,7 +102,7 @@ struct Pixmaps { PixmapSetEmptyActive floppy_525; PixmapSetEmptyActive floppy_35; PixmapSetEmptyActive cdrom; - PixmapSetEmptyActive zip; + PixmapSetEmptyActive rdisk; PixmapSetEmptyActive mo; PixmapSetActive hd; PixmapSetEmptyActive net; @@ -168,6 +170,7 @@ struct StateEmptyActive { bool empty = false; bool active = false; bool write_active = false; + bool wp = false; void setActive(bool b) { @@ -193,6 +196,14 @@ struct StateEmptyActive { empty = b; refresh(); } + void setWriteProtected(bool b) + { + if (!label || b == wp) + return; + + wp = b; + refresh(); + } void refresh() { if (!label) @@ -203,7 +214,9 @@ struct StateEmptyActive { else label->setPixmap(write_active ? pixmaps->empty_write_active : (active ? pixmaps->empty_active : pixmaps->empty)); } else { - if (active && write_active) + if (wp) + label->setPixmap(active ? pixmaps->wp_active : pixmaps->wp); + else if (active && write_active) label->setPixmap(pixmaps->read_write_active); else label->setPixmap(write_active ? pixmaps->write_active : (active ? pixmaps->active : pixmaps->normal)); @@ -241,6 +254,8 @@ void PixmapSetEmptyActive::load(const QIcon &icon) { normal = getIconWithIndicator(icon, pixmap_size, QIcon::Normal, None); + wp = getIconWithIndicator(icon, pixmap_size, QIcon::Normal, WriteProtected); + wp_active = getIconWithIndicator(icon, pixmap_size, QIcon::Normal, WriteProtectedActive); active = getIconWithIndicator(icon, pixmap_size, QIcon::Normal, Active); write_active = getIconWithIndicator(icon, pixmap_size, QIcon::Normal, WriteActive); read_write_active = getIconWithIndicator(icon, pixmap_size, QIcon::Normal, ReadWriteActive); @@ -268,7 +283,7 @@ struct MachineStatus::States { pixmaps.floppy_525.load(QIcon(":/settings/qt/icons/floppy_525.ico")); pixmaps.floppy_35.load(QIcon(":/settings/qt/icons/floppy_35.ico")); pixmaps.cdrom.load(QIcon(":/settings/qt/icons/cdrom.ico")); - pixmaps.zip.load(QIcon(":/settings/qt/icons/zip.ico")); + pixmaps.rdisk.load(QIcon(":/settings/qt/icons/rdisk.ico")); pixmaps.mo.load(QIcon(":/settings/qt/icons/mo.ico")); pixmaps.hd.load(QIcon(":/settings/qt/icons/hard_disk.ico")); pixmaps.net.load(QIcon(":/settings/qt/icons/network.ico")); @@ -283,8 +298,8 @@ struct MachineStatus::States { for (auto &c : cdrom) { c.pixmaps = &pixmaps.cdrom; } - for (auto &z : zip) { - z.pixmaps = &pixmaps.zip; + for (auto &z : rdisk) { + z.pixmaps = &pixmaps.rdisk; } for (auto &m : mo) { m.pixmaps = &pixmaps.mo; @@ -301,7 +316,7 @@ struct MachineStatus::States { StateEmptyActive cassette; std::array fdd; std::array cdrom; - std::array zip; + std::array rdisk; std::array mo; std::array hdds; std::array net; @@ -373,7 +388,7 @@ MachineStatus::iterateCDROM(const std::function &cb) (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; - if ((cdrom[i].bus_type == CDROM_BUS_MITSUMI) && (cdrom_interface_current == 0)) + if ((cdrom[i].bus_type == CDROM_BUS_MITSUMI || cdrom[i].bus_type == CDROM_BUS_MKE) && (cdrom_interface_current == 0)) continue; if (cdrom[i].bus_type != 0) { cb(i); @@ -382,21 +397,21 @@ MachineStatus::iterateCDROM(const std::function &cb) } void -MachineStatus::iterateZIP(const std::function &cb) +MachineStatus::iterateRDisk(const std::function &cb) { auto hdc_name = QString(hdc_get_internal_name(hdc_current[0])); - for (size_t i = 0; i < ZIP_NUM; i++) { + for (size_t i = 0; i < RDISK_NUM; i++) { /* Could be Internal or External IDE.. */ - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !hasIDE() && + if ((rdisk_drives[i].bus_type == RDISK_BUS_ATAPI) && !hasIDE() && (hdc_name.left(3) != QStringLiteral("ide")) && (hdc_name.left(5) != QStringLiteral("xtide")) && (hdc_name.left(5) != QStringLiteral("mcide"))) continue; - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !hasSCSI() && + if ((rdisk_drives[i].bus_type == RDISK_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; - if (zip_drives[i].bus_type != 0) { + if (rdisk_drives[i].bus_type != 0) { cb(i); } } @@ -454,16 +469,23 @@ MachineStatus::refreshEmptyIcons() if (!sbar_initialized) return; - for (size_t i = 0; i < FDD_NUM; ++i) + for (size_t i = 0; i < FDD_NUM; ++i) { d->fdd[i].setEmpty(machine_status.fdd[i].empty); + d->fdd[i].setWriteProtected(machine_status.fdd[i].write_prot); + } for (size_t i = 0; i < CDROM_NUM; ++i) d->cdrom[i].setEmpty(machine_status.cdrom[i].empty); - for (size_t i = 0; i < ZIP_NUM; i++) - d->zip[i].setEmpty(machine_status.zip[i].empty); - for (size_t i = 0; i < MO_NUM; i++) + for (size_t i = 0; i < RDISK_NUM; i++) { + d->rdisk[i].setEmpty(machine_status.rdisk[i].empty); + d->rdisk[i].setWriteProtected(machine_status.rdisk[i].write_prot); + } + for (size_t i = 0; i < MO_NUM; i++) { d->mo[i].setEmpty(machine_status.mo[i].empty); + d->mo[i].setWriteProtected(machine_status.mo[i].write_prot); + } d->cassette.setEmpty(machine_status.cassette.empty); + d->cassette.setWriteProtected(machine_status.cassette.write_prot); for (size_t i = 0; i < NET_CARD_MAX; i++) d->net[i].setEmpty(machine_status.net[i].empty); @@ -493,13 +515,13 @@ MachineStatus::refreshIcons() ui_sb_update_icon_write(SB_CDROM | i, 0); } } - for (size_t i = 0; i < ZIP_NUM; i++) { - d->zip[i].setActive(machine_status.zip[i].active); - d->zip[i].setWriteActive(machine_status.zip[i].write_active); - if (machine_status.zip[i].active) - ui_sb_update_icon(SB_ZIP | i, 0); - if (machine_status.zip[i].write_active) - ui_sb_update_icon_write(SB_ZIP | i, 0); + for (size_t i = 0; i < RDISK_NUM; i++) { + d->rdisk[i].setActive(machine_status.rdisk[i].active); + d->rdisk[i].setWriteActive(machine_status.rdisk[i].write_active); + if (machine_status.rdisk[i].active) + ui_sb_update_icon(SB_RDISK | i, 0); + if (machine_status.rdisk[i].write_active) + ui_sb_update_icon_write(SB_RDISK | i, 0); } for (size_t i = 0; i < MO_NUM; i++) { d->mo[i].setActive(machine_status.mo[i].active); @@ -536,9 +558,9 @@ MachineStatus::clearActivity() cdrom.setActive(false); cdrom.setWriteActive(false); } - for (auto &zip : d->zip) { - zip.setActive(false); - zip.setWriteActive(false); + for (auto &rdisk : d->rdisk) { + rdisk.setActive(false); + rdisk.setWriteActive(false); } for (auto &mo : d->mo) { mo.setActive(false); @@ -578,8 +600,8 @@ MachineStatus::refresh(QStatusBar *sbar) for (size_t i = 0; i < CDROM_NUM; i++) { sbar->removeWidget(d->cdrom[i].label.get()); } - for (size_t i = 0; i < ZIP_NUM; i++) { - sbar->removeWidget(d->zip[i].label.get()); + for (size_t i = 0; i < RDISK_NUM; i++) { + sbar->removeWidget(d->rdisk[i].label.get()); } for (size_t i = 0; i < MO_NUM; i++) { sbar->removeWidget(d->mo[i].label.get()); @@ -595,6 +617,12 @@ MachineStatus::refresh(QStatusBar *sbar) if (cassette_enable) { d->cassette.label = std::make_unique(); d->cassette.setEmpty(QString(cassette_fname).isEmpty()); + if (QString(cassette_fname).isEmpty()) + d->cassette.setWriteProtected(false); + else if (QString(cassette_fname).left(5) == "wp://") + d->cassette.setWriteProtected(true); + else + d->cassette.setWriteProtected(cassette_ui_writeprot); d->cassette.refresh(); connect((ClickableLabel *) d->cassette.label.get(), &ClickableLabel::clicked, [](QPoint pos) { MediaMenu::ptr->cassetteMenu->popup(pos - QPoint(0, MediaMenu::ptr->cassetteMenu->sizeHint().height())); @@ -602,7 +630,7 @@ MachineStatus::refresh(QStatusBar *sbar) connect((ClickableLabel *) d->cassette.label.get(), &ClickableLabel::dropped, [](QString str) { MediaMenu::ptr->cassetteMount(str, false); }); - d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title()); + d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->toolTip()); d->cassette.label->setAcceptDrops(true); sbar->addWidget(d->cassette.label.get()); } @@ -618,7 +646,7 @@ MachineStatus::refresh(QStatusBar *sbar) connect((ClickableLabel *) d->cartridge[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->cartridgeMount(i, str); }); - d->cartridge[i].label->setToolTip(MediaMenu::ptr->cartridgeMenus[i]->title()); + d->cartridge[i].label->setToolTip(MediaMenu::ptr->cartridgeMenus[i]->toolTip()); d->cartridge[i].label->setAcceptDrops(true); sbar->addWidget(d->cartridge[i].label.get()); } @@ -635,6 +663,12 @@ MachineStatus::refresh(QStatusBar *sbar) } d->fdd[i].label = std::make_unique(); d->fdd[i].setEmpty(QString(floppyfns[i]).isEmpty()); + if (QString(floppyfns[i]).isEmpty()) + d->fdd[i].setWriteProtected(false); + else if (QString(floppyfns[i]).left(5) == "wp://") + d->fdd[i].setWriteProtected(true); + else + d->fdd[i].setWriteProtected(ui_writeprot[i]); d->fdd[i].setActive(false); d->fdd[i].setWriteActive(false); d->fdd[i].refresh(); @@ -644,7 +678,7 @@ MachineStatus::refresh(QStatusBar *sbar) connect((ClickableLabel *) d->fdd[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->floppyMount(i, str, false); }); - d->fdd[i].label->setToolTip(MediaMenu::ptr->floppyMenus[i]->title()); + d->fdd[i].label->setToolTip(MediaMenu::ptr->floppyMenus[i]->toolTip()); d->fdd[i].label->setAcceptDrops(true); sbar->addWidget(d->fdd[i].label.get()); }); @@ -661,31 +695,43 @@ MachineStatus::refresh(QStatusBar *sbar) connect((ClickableLabel *) d->cdrom[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->cdromMount(i, str); }); - d->cdrom[i].label->setToolTip(MediaMenu::ptr->cdromMenus[i]->title()); + d->cdrom[i].label->setToolTip(MediaMenu::ptr->cdromMenus[i]->toolTip()); d->cdrom[i].label->setAcceptDrops(true); sbar->addWidget(d->cdrom[i].label.get()); }); - iterateZIP([this, sbar](int i) { - d->zip[i].label = std::make_unique(); - d->zip[i].setEmpty(QString(zip_drives[i].image_path).isEmpty()); - d->zip[i].setActive(false); - d->zip[i].setWriteActive(false); - d->zip[i].refresh(); - connect((ClickableLabel *) d->zip[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { - MediaMenu::ptr->zipMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->zipMenus[i]->sizeHint().height())); + iterateRDisk([this, sbar](int i) { + d->rdisk[i].label = std::make_unique(); + d->rdisk[i].setEmpty(QString(rdisk_drives[i].image_path).isEmpty()); + if (QString(rdisk_drives[i].image_path).isEmpty()) + d->rdisk[i].setWriteProtected(false); + else if (QString(rdisk_drives[i].image_path).left(5) == "wp://") + d->rdisk[i].setWriteProtected(true); + else + d->rdisk[i].setWriteProtected(rdisk_drives[i].read_only); + d->rdisk[i].setActive(false); + d->rdisk[i].setWriteActive(false); + d->rdisk[i].refresh(); + connect((ClickableLabel *) d->rdisk[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + MediaMenu::ptr->rdiskMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->rdiskMenus[i]->sizeHint().height())); }); - connect((ClickableLabel *) d->zip[i].label.get(), &ClickableLabel::dropped, [i](QString str) { - MediaMenu::ptr->zipMount(i, str, false); + connect((ClickableLabel *) d->rdisk[i].label.get(), &ClickableLabel::dropped, [i](QString str) { + MediaMenu::ptr->rdiskMount(i, str, false); }); - d->zip[i].label->setToolTip(MediaMenu::ptr->zipMenus[i]->title()); - d->zip[i].label->setAcceptDrops(true); - sbar->addWidget(d->zip[i].label.get()); + d->rdisk[i].label->setToolTip(MediaMenu::ptr->rdiskMenus[i]->toolTip()); + d->rdisk[i].label->setAcceptDrops(true); + sbar->addWidget(d->rdisk[i].label.get()); }); iterateMO([this, sbar](int i) { d->mo[i].label = std::make_unique(); d->mo[i].setEmpty(QString(mo_drives[i].image_path).isEmpty()); + if (QString(rdisk_drives[i].image_path).isEmpty()) + d->mo[i].setWriteProtected(false); + else if (QString(rdisk_drives[i].image_path).left(5) == "wp://") + d->mo[i].setWriteProtected(true); + else + d->mo[i].setWriteProtected(rdisk_drives[i].read_only); d->mo[i].setActive(false); d->mo[i].setWriteActive(false); d->mo[i].refresh(); @@ -695,7 +741,7 @@ MachineStatus::refresh(QStatusBar *sbar) connect((ClickableLabel *) d->mo[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->moMount(i, str, false); }); - d->mo[i].label->setToolTip(MediaMenu::ptr->moMenus[i]->title()); + d->mo[i].label->setToolTip(MediaMenu::ptr->moMenus[i]->toolTip()); d->mo[i].label->setAcceptDrops(true); sbar->addWidget(d->mo[i].label.get()); }); @@ -706,7 +752,7 @@ MachineStatus::refresh(QStatusBar *sbar) d->net[i].setActive(false); d->net[i].setWriteActive(false); d->net[i].refresh(); - d->net[i].label->setToolTip(MediaMenu::ptr->netMenus[i]->title()); + d->net[i].label->setToolTip(MediaMenu::ptr->netMenus[i]->toolTip()); connect((ClickableLabel *) d->net[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { MediaMenu::ptr->netMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->netMenus[i]->sizeHint().height())); }); @@ -864,27 +910,27 @@ MachineStatus::updateTip(int tag) switch (category) { case SB_CASSETTE: if (d->cassette.label && MediaMenu::ptr->cassetteMenu) - d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title()); + d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->toolTip()); break; case SB_CARTRIDGE: if (d->cartridge[item].label && MediaMenu::ptr->cartridgeMenus[item]) - d->cartridge[item].label->setToolTip(MediaMenu::ptr->cartridgeMenus[item]->title()); + d->cartridge[item].label->setToolTip(MediaMenu::ptr->cartridgeMenus[item]->toolTip()); break; case SB_FLOPPY: if (d->fdd[item].label && MediaMenu::ptr->floppyMenus[item]) - d->fdd[item].label->setToolTip(MediaMenu::ptr->floppyMenus[item]->title()); + d->fdd[item].label->setToolTip(MediaMenu::ptr->floppyMenus[item]->toolTip()); break; case SB_CDROM: if (d->cdrom[item].label && MediaMenu::ptr->cdromMenus[item]) - d->cdrom[item].label->setToolTip(MediaMenu::ptr->cdromMenus[item]->title()); + d->cdrom[item].label->setToolTip(MediaMenu::ptr->cdromMenus[item]->toolTip()); break; - case SB_ZIP: - if (d->zip[item].label && MediaMenu::ptr->zipMenus[item]) - d->zip[item].label->setToolTip(MediaMenu::ptr->zipMenus[item]->title()); + case SB_RDISK: + if (d->rdisk[item].label && MediaMenu::ptr->rdiskMenus[item]) + d->rdisk[item].label->setToolTip(MediaMenu::ptr->rdiskMenus[item]->toolTip()); break; case SB_MO: if (d->mo[item].label && MediaMenu::ptr->moMenus[item]) - d->mo[item].label->setToolTip(MediaMenu::ptr->moMenus[item]->title()); + d->mo[item].label->setToolTip(MediaMenu::ptr->moMenus[item]->toolTip()); break; case SB_HDD: break; diff --git a/src/qt/qt_machinestatus.hpp b/src/qt/qt_machinestatus.hpp index ad6425b5a..9dde36a63 100644 --- a/src/qt/qt_machinestatus.hpp +++ b/src/qt/qt_machinestatus.hpp @@ -67,7 +67,7 @@ public: static bool hasSCSI(); static void iterateFDD(const std::function &cb); static void iterateCDROM(const std::function &cb); - static void iterateZIP(const std::function &cb); + static void iterateRDisk(const std::function &cb); static void iterateMO(const std::function &cb); static void iterateNIC(const std::function &cb); diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 1f1dd6b49..f1f0b3b20 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -55,6 +55,11 @@ extern "C" { #endif #include <86box/gdbstub.h> #include <86box/version.h> +#include <86box/renderdefs.h> +#ifdef Q_OS_LINUX +#define GAMEMODE_AUTO +#include "../unix/gamemode/gamemode_client.h" +#endif } #ifdef Q_OS_WINDOWS @@ -77,6 +82,8 @@ extern "C" { #include "qt_styleoverride.hpp" #include "qt_unixmanagerfilter.hpp" #include "qt_util.hpp" +#include "qt_vmmanager_clientsocket.hpp" +#include "qt_vmmanager_mainwindow.hpp" // Void Cast #define VC(x) const_cast(x) @@ -99,6 +106,8 @@ bool cpu_thread_running = false; void qt_set_sequence_auto_mnemonic(bool b); #ifdef Q_OS_WINDOWS +bool acp_utf8 = false; + static void keyboard_getkeymap() { @@ -214,7 +223,7 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) (GetForegroundWindow() == ((HWND) secondaryRenderer->winId()))); } - bool skip = ((nCode < 0) || (nCode != HC_ACTION) || !is_over_window); + bool skip = ((nCode < 0) || (nCode != HC_ACTION) || !is_over_window || (kbd_req_capture && !mouse_capture)); if (skip) return CallNextHookEx(NULL, nCode, wParam, lParam); @@ -443,14 +452,14 @@ main_thread_fn() const uint64_t new_time = elapsed_timer.elapsed(); #ifdef USE_GDBSTUB if (gdbstub_next_asap && (drawits <= 0)) - drawits = 10; + drawits = force_10ms ? 10 : 1; else #endif drawits += static_cast(new_time - old_time); old_time = new_time; if (drawits > 0 && !dopause) { /* Yes, so do one frame now. */ - drawits -= 10; + drawits -= force_10ms ? 10 : 1; if (drawits > 50) drawits = 0; @@ -469,8 +478,8 @@ main_thread_fn() break; } #endif - /* Every 200 frames we save the machine status. */ - if (++frames >= 200 && nvr_dosave) { + /* Every 2 emulated seconds we save the machine status. */ + if (++frames >= (force_10ms ? 200 : 2000) && nvr_dosave) { qt_nvr_save(); nvr_dosave = 0; frames = 0; @@ -512,6 +521,13 @@ extern bool windows_is_light_theme(); int main(int argc, char *argv[]) { +#ifdef Q_OS_WINDOWS + /* Check if Windows supports UTF-8 */ + if (GetACP() == CP_UTF8) + acp_utf8 = 1; + else + acp_utf8 = 0; +#endif #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, false); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); @@ -527,6 +543,9 @@ main(int argc, char *argv[]) #ifdef Q_OS_WINDOWS Q_INIT_RESOURCE(darkstyle); + if (QFile(QApplication::applicationDirPath() + "/opengl32.dll").exists()) { + qputenv("QT_OPENGL_DLL", QFileInfo(QApplication::applicationDirPath() + "/opengl32.dll").absoluteFilePath().toUtf8()); + } QApplication::setAttribute(Qt::AA_NativeWindows); if (!windows_is_light_theme()) { @@ -542,13 +561,11 @@ main(int argc, char *argv[]) } #endif - qt_set_sequence_auto_mnemonic(false); Q_INIT_RESOURCE(qt_resources); Q_INIT_RESOURCE(qt_translations); QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); fmt.setSwapInterval(0); QSurfaceFormat::setDefaultFormat(fmt); - app.setStyle(new StyleOverride()); #ifdef __APPLE__ CocoaEventFilter cocoafilter; @@ -567,6 +584,14 @@ main(int argc, char *argv[]) return 0; } + if (!vmm_enabled) +#ifdef Q_OS_MACOS + qt_set_sequence_auto_mnemonic(false); +#else + qt_set_sequence_auto_mnemonic(!!kbd_req_capture); +#endif + app.setStyle(new StyleOverride()); + bool startMaximized = window_remember && monitor_settings[0].mon_window_maximized; fprintf(stderr, "Qt: version %s, platform \"%s\"\n", qVersion(), QApplication::platformName().toUtf8().data()); ProgSettings::loadTranslators(&app); @@ -600,6 +625,19 @@ main(int argc, char *argv[]) return 6; } + if (vmm_enabled) { + // VMManagerMain vmm; + // // Hackish until there is a proper solution + // QApplication::setApplicationName("86Box VM Manager"); + // QApplication::setApplicationDisplayName("86Box VM Manager"); + // vmm.show(); + // vmm.exec(); + const auto vmm_main_window = new VMManagerMainWindow(); + vmm_main_window->show(); + QApplication::exec(); + return 0; + } + // UUID / copy / move detection if(!util::compareUuid()) { QMessageBox movewarnbox; @@ -642,6 +680,11 @@ main(int argc, char *argv[]) #endif if (settings_only) { + VMManagerClientSocket manager_socket; + if (qgetenv("VMM_86BOX_SOCKET").size()) { + manager_socket.IPCConnect(qgetenv("VMM_86BOX_SOCKET")); + manager_socket.clientRunningStateChanged(VMManagerProtocol::RunningState::PausedWaiting); + } Settings settings; if (settings.exec() == QDialog::Accepted) { settings.save(); @@ -672,6 +715,16 @@ main(int argc, char *argv[]) } else { main_window->show(); } +#ifdef WAYLAND + if (QApplication::platformName().contains("wayland")) { + /* Force a sync. */ + (void)main_window->winId(); + QApplication::sync(); + extern void wl_keyboard_grab(QWindow *window); + wl_keyboard_grab(main_window->windowHandle()); + } +#endif + app.installEventFilter(main_window); @@ -748,6 +801,25 @@ main(int argc, char *argv[]) socket.connectToServer(qgetenv("86BOX_MANAGER_SOCKET")); } + VMManagerClientSocket manager_socket; + if (qgetenv("VMM_86BOX_SOCKET").size()) { + manager_socket.IPCConnect(qgetenv("VMM_86BOX_SOCKET")); + QObject::connect(&manager_socket, &VMManagerClientSocket::pause, main_window, &MainWindow::togglePause); + QObject::connect(&manager_socket, &VMManagerClientSocket::resetVM, main_window, &MainWindow::hardReset); + QObject::connect(&manager_socket, &VMManagerClientSocket::showsettings, main_window, &MainWindow::showSettings); + QObject::connect(&manager_socket, &VMManagerClientSocket::ctrlaltdel, []() { pc_send_cad(); }); + QObject::connect(&manager_socket, &VMManagerClientSocket::request_shutdown, main_window, &MainWindow::close); + QObject::connect(&manager_socket, &VMManagerClientSocket::force_shutdown, []() { + do_stop(); + emit main_window->close(); + }); + QObject::connect(main_window, &MainWindow::vmmRunningStateChanged, &manager_socket, &VMManagerClientSocket::clientRunningStateChanged); + QObject::connect(main_window, &MainWindow::vmmConfigurationChanged, &manager_socket, &VMManagerClientSocket::configurationChanged); + main_window->installEventFilter(&manager_socket); + + manager_socket.sendWinIdMessage(main_window->winId()); + } + // pc_reset_hard_init(); QTimer onesec; @@ -780,7 +852,7 @@ main(int argc, char *argv[]) /* Set the PAUSE mode depending on the renderer. */ #ifdef USE_VNC - if (vid_api == 5) + if (vid_api == RENDERER_VNC) plat_pause(1); else #endif diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 1fb9b3fb5..e7a90e0c3 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -52,6 +52,7 @@ extern "C" { #include <86box/apm.h> #include <86box/nvr.h> #include <86box/acpi.h> +#include <86box/renderdefs.h> #ifdef USE_VNC # include <86box/vnc.h> @@ -91,11 +92,14 @@ extern bool cpu_thread_running; # include #endif +void qt_set_sequence_auto_mnemonic(bool b); + #include #include #include #include "qt_settings.hpp" +#include "qt_about.hpp" #include "qt_machinestatus.hpp" #include "qt_mediamenu.hpp" #include "qt_util.hpp" @@ -186,6 +190,57 @@ MainWindow::MainWindow(QWidget *parent) ui->menuEGA_S_VGA_settings->menuAction()->setMenuRole(QAction::NoRole); ui->stackedWidget->setMouseTracking(true); statusBar()->setVisible(!hide_status_bar); + + num_icon = QIcon(":/settings/qt/icons/num_lock_on.ico"); + num_icon_off = QIcon(":/settings/qt/icons/num_lock_off.ico"); + scroll_icon = QIcon(":/settings/qt/icons/scroll_lock_on.ico"); + scroll_icon_off = QIcon(":/settings/qt/icons/scroll_lock_off.ico"); + caps_icon = QIcon(":/settings/qt/icons/caps_lock_on.ico"); + caps_icon_off = QIcon(":/settings/qt/icons/caps_lock_off.ico"); + kana_icon = QIcon(":/settings/qt/icons/kana_lock_on.ico"); + kana_icon_off = QIcon(":/settings/qt/icons/kana_lock_off.ico"); + + num_label = new QLabel; + num_label->setPixmap(num_icon_off.pixmap(QSize(16, 16))); + num_label->setToolTip(QShortcut::tr("Num Lock")); + statusBar()->addPermanentWidget(num_label); + + caps_label = new QLabel; + caps_label->setPixmap(caps_icon_off.pixmap(QSize(16, 16))); + caps_label->setToolTip(QShortcut::tr("Caps Lock")); + statusBar()->addPermanentWidget(caps_label); + + scroll_label = new QLabel; + scroll_label->setPixmap(scroll_icon_off.pixmap(QSize(16, 16))); + scroll_label->setToolTip(QShortcut::tr("Scroll Lock")); + statusBar()->addPermanentWidget(scroll_label); + + kana_label = new QLabel; + kana_label->setPixmap(kana_icon_off.pixmap(QSize(16, 16))); + kana_label->setToolTip(QShortcut::tr("Kana Lock")); + statusBar()->addPermanentWidget(kana_label); + + QTimer* ledKeyboardTimer = new QTimer(this); + ledKeyboardTimer->setTimerType(Qt::CoarseTimer); + ledKeyboardTimer->setInterval(1); + connect(ledKeyboardTimer, &QTimer::timeout, this, [this] () { + uint8_t caps, num, scroll, kana; + keyboard_get_states(&caps, &num, &scroll, &kana); + + if (num_label->isVisible()) + num_label->setPixmap(num ? this->num_icon.pixmap(QSize(16, 16)) : this->num_icon_off.pixmap(QSize(16, 16))); + if (caps_label->isVisible()) + caps_label->setPixmap(caps ? this->caps_icon.pixmap(QSize(16, 16)) : this->caps_icon_off.pixmap(QSize(16, 16))); + if (scroll_label->isVisible()) + scroll_label->setPixmap(scroll ? this->scroll_icon.pixmap(QSize(16, 16)) : + this->scroll_icon_off.pixmap(QSize(16, 16))); + + if (kana_label->isVisible()) + kana_label->setPixmap(kana ? this->kana_icon.pixmap(QSize(16, 16)) : + this->kana_icon_off.pixmap(QSize(16, 16))); + }); + ledKeyboardTimer->start(); + #ifdef Q_OS_WINDOWS util::setWin11RoundedCorners(this->winId(), (hide_status_bar ? false : true)); #endif @@ -213,6 +268,14 @@ MainWindow::MainWindow(QWidget *parent) connect(this, &MainWindow::hardResetCompleted, this, [this]() { ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); + num_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + scroll_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + caps_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + int ext_ax_kbd = machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD) && + (keyboard_type == KEYBOARD_TYPE_AX); + int int_ax_kbd = machine_has_flags(machine, MACHINE_KEYBOARD_JIS) && + !machine_has_bus(machine, MACHINE_BUS_PS2_PORTS); + kana_label->setVisible(ext_ax_kbd || int_ax_kbd); while (QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); #ifdef USE_WACOM @@ -244,8 +307,6 @@ MainWindow::MainWindow(QWidget *parent) } } #endif - ui->actionPause->setChecked(false); - ui->actionPause->setCheckable(false); }); connect(this, &MainWindow::getTitleForNonQtThread, this, &MainWindow::getTitle_, Qt::BlockingQueuedConnection); @@ -265,7 +326,8 @@ MainWindow::MainWindow(QWidget *parent) mouse_capture = state ? 1 : 0; qt_mouse_capture(mouse_capture); if (mouse_capture) { - this->grabKeyboard(); + if (hook_enabled) + this->grabKeyboard(); if (ui->stackedWidget->mouse_capture_func) ui->stackedWidget->mouse_capture_func(this->windowHandle()); } else { @@ -275,6 +337,16 @@ MainWindow::MainWindow(QWidget *parent) } ui->stackedWidget->unsetCursor(); } +#ifndef Q_OS_MACOS + if (kbd_req_capture) { + qt_set_sequence_auto_mnemonic(!mouse_capture); + /* Hack to get the menubar to update the internal Alt+shortcut table */ + if (!video_fullscreen) { + ui->menubar->hide(); + ui->menubar->show(); + } + } +#endif }); connect(qApp, &QGuiApplication::applicationStateChanged, [this](Qt::ApplicationState state) { @@ -362,29 +434,17 @@ MainWindow::MainWindow(QWidget *parent) ui->actionEnable_Discord_integration->setEnabled(discord_loaded); #endif -#if defined Q_OS_WINDOWS || defined Q_OS_MACOS - /* Make the option visible only if ANGLE is loaded. */ - ui->actionHardware_Renderer_OpenGL_ES->setVisible(QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES); - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES && vid_api == 2) - vid_api = 1; -#endif - ui->actionHardware_Renderer_OpenGL->setVisible(QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES); - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES && vid_api == 1) - vid_api = 0; - if ((QApplication::platformName().contains("eglfs") || QApplication::platformName() == "haiku")) { - if (vid_api >= 1) + if ((vid_api == RENDERER_OPENGL3) || (vid_api == RENDERER_VULKAN)) fprintf(stderr, "OpenGL renderers are unsupported on %s.\n", QApplication::platformName().toUtf8().data()); - vid_api = 0; - ui->actionHardware_Renderer_OpenGL->setVisible(false); - ui->actionHardware_Renderer_OpenGL_ES->setVisible(false); + vid_api = RENDERER_SOFTWARE; ui->actionVulkan->setVisible(false); ui->actionOpenGL_3_0_Core->setVisible(false); } #ifndef USE_VNC - if (vid_api == 5) - vid_api = 0; + if (vid_api == RENDERER_VNC) + vid_api = RENDERER_SOFTWARE; ui->actionVNC->setVisible(false); #endif @@ -404,15 +464,13 @@ MainWindow::MainWindow(QWidget *parent) if (!vulkanAvailable) #endif { - if (vid_api == 4) - vid_api = 0; + if (vid_api == RENDERER_VULKAN) + vid_api = RENDERER_SOFTWARE; ui->actionVulkan->setVisible(false); } auto actGroup = new QActionGroup(this); actGroup->addAction(ui->actionSoftware_Renderer); - actGroup->addAction(ui->actionHardware_Renderer_OpenGL); - actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES); actGroup->addAction(ui->actionOpenGL_3_0_Core); actGroup->addAction(ui->actionVulkan); actGroup->addAction(ui->actionVNC); @@ -421,7 +479,7 @@ MainWindow::MainWindow(QWidget *parent) connect(actGroup, &QActionGroup::triggered, [this](QAction *action) { vid_api = action->property("vid_api").toInt(); #ifdef USE_VNC - if (vnc_enabled && vid_api != 5) { + if (vnc_enabled && vid_api != RENDERER_VNC) { startblit(); vnc_enabled = 0; vnc_close(); @@ -433,23 +491,17 @@ MainWindow::MainWindow(QWidget *parent) switch (vid_api) { default: break; - case 0: + case RENDERER_SOFTWARE: newVidApi = RendererStack::Renderer::Software; break; - case 1: - newVidApi = RendererStack::Renderer::OpenGL; - break; - case 2: - newVidApi = RendererStack::Renderer::OpenGLES; - break; - case 3: + case RENDERER_OPENGL3: newVidApi = RendererStack::Renderer::OpenGL3; break; - case 4: + case RENDERER_VULKAN: newVidApi = RendererStack::Renderer::Vulkan; break; #ifdef USE_VNC - case 5: + case RENDERER_VNC: { newVidApi = RendererStack::Renderer::Software; startblit(); @@ -994,6 +1046,14 @@ void MainWindow::on_actionKeyboard_requires_capture_triggered() { kbd_req_capture ^= 1; +#ifndef Q_OS_MACOS + qt_set_sequence_auto_mnemonic(!!kbd_req_capture); + /* Hack to get the menubar to update the internal Alt+shortcut table */ + if (!video_fullscreen) { + ui->menubar->hide(); + ui->menubar->show(); + } +#endif } void @@ -1069,7 +1129,8 @@ MainWindow::on_actionSettings_triggered() case QDialog::Accepted: settings.save(); config_changed = 2; - updateShortcuts(); + updateShortcuts(); + emit vmmConfigurationChanged(); pc_reset_hard(); break; case QDialog::Rejected: @@ -1291,27 +1352,6 @@ MainWindow::on_actionFullscreen_triggered() emit resizeContents(vid_resize == 2 ? fixed_size_x : monitors[0].mon_scrnsz_x, vid_resize == 2 ? fixed_size_y : monitors[0].mon_scrnsz_y); } } else { - if (video_fullscreen_first) { - bool wasCaptured = mouse_capture == 1; - - char strFullscreen[100]; - sprintf(strFullscreen, qPrintable(tr("Press %s to return to windowed mode.")), acc_keys[FindAccelerator("fullscreen")].seq); - - QMessageBox questionbox(QMessageBox::Icon::Information, tr("Entering fullscreen mode"), QString(strFullscreen), QMessageBox::Ok, this); - QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); - questionbox.setCheckBox(chkbox); - chkbox->setChecked(!video_fullscreen_first); - - QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { - video_fullscreen_first = (state == Qt::CheckState::Unchecked); - }); - questionbox.exec(); - config_save(); - - /* (re-capture mouse after dialog). */ - if (wasCaptured) - emit setMouseCapture(true); - } video_fullscreen = 1; setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); ui->menubar->hide(); @@ -1413,7 +1453,7 @@ MainWindow::eventFilter(QObject *receiver, QEvent *event) } - if (!dopause) { + if (!dopause && (!kbd_req_capture || mouse_capture)) { if (event->type() == QEvent::Shortcut) { auto shortcutEvent = (QShortcutEvent *) event; if (shortcutEvent->key() == ui->actionExit->shortcut()) { @@ -1436,10 +1476,13 @@ MainWindow::eventFilter(QObject *receiver, QEvent *event) if (receiver == this) { static auto curdopause = dopause; if (event->type() == QEvent::WindowBlocked) { + window_blocked = true; curdopause = dopause; plat_pause(isShowMessage ? 2 : 1); emit setMouseCapture(false); + releaseKeyboard(); } else if (event->type() == QEvent::WindowUnblocked) { + window_blocked = false; plat_pause(curdopause); } } @@ -1455,6 +1498,19 @@ MainWindow::refreshMediaMenu() status->refresh(ui->statusbar); ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); ui->actionACPI_Shutdown->setEnabled(!!acpi_enabled); + + num_label->setToolTip(QShortcut::tr("Num Lock")); + num_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + scroll_label->setToolTip(QShortcut::tr("Scroll Lock")); + scroll_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + caps_label->setToolTip(QShortcut::tr("Caps Lock")); + caps_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); + kana_label->setToolTip(QShortcut::tr("Kana Lock")); + int ext_ax_kbd = machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD) && + (keyboard_type == KEYBOARD_TYPE_AX); + int int_ax_kbd = machine_has_flags(machine, MACHINE_KEYBOARD_JIS) && + !machine_has_bus(machine, MACHINE_BUS_PS2_PORTS); + kana_label->setVisible(ext_ax_kbd || int_ax_kbd); } void @@ -1552,13 +1608,13 @@ MainWindow::getRenderWidgetSize() void MainWindow::focusInEvent(QFocusEvent *event) { - this->grabKeyboard(); + //this->grabKeyboard(); } void MainWindow::focusOutEvent(QFocusEvent *event) { - this->releaseKeyboard(); + //this->releaseKeyboard(); } void @@ -1874,42 +1930,8 @@ MainWindow::on_actionAbout_Qt_triggered() void MainWindow::on_actionAbout_86Box_triggered() { - QMessageBox msgBox; - msgBox.setTextFormat(Qt::RichText); - QString versioninfo; -#ifdef EMU_GIT_HASH - versioninfo = QString(" [%1]").arg(EMU_GIT_HASH); -#endif -#ifdef USE_DYNAREC -# ifdef USE_NEW_DYNAREC -# define DYNAREC_STR "new dynarec" -# else -# define DYNAREC_STR "old dynarec" -# endif -#else -# define DYNAREC_STR "no dynarec" -#endif - 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: 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(tr("About 86Box")); - const auto closeButton = msgBox.addButton("OK", QMessageBox::ButtonRole::AcceptRole); - msgBox.setEscapeButton(closeButton); - const auto webSiteButton = msgBox.addButton(EMU_SITE, QMessageBox::ButtonRole::HelpRole); - webSiteButton->connect(webSiteButton, &QPushButton::released, []() { - QDesktopServices::openUrl(QUrl("https://" EMU_SITE)); - }); -#ifdef RELEASE_BUILD - msgBox.setIconPixmap(QIcon(":/settings/qt/icons/86Box-green.ico").pixmap(32, 32)); -#elif defined ALPHA_BUILD - msgBox.setIconPixmap(QIcon(":/settings/qt/icons/86Box-red.ico").pixmap(32, 32)); -#elif defined BETA_BUILD - msgBox.setIconPixmap(QIcon(":/settings/qt/icons/86Box-yellow.ico").pixmap(32, 32)); -#else - msgBox.setIconPixmap(QIcon(":/settings/qt/icons/86Box-gray.ico").pixmap(32, 32)); -#endif - msgBox.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); - msgBox.exec(); + const auto msgBox = new About(this); + msgBox->exec(); } void @@ -2081,8 +2103,12 @@ MainWindow::updateUiPauseState() QIcon(":/menuicons/qt/icons/pause.ico"); const auto tooltip_text = dopause ? QString(tr("Resume execution")) : QString(tr("Pause execution")); + const auto menu_text = dopause ? QString(tr("Re&sume")) : + QString(tr("&Pause")); ui->actionPause->setIcon(pause_icon); ui->actionPause->setToolTip(tooltip_text); + ui->actionPause->setText(menu_text); + emit vmmRunningStateChanged(static_cast(window_blocked ? (dopause ? VMManagerProtocol::RunningState::PausedWaiting : VMManagerProtocol::RunningState::RunningWaiting) : (VMManagerProtocol::RunningState)dopause)); } void diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 5811ac36a..e7611d576 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -5,12 +5,16 @@ #include #include #include +#include #include +#include #include #include #include +#include "qt_vmmanager_protocol.hpp" + class MediaMenu; class RendererStack; @@ -61,6 +65,9 @@ signals: void showMessageForNonQtThread(int flags, const QString &header, const QString &message, bool richText, std::atomic_bool* done); void getTitleForNonQtThread(wchar_t *title); + + void vmmRunningStateChanged(VMManagerProtocol::RunningState state); + void vmmConfigurationChanged(); public slots: void showSettings(); void hardReset(); @@ -79,7 +86,7 @@ private slots: void on_actionCtrl_Alt_Esc_triggered(); void on_actionHard_Reset_triggered(); void on_actionRight_CTRL_is_left_ALT_triggered(); - static void on_actionKeyboard_requires_capture_triggered(); + void on_actionKeyboard_requires_capture_triggered(); void on_actionResizable_window_triggered(bool checked); void on_actionInverted_VGA_monitor_triggered(); void on_action0_5x_triggered(); @@ -189,7 +196,12 @@ private: friend class RendererStack; // For UI variable access by non-primary renderer windows. friend class WindowsRawInputFilter; // Needed to reload renderers on style sheet changes. + QLabel *caps_label, *scroll_label, *num_label, *kana_label; + QIcon caps_icon, scroll_icon, num_icon, kana_icon; + QIcon caps_icon_off, scroll_icon_off, num_icon_off, kana_icon_off; + bool isShowMessage = false; + bool window_blocked = false; }; #endif // QT_MAINWINDOW_HPP diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 83a80342b..a0f06e75e 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -63,7 +63,7 @@ - Tablet tool + &Tablet tool @@ -121,8 +121,6 @@ Re&nderer - - @@ -144,7 +142,7 @@ - Filter method + Fi&lter method @@ -343,9 +341,6 @@ - - true - :/menuicons/qt/icons/pause.ico:/menuicons/qt/icons/pause.ico @@ -359,7 +354,7 @@ - Exit + E&xit QAction::QuitRole @@ -399,28 +394,6 @@ 0 - - - true - - - Qt (&OpenGL) - - - 1 - - - - - true - - - Qt (OpenGL &ES) - - - 2 - - true @@ -447,7 +420,7 @@ - Specify dimensions... + Specify &dimensions... @@ -692,7 +665,7 @@ - About Qt + About &Qt false @@ -751,7 +724,7 @@ Open&GL (3.0 Core) - 3 + 1 @@ -790,7 +763,7 @@ :/menuicons/qt/icons/acpi_shutdown.ico:/menuicons/qt/icons/acpi_shutdown.ico - ACPI shutdown + ACP&I shutdown ACPI shutdown @@ -829,7 +802,7 @@ - Renderer options... + Renderer &options... QAction::NoRole @@ -843,12 +816,12 @@ &Vulkan - 4 + 2 - MCA devices... + &MCA devices... @@ -856,7 +829,7 @@ true - Show non-primary monitors + Show non-&primary monitors @@ -864,15 +837,15 @@ true - VNC + &VNC - 5 + 3 - Open screenshots folder... + Open screenshots &folder... @@ -880,7 +853,7 @@ true - Apply fullscreen stretch mode when maximized + Appl&y fullscreen stretch mode when maximized @@ -888,7 +861,7 @@ true - Cursor/Puck + &Cursor/Puck @@ -896,7 +869,7 @@ true - Pen + &Pen diff --git a/src/qt/qt_mediahistorymanager.cpp b/src/qt/qt_mediahistorymanager.cpp index 5892c55cd..724616d1c 100644 --- a/src/qt/qt_mediahistorymanager.cpp +++ b/src/qt/qt_mediahistorymanager.cpp @@ -21,6 +21,9 @@ #include #include #include "qt_mediahistorymanager.hpp" +#ifdef Q_OS_WINDOWS +#include +#endif extern "C" { #include <86box/timer.h> @@ -30,7 +33,7 @@ extern "C" { #include <86box/fdd.h> #include <86box/cdrom.h> #include <86box/scsi_device.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/mo.h> #include <86box/path.h> } @@ -111,8 +114,8 @@ MediaHistoryManager::maxDevicesSupported(ui::MediaType type) return CDROM_NUM; case ui::MediaType::Floppy: return FDD_NUM; - case ui::MediaType::Zip: - return ZIP_NUM; + case ui::MediaType::RDisk: + return RDISK_NUM; case ui::MediaType::Mo: return MO_NUM; case ui::MediaType::Cassette: @@ -197,14 +200,16 @@ MediaHistoryManager::initialDeduplication() case ui::MediaType::Optical: current_image = cdrom[device_index].image_path; break; - case ui::MediaType::Zip: - current_image = zip_drives[device_index].image_path; + case ui::MediaType::RDisk: + current_image = rdisk_drives[device_index].image_path; break; case ui::MediaType::Mo: current_image = mo_drives[device_index].image_path; break; } deduplicateList(device_history, QVector(1, current_image)); + device_history = removeMissingImages(device_history); + device_history = pathAdjustFull(device_history); // Fill in missing, if any int missing = MAX_PREV_IMAGES - device_history.size(); if (missing) { @@ -213,6 +218,7 @@ MediaHistoryManager::initialDeduplication() } } setHistoryListForDeviceIndex(device_index, device_type, device_history); + serializeImageHistoryType(device_type); } } } @@ -231,8 +237,8 @@ MediaHistoryManager::getEmuHistoryVarForType(ui::MediaType type, int index) return &fdd_image_history[index][0]; case ui::MediaType::Optical: return &cdrom[index].image_history[0]; - case ui::MediaType::Zip: - return &zip_drives[index].image_history[0]; + case ui::MediaType::RDisk: + return &rdisk_drives[index].image_history[0]; case ui::MediaType::Mo: return &mo_drives[index].image_history[0]; } @@ -343,24 +349,42 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history) char temp[MAX_IMAGE_PATH_LEN * 2] = { 0 }; - if (path_abs(checked_path.toUtf8().data())) { - if (checked_path.length() > (MAX_IMAGE_PATH_LEN - 1)) - fatal("removeMissingImages(): checked_path.length() > %i\n", MAX_IMAGE_PATH_LEN - 1); - else - snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s", checked_path.toUtf8().constData()); + if (checked_path.left(8) == "ioctl://") { + strncpy(temp, checked_path.toUtf8().data(), sizeof(temp)); + temp[sizeof(temp) - 1] = '\0'; } else { - if ((strlen(usr_path) + strlen(path_get_slash(usr_path)) + checked_path.length()) > (MAX_IMAGE_PATH_LEN - 1)) - fatal("removeMissingImages(): Combined absolute path length > %i\n", MAX_IMAGE_PATH_LEN - 1); + QString path_only; + if (checked_path.left(5) == "wp://") + path_only = checked_path.right(checked_path.length() - 5); else - snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, - path_get_slash(usr_path), checked_path.toUtf8().constData()); + path_only = checked_path; + + if (path_abs(path_only.toUtf8().data())) { + if (path_only.length() > (MAX_IMAGE_PATH_LEN - 1)) + fatal("removeMissingImages(): path_only.length() > %i\n", MAX_IMAGE_PATH_LEN - 1); + else + snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s", path_only.toUtf8().constData()); + } else { + if ((strlen(usr_path) + strlen(path_get_slash(usr_path)) + path_only.length()) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("removeMissingImages(): Combined absolute path length > %i\n", MAX_IMAGE_PATH_LEN - 1); + else + snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, + path_get_slash(usr_path), path_only.toUtf8().constData()); + } + path_normalize(temp); } - path_normalize(temp); QString qstr = QString::fromUtf8(temp); QFileInfo new_fi(qstr); - if ((new_fi.filePath().left(8) != "ioctl://") && !new_fi.exists()) { + bool file_exists = new_fi.exists(); + +#ifdef Q_OS_WINDOWS + if (new_fi.filePath().left(8) == "ioctl://") + file_exists = (GetDriveType(new_fi.filePath().right(2).toUtf8().data()) == DRIVE_CDROM); +#endif + + if (!file_exists) { qWarning("Image file %s does not exist - removing from history", qPrintable(new_fi.filePath())); checked_path = ""; } diff --git a/src/qt/qt_mediahistorymanager.hpp b/src/qt/qt_mediahistorymanager.hpp index 29ada8e2a..92b5939d3 100644 --- a/src/qt/qt_mediahistorymanager.hpp +++ b/src/qt/qt_mediahistorymanager.hpp @@ -45,7 +45,7 @@ Q_NAMESPACE enum class MediaType { Floppy, Optical, - Zip, + RDisk, Mo, Cassette, Cartridge @@ -62,7 +62,7 @@ typedef QHash master_list_t; static const MediaType AllSupportedMediaHistoryTypes[] = { MediaType::Optical, MediaType::Floppy, - MediaType::Zip, + MediaType::RDisk, MediaType::Mo, MediaType::Cassette, MediaType::Cartridge diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 351012d1e..465c56129 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -56,7 +56,7 @@ extern "C" { #include <86box/fdd_86f.h> #include <86box/cdrom.h> #include <86box/scsi_device.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/mo.h> #include <86box/sound.h> #include <86box/ui.h> @@ -69,9 +69,12 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_mediahistorymanager.hpp" #include "qt_mediamenu.hpp" +#include "qt_iconindicators.hpp" std::shared_ptr MediaMenu::ptr; +static QSize pixmap_size(16, 16); + MediaMenu::MediaMenu(QWidget *parent) : QObject(parent) { @@ -86,27 +89,28 @@ MediaMenu::refresh(QMenu *parentMenu) if (MachineStatus::hasCassette()) { cassetteMenu = parentMenu->addMenu(""); - cassetteMenu->addAction(tr("&New image..."), [this]() { cassetteNewImage(); }); + QIcon img_icon = QIcon(":/settings/qt/icons/cassette_image.ico"); + cassetteMenu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, New), tr("&New image..."), [this]() { cassetteNewImage(); }); cassetteMenu->addSeparator(); - cassetteMenu->addAction(tr("&Existing image..."), [this]() { cassetteSelectImage(false); }); - cassetteMenu->addAction(tr("Existing image (&Write-protected)..."), [this]() { cassetteSelectImage(true); }); + cassetteMenu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Browse), tr("&Existing image..."), [this]() { cassetteSelectImage(false); }); + cassetteMenu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, WriteProtectedBrowse), tr("Existing image (&Write-protected)..."), [this]() { cassetteSelectImage(true); }); cassetteMenu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { cassetteImageHistoryPos[slot] = cassetteMenu->children().count(); - cassetteMenu->addAction(tr("Image %1").arg(slot), [this, slot]() { cassetteMenuSelect(slot); })->setCheckable(false); + cassetteMenu->addAction(img_icon, tr("Image %1").arg(slot), [this, slot]() { cassetteMenuSelect(slot); })->setCheckable(false); } cassetteMenu->addSeparator(); cassetteRecordPos = cassetteMenu->children().count(); - cassetteMenu->addAction(tr("&Record"), [this] { pc_cas_set_mode(cassette, 1); cassetteUpdateMenu(); })->setCheckable(true); + cassetteMenu->addAction(QIcon(":/settings/qt/icons/record.ico"), tr("&Record"), [this] { pc_cas_set_mode(cassette, 1); cassetteUpdateMenu(); })->setCheckable(true); cassettePlayPos = cassetteMenu->children().count(); - cassetteMenu->addAction(tr("&Play"), [this] { pc_cas_set_mode(cassette, 0); cassetteUpdateMenu(); })->setCheckable(true); + cassetteMenu->addAction(QIcon(":/menuicons/qt/icons/run.ico"), tr("&Play"), [this] { pc_cas_set_mode(cassette, 0); cassetteUpdateMenu(); })->setCheckable(true); cassetteRewindPos = cassetteMenu->children().count(); - cassetteMenu->addAction(tr("&Rewind to the beginning"), [] { pc_cas_rewind(cassette); }); + cassetteMenu->addAction(QIcon(":/settings/qt/icons/rewind.ico"), tr("&Rewind to the beginning"), [] { pc_cas_rewind(cassette); }); cassetteFastFwdPos = cassetteMenu->children().count(); - cassetteMenu->addAction(tr("&Fast forward to the end"), [] { pc_cas_append(cassette); }); + cassetteMenu->addAction(QIcon(":/settings/qt/icons/fast_forward.ico"), tr("&Fast forward to the end"), [] { pc_cas_append(cassette); }); cassetteMenu->addSeparator(); cassetteEjectPos = cassetteMenu->children().count(); - cassetteMenu->addAction(tr("E&ject"), [this]() { cassetteEject(); }); + cassetteMenu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Eject), tr("E&ject"), [this]() { cassetteEject(); }); cassetteUpdateMenu(); } @@ -114,15 +118,16 @@ MediaMenu::refresh(QMenu *parentMenu) if (machine_has_cartridge(machine)) { for (int i = 0; i < 2; i++) { auto *menu = parentMenu->addMenu(""); - menu->addAction(tr("&Image..."), [this, i]() { cartridgeSelectImage(i); }); + QIcon img_icon = QIcon(":/settings/qt/icons/cartridge_image.ico"); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Browse), tr("&Image..."), [this, i]() { cartridgeSelectImage(i); }); menu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { cartridgeImageHistoryPos[slot] = menu->children().count(); - menu->addAction(tr("Image %1").arg(slot), [this, i, slot]() { cartridgeMenuSelect(i, slot); })->setCheckable(false); + menu->addAction(img_icon, tr("Image %1").arg(slot), [this, i, slot]() { cartridgeMenuSelect(i, slot); })->setCheckable(false); } menu->addSeparator(); cartridgeEjectPos = menu->children().count(); - menu->addAction(tr("E&ject"), [this, i]() { cartridgeEject(i); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Eject), tr("E&ject"), [this, i]() { cartridgeEject(i); }); cartridgeMenus[i] = menu; cartridgeUpdateMenu(i); } @@ -131,21 +136,23 @@ MediaMenu::refresh(QMenu *parentMenu) floppyMenus.clear(); MachineStatus::iterateFDD([this, parentMenu](int i) { auto *menu = parentMenu->addMenu(""); - menu->addAction(tr("&New image..."), [this, i]() { floppyNewImage(i); }); + QIcon img_icon = fdd_is_525(i) ? QIcon(":/settings/qt/icons/floppy_525_image.ico") : + QIcon(":/settings/qt/icons/floppy_35_image.ico"); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, New), tr("&New image..."), [this, i]() { floppyNewImage(i); }); menu->addSeparator(); - menu->addAction(tr("&Existing image..."), [this, i]() { floppySelectImage(i, false); }); - menu->addAction(tr("Existing image (&Write-protected)..."), [this, i]() { floppySelectImage(i, true); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Browse), tr("&Existing image..."), [this, i]() { floppySelectImage(i, false); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, WriteProtectedBrowse), tr("Existing image (&Write-protected)..."), [this, i]() { floppySelectImage(i, true); }); menu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { floppyImageHistoryPos[slot] = menu->children().count(); - menu->addAction(tr("Image %1").arg(slot), [this, i, slot]() { floppyMenuSelect(i, slot); })->setCheckable(false); + menu->addAction(img_icon, tr("Image %1").arg(slot), [this, i, slot]() { floppyMenuSelect(i, slot); })->setCheckable(false); } menu->addSeparator(); floppyExportPos = menu->children().count(); - menu->addAction(tr("E&xport to 86F..."), [this, i]() { floppyExportTo86f(i); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Export), tr("E&xport to 86F..."), [this, i]() { floppyExportTo86f(i); }); menu->addSeparator(); floppyEjectPos = menu->children().count(); - menu->addAction(tr("E&ject"), [this, i]() { floppyEject(i); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Eject), tr("E&ject"), [this, i]() { floppyEject(i); }); floppyMenus[i] = menu; floppyUpdateMenu(i); }); @@ -156,8 +163,8 @@ MediaMenu::refresh(QMenu *parentMenu) cdromMutePos = menu->children().count(); menu->addAction(QIcon(":/settings/qt/icons/cdrom_mute.ico"), tr("&Mute"), [this, i]() { cdromMute(i); })->setCheckable(true); menu->addSeparator(); - menu->addAction(QIcon(":/settings/qt/icons/cdrom_image.ico"), tr("&Image..."), [this, i]() { cdromMount(i, 0, nullptr); })->setCheckable(false); - menu->addAction(QIcon(":/settings/qt/icons/cdrom_folder.ico"), tr("&Folder..."), [this, i]() { cdromMount(i, 1, nullptr); })->setCheckable(false); + menu->addAction(getIconWithIndicator(QIcon(":/settings/qt/icons/cdrom_image.ico"), pixmap_size, QIcon::Normal, Browse), tr("&Image..."), [this, i]() { cdromMount(i, 0, nullptr); })->setCheckable(false); + menu->addAction(getIconWithIndicator(QIcon(":/settings/qt/icons/cdrom_folder.ico"), pixmap_size, QIcon::Normal, Browse), tr("&Folder..."), [this, i]() { cdromMount(i, 1, nullptr); })->setCheckable(false); menu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { cdromImageHistoryPos[slot] = menu->children().count(); @@ -170,7 +177,7 @@ MediaMenu::refresh(QMenu *parentMenu) for (const auto &letter : driveLetters) { auto drive = QString("%1:\\").arg(letter); if (GetDriveType(drive.toUtf8().constData()) == DRIVE_CDROM) - menu->addAction(QIcon(":/settings/qt/icons/cdrom_host.ico"), tr("Host CD/DVD Drive (%1:)").arg(letter), [this, i, letter] { cdromMount(i, 2, QString(R"(\\.\%1:)").arg(letter)); })->setCheckable(false); + menu->addAction(QIcon(":/settings/qt/icons/cdrom_host.ico"), tr("&Host CD/DVD Drive (%1:)").arg(letter), [this, i, letter] { cdromMount(i, 2, QString(R"(\\.\%1:)").arg(letter)); })->setCheckable(false); } menu->addSeparator(); #endif // Q_OS_WINDOWS @@ -180,40 +187,42 @@ MediaMenu::refresh(QMenu *parentMenu) cdromUpdateMenu(i); }); - zipMenus.clear(); - MachineStatus::iterateZIP([this, parentMenu](int i) { + rdiskMenus.clear(); + MachineStatus::iterateRDisk([this, parentMenu](int i) { auto *menu = parentMenu->addMenu(""); - menu->addAction(tr("&New image..."), [this, i]() { zipNewImage(i); }); + QIcon img_icon = QIcon(":/settings/qt/icons/rdisk_image.ico"); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, New), tr("&New image..."), [this, i]() { rdiskNewImage(i); }); menu->addSeparator(); - menu->addAction(tr("&Existing image..."), [this, i]() { zipSelectImage(i, false); }); - menu->addAction(tr("Existing image (&Write-protected)..."), [this, i]() { zipSelectImage(i, true); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Browse), tr("&Existing image..."), [this, i]() { rdiskSelectImage(i, false); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, WriteProtectedBrowse), tr("Existing image (&Write-protected)..."), [this, i]() { rdiskSelectImage(i, true); }); menu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { - zipImageHistoryPos[slot] = menu->children().count(); - menu->addAction(tr("Image %1").arg(slot), [this, i, slot]() { zipReload(i, slot); })->setCheckable(false); + rdiskImageHistoryPos[slot] = menu->children().count(); + menu->addAction(img_icon, tr("Image %1").arg(slot), [this, i, slot]() { rdiskReload(i, slot); })->setCheckable(false); } menu->addSeparator(); - zipEjectPos = menu->children().count(); - menu->addAction(tr("E&ject"), [this, i]() { zipEject(i); }); - zipMenus[i] = menu; - zipUpdateMenu(i); + rdiskEjectPos = menu->children().count(); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Eject), tr("E&ject"), [this, i]() { rdiskEject(i); }); + rdiskMenus[i] = menu; + rdiskUpdateMenu(i); }); moMenus.clear(); MachineStatus::iterateMO([this, parentMenu](int i) { auto *menu = parentMenu->addMenu(""); - menu->addAction(tr("&New image..."), [this, i]() { moNewImage(i); }); + QIcon img_icon = QIcon(":/settings/qt/icons/mo_image.ico"); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, New), tr("&New image..."), [this, i]() { moNewImage(i); }); menu->addSeparator(); - menu->addAction(tr("&Existing image..."), [this, i]() { moSelectImage(i, false); }); - menu->addAction(tr("Existing image (&Write-protected)..."), [this, i]() { moSelectImage(i, true); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Browse), tr("&Existing image..."), [this, i]() { moSelectImage(i, false); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, WriteProtectedBrowse), tr("Existing image (&Write-protected)..."), [this, i]() { moSelectImage(i, true); }); menu->addSeparator(); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { moImageHistoryPos[slot] = menu->children().count(); - menu->addAction(tr("Image %1").arg(slot), [this, i, slot]() { moReload(i, slot); })->setCheckable(false); + menu->addAction(img_icon, tr("Image %1").arg(slot), [this, i, slot]() { moReload(i, slot); })->setCheckable(false); } menu->addSeparator(); moEjectPos = menu->children().count(); - menu->addAction(tr("E&ject"), [this, i]() { moEject(i); }); + menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Eject), tr("E&ject"), [this, i]() { moEject(i); }); moMenus[i] = menu; moUpdateMenu(i); }); @@ -227,7 +236,7 @@ MediaMenu::refresh(QMenu *parentMenu) netMenus[i] = menu; nicUpdateMenu(i); }); - parentMenu->addAction(tr("Clear image history"), [this]() { clearImageHistory(); }); + parentMenu->addAction(tr("Clear image &history"), [this]() { clearImageHistory(); }); } void @@ -277,11 +286,18 @@ MediaMenu::cassetteMount(const QString &filename, bool wp) if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); + + if (filename.left(5) == "wp://") + cassette_ui_writeprot = 1; + else if (cassette_ui_writeprot) + filenameBytes = QString::asprintf(R"(wp://%s)", filename.toUtf8().data()).toUtf8(); + strncpy(cassette_fname, filenameBytes.data(), sizeof(cassette_fname) - 1); pc_cas_set_fname(cassette, cassette_fname); } ui_sb_update_icon_state(SB_CASSETTE, filename.isEmpty() ? 1 : 0); + ui_sb_update_icon_wp(SB_CASSETTE, cassette_ui_writeprot); mhm.addImageToHistory(0, ui::MediaType::Cassette, previous_image.filePath(), filename); cassetteUpdateMenu(); ui_sb_update_tip(SB_CASSETTE); @@ -324,7 +340,8 @@ MediaMenu::cassetteUpdateMenu() recordMenu->setChecked(isSaving); playMenu->setChecked(!isSaving); - cassetteMenu->setTitle(tr("Cassette: %1").arg(name.isEmpty() ? tr("(empty)") : name)); + cassetteMenu->setTitle(tr("C&assette: %1").arg(name.isEmpty() ? tr("(empty)") : name)); + cassetteMenu->setToolTip(tr("Cassette: %1").arg(name.isEmpty() ? tr("(empty)") : name)); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { updateImageHistory(0, slot, ui::MediaType::Cassette); @@ -391,7 +408,8 @@ MediaMenu::cartridgeUpdateMenu(int i) auto *ejectMenu = dynamic_cast(childs[cartridgeEjectPos]); ejectMenu->setEnabled(!name.isEmpty()); ejectMenu->setText(name.isEmpty() ? tr("E&ject") : tr("E&ject %1").arg(fi.fileName())); - menu->setTitle(tr("Cartridge %1: %2").arg(QString::number(i + 1), name.isEmpty() ? tr("(empty)") : name)); + menu->setTitle(tr("Car&tridge %1: %2").arg(QString::number(i + 1), name.isEmpty() ? tr("(empty)") : name)); + menu->setToolTip(tr("Cartridge %1: %2").arg(QString::number(i + 1), name.isEmpty() ? tr("(empty)") : name)); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { updateImageHistory(i, slot, ui::MediaType::Cartridge); @@ -443,10 +461,18 @@ MediaMenu::floppyMount(int i, const QString &filename, bool wp) ui_writeprot[i] = wp ? 1 : 0; if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); + + if (filename.left(5) == "wp://") + ui_writeprot[i] = 1; + else if (ui_writeprot[i]) + filenameBytes = QString::asprintf(R"(wp://%s)", filename.toUtf8().data()).toUtf8(); + fdd_load(i, filenameBytes.data()); - } + mhm.addImageToHistory(i, ui::MediaType::Floppy, previous_image.filePath(), QString(filenameBytes)); + } else + mhm.addImageToHistory(i, ui::MediaType::Floppy, previous_image.filePath(), filename); ui_sb_update_icon_state(SB_FLOPPY | i, filename.isEmpty() ? 1 : 0); - mhm.addImageToHistory(i, ui::MediaType::Floppy, previous_image.filePath(), filename); + ui_sb_update_icon_wp(SB_FLOPPY | i, ui_writeprot[i]); floppyUpdateMenu(i); ui_sb_update_tip(SB_FLOPPY | i); config_save(); @@ -500,7 +526,8 @@ MediaMenu::floppyUpdateMenu(int i) } int type = fdd_get_type(i); - floppyMenus[i]->setTitle(tr("Floppy %1 (%2): %3").arg(QString::number(i + 1), fdd_getname(type), name.isEmpty() ? tr("(empty)") : name)); + floppyMenus[i]->setTitle(tr("&Floppy %1 (%2): %3").arg(QString::number(i + 1), fdd_getname(type), name.isEmpty() ? tr("(empty)") : name)); + floppyMenus[i]->setToolTip(tr("Floppy %1 (%2): %3").arg(QString::number(i + 1), fdd_getname(type), name.isEmpty() ? tr("(empty)") : name)); } @@ -567,13 +594,13 @@ MediaMenu::cdromMount(int i, int dir, const QString &arg) QFileInfo fi(cdrom[i].image_path); if (dir > 1) - filename = QString::asprintf(R"(ioctl://%s)", arg.toStdString().c_str()); + filename = QString::asprintf(R"(ioctl://%s)", arg.toUtf8().data()); else if (dir == 1) filename = QFileDialog::getExistingDirectory(parentWidget); else { filename = QFileDialog::getOpenFileName(parentWidget, QString(), QString(), - tr("CD-ROM images") % util::DlgFilter({ "iso", "cue" }) % tr("All files") % util::DlgFilter({ "*" }, true)); + tr("CD-ROM images") % util::DlgFilter({ "iso", "cue", "mds" }) % tr("All files") % util::DlgFilter({ "*" }, true)); } if (filename.isEmpty()) @@ -639,8 +666,18 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) menu = cassetteMenu; children = menu->children(); imageHistoryUpdatePos = dynamic_cast(children[cassetteImageHistoryPos[slot]]); - fi.setFile(fn); - menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + menu_icon = QIcon(":/settings/qt/icons/cassette_image.ico"); + if (fn.left(5) == "wp://") + fi.setFile(fn.right(fn.length() - 5)); + else + fi.setFile(fn); + if (!fi.fileName().isEmpty() && (fn.left(5) == "wp://")) { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn.right(fn.length() - 5); + imageHistoryUpdatePos->setIcon(getIconWithIndicator(menu_icon, pixmap_size, QIcon::Normal, WriteProtected)); + } else { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + imageHistoryUpdatePos->setIcon(menu_icon); + } break; case ui::MediaType::Cartridge: if (!machine_has_cartridge(machine)) @@ -657,8 +694,19 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) menu = floppyMenus[index]; children = menu->children(); imageHistoryUpdatePos = dynamic_cast(children[floppyImageHistoryPos[slot]]); - fi.setFile(fn); - menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + menu_icon = fdd_is_525(index) ? QIcon(":/settings/qt/icons/floppy_525_image.ico") : + QIcon(":/settings/qt/icons/floppy_35_image.ico"); + if (fn.left(5) == "wp://") + fi.setFile(fn.right(fn.length() - 5)); + else + fi.setFile(fn); + if (!fi.fileName().isEmpty() && (fn.left(5) == "wp://")) { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn.right(fn.length() - 5); + imageHistoryUpdatePos->setIcon(getIconWithIndicator(menu_icon, pixmap_size, QIcon::Normal, WriteProtected)); + } else { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + imageHistoryUpdatePos->setIcon(menu_icon); + } break; case ui::MediaType::Optical: if (!cdromMenus.contains(index)) @@ -680,14 +728,24 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) } imageHistoryUpdatePos->setIcon(menu_icon); break; - case ui::MediaType::Zip: - if (!zipMenus.contains(index)) + case ui::MediaType::RDisk: + if (!rdiskMenus.contains(index)) return; - menu = zipMenus[index]; + menu = rdiskMenus[index]; children = menu->children(); - imageHistoryUpdatePos = dynamic_cast(children[zipImageHistoryPos[slot]]); - fi.setFile(fn); - menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + imageHistoryUpdatePos = dynamic_cast(children[rdiskImageHistoryPos[slot]]); + menu_icon = QIcon(":/settings/qt/icons/mo_image.ico"); + if (fn.left(5) == "wp://") + fi.setFile(fn.right(fn.length() - 5)); + else + fi.setFile(fn); + if (!fi.fileName().isEmpty() && (fn.left(5) == "wp://")) { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn.right(fn.length() - 5); + imageHistoryUpdatePos->setIcon(getIconWithIndicator(menu_icon, pixmap_size, QIcon::Normal, WriteProtected)); + } else { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + imageHistoryUpdatePos->setIcon(menu_icon); + } break; case ui::MediaType::Mo: if (!moMenus.contains(index)) @@ -695,11 +753,26 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) menu = moMenus[index]; children = menu->children(); imageHistoryUpdatePos = dynamic_cast(children[moImageHistoryPos[slot]]); - fi.setFile(fn); - menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + menu_icon = QIcon(":/settings/qt/icons/mo_image.ico"); + if (fn.left(5) == "wp://") + fi.setFile(fn.right(fn.length() - 5)); + else + fi.setFile(fn); + if (!fi.fileName().isEmpty() && (fn.left(5) == "wp://")) { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn.right(fn.length() - 5); + imageHistoryUpdatePos->setIcon(getIconWithIndicator(menu_icon, pixmap_size, QIcon::Normal, WriteProtected)); + } else { + menu_item_name = fi.fileName().isEmpty() ? tr("Reload previous image") : fn; + imageHistoryUpdatePos->setIcon(menu_icon); + } break; } +#ifndef Q_OS_MACOS + if ((slot >= 0) && (slot <= 9)) + imageHistoryUpdatePos->setText(menu_item_name.prepend("&%1 ").arg((slot == 9) ? 0 : (slot + 1))); + else +#endif imageHistoryUpdatePos->setText(menu_item_name); if (fn.left(8) == "ioctl://") @@ -747,9 +820,12 @@ MediaMenu::cdromUpdateMenu(int i) menu_item_name = name.isEmpty() ? QString() : fi.fileName(); name2 = name; - menu_icon = fi.isDir() ? QIcon(":/settings/qt/icons/cdrom_folder.ico") : QIcon(":/settings/qt/icons/cdrom_image.ico"); + if (name.isEmpty()) + menu_icon = QIcon(":/settings/qt/icons/cdrom.ico"); + else + menu_icon = fi.isDir() ? QIcon(":/settings/qt/icons/cdrom_folder.ico") : QIcon(":/settings/qt/icons/cdrom_image.ico"); } - ejectMenu->setIcon(menu_icon); + ejectMenu->setIcon(getIconWithIndicator(menu_icon, pixmap_size, QIcon::Normal, Eject)); ejectMenu->setText(name.isEmpty() ? tr("E&ject") : tr("E&ject %1").arg(menu_item_name)); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) @@ -766,145 +842,192 @@ MediaMenu::cdromUpdateMenu(int i) busName = "SCSI"; break; case CDROM_BUS_MITSUMI: - busName = "Mitsumi"; - break; + busName = "Mitsumi"; + break; + case CDROM_BUS_MKE: + busName = "Panasonic/MKE"; + break; } - menu->setTitle(tr("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name2)); + menu->setTitle(tr("&CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name2)); + menu->setToolTip(tr("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name2)); } void -MediaMenu::zipNewImage(int i) +MediaMenu::rdiskNewImage(int i) { - NewFloppyDialog dialog(NewFloppyDialog::MediaType::Zip, parentWidget); + NewFloppyDialog dialog(NewFloppyDialog::MediaType::RDisk, parentWidget); switch (dialog.exec()) { default: break; case QDialog::Accepted: QByteArray filename = dialog.fileName().toUtf8(); - zipMount(i, filename, false); + rdiskMount(i, filename, false); break; } } void -MediaMenu::zipSelectImage(int i, bool wp) +MediaMenu::rdiskSelectImage(int i, bool wp) { const auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), QString(), - tr("ZIP images") % util::DlgFilter({ "im?", "zdi" }) % tr("All files") % util::DlgFilter({ "*" }, true)); + tr("Removable disk images") % util::DlgFilter({ "im?", "rdi", "zdi" }) % tr("All files") % util::DlgFilter({ "*" }, true)); if (!filename.isEmpty()) - zipMount(i, filename, wp); + rdiskMount(i, filename, wp); } void -MediaMenu::zipMount(int i, const QString &filename, bool wp) +MediaMenu::rdiskMount(int i, const QString &filename, bool wp) { - const auto dev = static_cast(zip_drives[i].priv); - int was_empty = zip_is_empty(i); + const auto dev = static_cast(rdisk_drives[i].priv); + int was_empty = rdisk_is_empty(i); - zip_disk_close(dev); - zip_drives[i].read_only = wp; + rdisk_disk_close(dev); + rdisk_drives[i].read_only = wp; if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); - zip_load(dev, filenameBytes.data(), 1); + + if (filename.left(5) == "wp://") + rdisk_drives[i].read_only = 1; + else if (rdisk_drives[i].read_only) + filenameBytes = QString::asprintf(R"(wp://%s)", filename.toUtf8().data()).toUtf8(); + + rdisk_load(dev, filenameBytes.data(), 1); /* Signal media change to the emulated machine. */ - zip_insert(dev); + rdisk_insert(dev); /* The drive was previously empty, transition directly to UNIT ATTENTION. */ if (was_empty) - zip_insert(dev); + rdisk_insert(dev); } - mhm.addImageToHistory(i, ui::MediaType::Zip, zip_drives[i].prev_image_path, zip_drives[i].image_path); + mhm.addImageToHistory(i, ui::MediaType::RDisk, rdisk_drives[i].prev_image_path, rdisk_drives[i].image_path); - ui_sb_update_icon_state(SB_ZIP | i, filename.isEmpty() ? 1 : 0); - zipUpdateMenu(i); - ui_sb_update_tip(SB_ZIP | i); + ui_sb_update_icon_state(SB_RDISK | i, filename.isEmpty() ? 1 : 0); + ui_sb_update_icon_wp(SB_RDISK | i, wp); + rdiskUpdateMenu(i); + ui_sb_update_tip(SB_RDISK | i); config_save(); } void -MediaMenu::zipEject(int i) +MediaMenu::rdiskEject(int i) { - const auto dev = static_cast(zip_drives[i].priv); + const auto dev = static_cast(rdisk_drives[i].priv); - mhm.addImageToHistory(i, ui::MediaType::Zip, zip_drives[i].image_path, QString()); - zip_disk_close(dev); - zip_drives[i].image_path[0] = 0; - if (zip_drives[i].bus_type) { + mhm.addImageToHistory(i, ui::MediaType::RDisk, rdisk_drives[i].image_path, QString()); + rdisk_disk_close(dev); + rdisk_drives[i].image_path[0] = 0; + if (rdisk_drives[i].bus_type) { /* Signal disk change to the emulated machine. */ - zip_insert(dev); + rdisk_insert(dev); } - ui_sb_update_icon_state(SB_ZIP | i, 1); - zipUpdateMenu(i); - ui_sb_update_tip(SB_ZIP | i); + ui_sb_update_icon_state(SB_RDISK | i, 1); + rdiskUpdateMenu(i); + ui_sb_update_tip(SB_RDISK | i); config_save(); } void -MediaMenu::zipReloadPrev(int i) +MediaMenu::rdiskReloadPrev(int i) { - const auto dev = static_cast(zip_drives[i].priv); + const auto dev = static_cast(rdisk_drives[i].priv); - zip_disk_reload(dev); - if (strlen(zip_drives[i].image_path) == 0) { - ui_sb_update_icon_state(SB_ZIP | i, 1); + rdisk_disk_reload(dev); + if (strlen(rdisk_drives[i].image_path) == 0) { + ui_sb_update_icon_state(SB_RDISK | i, 1); } else { - ui_sb_update_icon_state(SB_ZIP | i, 0); + ui_sb_update_icon_state(SB_RDISK | i, 0); } + ui_sb_update_icon_wp(SB_RDISK | i, rdisk_drives[i].read_only); - zipUpdateMenu(i); - ui_sb_update_tip(SB_ZIP | i); + rdiskUpdateMenu(i); + ui_sb_update_tip(SB_RDISK | i); config_save(); } void -MediaMenu::zipReload(int index, int slot) +MediaMenu::rdiskReload(int index, int slot) { - const QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Zip); - zipMount(index, filename, false); - zipUpdateMenu(index); - ui_sb_update_tip(SB_ZIP | index); + const QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::RDisk); + rdiskMount(index, filename, rdisk_drives[index].read_only); + rdiskUpdateMenu(index); + ui_sb_update_tip(SB_RDISK | index); } void -MediaMenu::zipUpdateMenu(int i) +MediaMenu::moUpdateMenu(int i) { - const QString name = zip_drives[i].image_path; - const QString prev_name = zip_drives[i].prev_image_path; - QFileInfo fi(zip_drives[i].image_path); - if (!zipMenus.contains(i)) + QString name = mo_drives[i].image_path; + QString prev_name = mo_drives[i].prev_image_path; + QFileInfo fi(mo_drives[i].image_path); + if (!moMenus.contains(i)) return; - auto *menu = zipMenus[i]; + auto *menu = moMenus[i]; auto childs = menu->children(); - auto *ejectMenu = dynamic_cast(childs[zipEjectPos]); + auto *ejectMenu = dynamic_cast(childs[moEjectPos]); ejectMenu->setEnabled(!name.isEmpty()); ejectMenu->setText(name.isEmpty() ? tr("E&ject") : tr("E&ject %1").arg(fi.fileName())); QString busName = tr("Unknown Bus"); - switch (zip_drives[i].bus_type) { + switch (mo_drives[i].bus_type) { default: break; - case ZIP_BUS_ATAPI: + case MO_BUS_ATAPI: busName = "ATAPI"; break; - case ZIP_BUS_SCSI: + case MO_BUS_SCSI: busName = "SCSI"; break; } - menu->setTitle(tr("ZIP %1 %2 (%3): %4").arg((zip_drives[i].is_250 > 0) ? QString("250") : QString("100"), QString::number(i + 1), busName, name.isEmpty() ? tr("(empty)") : name)); + menu->setTitle(tr("&MO %1 (%2): %3").arg(QString::number(i + 1), busName, name.isEmpty() ? tr("(empty)") : name)); + menu->setToolTip(tr("MO %1 (%2): %3").arg(QString::number(i + 1), busName, name.isEmpty() ? tr("(empty)") : name)); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) - updateImageHistory(i, slot, ui::MediaType::Zip); + updateImageHistory(i, slot, ui::MediaType::Mo); +} + +void +MediaMenu::rdiskUpdateMenu(int i) +{ + const QString name = rdisk_drives[i].image_path; + const QString prev_name = rdisk_drives[i].prev_image_path; + QFileInfo fi(rdisk_drives[i].image_path); + if (!rdiskMenus.contains(i)) + return; + auto *menu = rdiskMenus[i]; + auto childs = menu->children(); + + auto *ejectMenu = dynamic_cast(childs[rdiskEjectPos]); + ejectMenu->setEnabled(!name.isEmpty()); + ejectMenu->setText(name.isEmpty() ? tr("E&ject") : tr("E&ject %1").arg(fi.fileName())); + + QString busName = tr("Unknown Bus"); + switch (rdisk_drives[i].bus_type) { + default: + break; + case RDISK_BUS_ATAPI: + busName = "ATAPI"; + break; + case RDISK_BUS_SCSI: + busName = "SCSI"; + break; + } + + menu->setTitle(tr("&Removable disk %1 (%2): %3").arg(QString::number(i + 1), busName, name.isEmpty() ? tr("(empty)") : name)); + menu->setToolTip(tr("Removable disk %1 (%2): %3").arg(QString::number(i + 1), busName, name.isEmpty() ? tr("(empty)") : name)); + + for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) + updateImageHistory(i, slot, ui::MediaType::RDisk); } void @@ -947,6 +1070,12 @@ MediaMenu::moMount(int i, const QString &filename, bool wp) mo_drives[i].read_only = wp; if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); + + if (filename.left(5) == "wp://") + mo_drives[i].read_only = 1; + else if (mo_drives[i].read_only) + filenameBytes = QString::asprintf(R"(wp://%s)", filename.toUtf8().data()).toUtf8(); + mo_load(dev, filenameBytes.data(), 1); /* Signal media change to the emulated machine. */ @@ -995,6 +1124,7 @@ MediaMenu::moReloadPrev(int i) } else { ui_sb_update_icon_state(SB_MO | i, 0); } + ui_sb_update_icon_state(SB_MO | i, mo_drives[i].read_only); moUpdateMenu(i); ui_sb_update_tip(SB_MO | i); @@ -1011,39 +1141,6 @@ MediaMenu::moReload(int index, int slot) ui_sb_update_tip(SB_MO | index); } -void -MediaMenu::moUpdateMenu(int i) -{ - QString name = mo_drives[i].image_path; - QString prev_name = mo_drives[i].prev_image_path; - QFileInfo fi(mo_drives[i].image_path); - if (!moMenus.contains(i)) - return; - auto *menu = moMenus[i]; - auto childs = menu->children(); - - auto *ejectMenu = dynamic_cast(childs[moEjectPos]); - ejectMenu->setEnabled(!name.isEmpty()); - ejectMenu->setText(name.isEmpty() ? tr("E&ject") : tr("E&ject %1").arg(fi.fileName())); - - QString busName = tr("Unknown Bus"); - switch (mo_drives[i].bus_type) { - default: - break; - case MO_BUS_ATAPI: - busName = "ATAPI"; - break; - case MO_BUS_SCSI: - busName = "SCSI"; - break; - } - - menu->setTitle(tr("MO %1 (%2): %3").arg(QString::number(i + 1), busName, name.isEmpty() ? tr("(empty)") : name)); - - for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) - updateImageHistory(i, slot, ui::MediaType::Mo); -} - void MediaMenu::nicConnect(int i) { @@ -1081,6 +1178,15 @@ MediaMenu::nicUpdateMenu(int i) case NET_TYPE_VDE: netType = "VDE"; break; + case NET_TYPE_TAP: + netType = "TAP"; + break; + case NET_TYPE_NMSWITCH: + netType = "Local Switch"; + break; + case NET_TYPE_NRSWITCH: + netType = "Remote Switch"; + break; } QString devName = DeviceConfig::DeviceName(network_card_getdevice(net_cards_conf[i].device_num), network_card_get_internal_name(net_cards_conf[i].device_num), 1); @@ -1090,7 +1196,8 @@ MediaMenu::nicUpdateMenu(int i) auto *connectedAction = dynamic_cast(childs[netDisconnPos]); connectedAction->setChecked(network_is_connected(i)); - menu->setTitle(tr("NIC %1 (%2) %3").arg(QString::number(i + 1), netType, devName)); + menu->setTitle(tr("&NIC %1 (%2) %3").arg(QString::number(i + 1), netType, devName)); + menu->setToolTip(tr("NIC %1 (%2) %3").arg(QString::number(i + 1), netType, devName)); } QString @@ -1155,21 +1262,21 @@ plat_cdrom_ui_update(uint8_t id, uint8_t reload) } void -zip_eject(uint8_t id) +rdisk_eject(uint8_t id) { - MediaMenu::ptr->zipEject(id); + MediaMenu::ptr->rdiskEject(id); } void -zip_mount(uint8_t id, char *fn, uint8_t wp) +rdisk_mount(uint8_t id, char *fn, uint8_t wp) { - MediaMenu::ptr->zipMount(id, QString(fn), wp); + MediaMenu::ptr->rdiskMount(id, QString(fn), wp); } void -zip_reload(uint8_t id) +rdisk_reload(uint8_t id) { - MediaMenu::ptr->zipReloadPrev(id); + MediaMenu::ptr->rdiskReloadPrev(id); } void diff --git a/src/qt/qt_mediamenu.hpp b/src/qt/qt_mediamenu.hpp index ed97a0a50..fb24d24e0 100644 --- a/src/qt/qt_mediamenu.hpp +++ b/src/qt/qt_mediamenu.hpp @@ -17,7 +17,7 @@ public: void refresh(QMenu *parentMenu); - // because some 86box C-only code needs to call zip and + // because some 86box C-only code needs to call rdisk and // mo eject directly static std::shared_ptr ptr; @@ -51,13 +51,13 @@ public: void clearImageHistory(); void cdromUpdateMenu(int i); - void zipNewImage(int i); - void zipSelectImage(int i, bool wp); - void zipMount(int i, const QString &filename, bool wp); - void zipEject(int i); - void zipReloadPrev(int i); - void zipReload(int index, int slot); - void zipUpdateMenu(int i); + void rdiskNewImage(int i); + void rdiskSelectImage(int i, bool wp); + void rdiskMount(int i, const QString &filename, bool wp); + void rdiskEject(int i); + void rdiskReloadPrev(int i); + void rdiskReload(int index, int slot); + void rdiskUpdateMenu(int i); void moNewImage(int i); void moSelectImage(int i, bool wp); @@ -84,7 +84,7 @@ private: QMap cartridgeMenus; QMap floppyMenus; QMap cdromMenus; - QMap zipMenus; + QMap rdiskMenus; QMap moMenus; QMap netMenus; @@ -111,8 +111,8 @@ private: int cdromEjectPos; int cdromImageHistoryPos[MAX_PREV_IMAGES]; - int zipEjectPos; - int zipImageHistoryPos[MAX_PREV_IMAGES]; + int rdiskEjectPos; + int rdiskImageHistoryPos[MAX_PREV_IMAGES]; int moEjectPos; int moImageHistoryPos[MAX_PREV_IMAGES]; diff --git a/src/qt/qt_newfloppydialog.cpp b/src/qt/qt_newfloppydialog.cpp index 58a7a3df2..d9ae09d0c 100644 --- a/src/qt/qt_newfloppydialog.cpp +++ b/src/qt/qt_newfloppydialog.cpp @@ -29,7 +29,7 @@ extern "C" { #include <86box/plat.h> #include <86box/random.h> #include <86box/scsi_device.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/mo.h> } @@ -110,7 +110,7 @@ static const QStringList floppyTypes = { "2.88 MB", }; -static const QStringList zipTypes = { +static const QStringList rdiskTypes = { "ZIP 100", "ZIP 250", }; @@ -146,11 +146,11 @@ NewFloppyDialog::NewFloppyDialog(MediaType type, QWidget *parent) tr("All images") % util::DlgFilter({ "86f", "dsk", "flp", "im?", "img", "*fd?" }) % tr("Basic sector images") % util::DlgFilter({ "dsk", "flp", "im?", "img", "*fd?" }) % tr("Surface images") % util::DlgFilter({ "86f" }, true)); break; - case MediaType::Zip: - for (int i = 0; i < zipTypes.size(); ++i) { - Models::AddEntry(model, tr(zipTypes[i].toUtf8().data()), i); + case MediaType::RDisk: + for (int i = 0; i < rdiskTypes.size(); ++i) { + Models::AddEntry(model, tr(rdiskTypes[i].toUtf8().data()), i); } - ui->fileField->setFilter(tr("ZIP images") % util::DlgFilter({ "im?", "img", "zdi" }, true)); + ui->fileField->setFilter(tr("Removable disk images") % util::DlgFilter({ "im?", "img", "rdi", "zdi" }, true)); break; case MediaType::Mo: for (int i = 0; i < moTypes.size(); ++i) { @@ -218,13 +218,13 @@ NewFloppyDialog::onCreate() } } break; - case MediaType::Zip: + case MediaType::RDisk: { fileType = fi.suffix().toLower() == QStringLiteral("zdi") ? FileType::Zdi : FileType::Img; std::atomic_bool res; std::thread t([this, &res, filename, fileType, &progress] { - res = createZipSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex() + 12], fileType, progress); + res = createRDiskSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex() + 12], fileType, progress); }); progress.exec(); t.join(); @@ -463,7 +463,7 @@ NewFloppyDialog::createSectorImage(const QString &filename, const disk_size_t &d } bool -NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type, QProgressDialog &pbar) +NewFloppyDialog::createRDiskSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type, QProgressDialog &pbar) { uint64_t total_size = 0; uint32_t total_sectors = 0; diff --git a/src/qt/qt_newfloppydialog.hpp b/src/qt/qt_newfloppydialog.hpp index a342df567..7429fc186 100644 --- a/src/qt/qt_newfloppydialog.hpp +++ b/src/qt/qt_newfloppydialog.hpp @@ -16,7 +16,7 @@ class NewFloppyDialog : public QDialog { public: enum class MediaType { Floppy, - Zip, + RDisk, Mo, }; enum class FileType { @@ -42,7 +42,7 @@ private: bool create86f(const QString &filename, const disk_size_t &disk_size, uint8_t rpm_mode); bool createSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type); - bool createZipSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type, QProgressDialog &pbar); + bool createRDiskSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type, QProgressDialog &pbar); bool createMoSectorImage(const QString &filename, int8_t disk_size, FileType type, QProgressDialog &pbar); }; diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 45bae6ea7..4ec091eb2 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -303,27 +303,27 @@ OpenGLRenderer::find_uniforms(struct glsl_shader *glsl, int num_pass) u->orig.texture_size = get_uniform(p, "OrigTextureSize"); for (i = 0; i < glsl->num_passes; ++i) { - sprintf(s, "Pass%dTexture", (i + 1)); + snprintf(s, sizeof(s) -1, "Pass%dTexture", (i + 1)); u->pass[i].texture = get_uniform(p, s); - sprintf(s, "Pass%dInputSize", (i + 1)); + snprintf(s, sizeof(s) -1, "Pass%dInputSize", (i + 1)); u->pass[i].input_size = get_uniform(p, s); - sprintf(s, "Pass%dTextureSize", (i + 1)); + snprintf(s, sizeof(s) -1, "Pass%dTextureSize", (i + 1)); u->pass[i].texture_size = get_uniform(p, s); - sprintf(s, "PassPrev%dTexture", num_pass - i); + snprintf(s, sizeof(s) -1, "PassPrev%dTexture", num_pass - i); u->prev_pass[i].texture = get_uniform(p, s); - sprintf(s, "PassPrev%dInputSize", num_pass - i); + snprintf(s, sizeof(s) -1, "PassPrev%dInputSize", num_pass - i); u->prev_pass[i].input_size = get_uniform(p, s); - sprintf(s, "PassPrev%dTextureSize", num_pass - i); + snprintf(s, sizeof(s) -1, "PassPrev%dTextureSize", num_pass - i); u->prev_pass[i].texture_size = get_uniform(p, s); } u->prev[0].texture = get_uniform(p, "PrevTexture"); u->prev[0].tex_coord = get_attrib(p, "PrevTexCoord"); for (i = 1; i < MAX_PREV; ++i) { - sprintf(s, "Prev%dTexture", i); + snprintf(s, sizeof(s) -1, "Prev%dTexture", i); u->prev[i].texture = get_uniform(p, s); - sprintf(s, "Prev%dTexCoord", i); + snprintf(s, sizeof(s) -1, "Prev%dTexCoord", i); u->prev[i].tex_coord = get_attrib(p, s); } for (i = 0; i < MAX_PREV; ++i) @@ -434,23 +434,21 @@ OpenGLRenderer::delete_prev(struct shader_prev *prev) void OpenGLRenderer::delete_shader(struct glsl_shader *glsl) { - int i; - for (i = 0; i < glsl->num_passes; ++i) + for (int i = 0; i < glsl->num_passes; ++i) delete_pass(&glsl->passes[i]); if (glsl->has_prev) { delete_pass(&glsl->prev_scene); - for (i = 0; i < MAX_PREV; ++i) + for (int i = 0; i < MAX_PREV; ++i) delete_prev(&glsl->prev[i]); } - for (i = 0; i < glsl->num_lut_textures; ++i) + for (int i = 0; i < glsl->num_lut_textures; ++i) delete_texture(&glsl->lut_textures[i].texture); } void OpenGLRenderer::delete_glsl(glsl_t *glsl) { - int i; - for (i = 0; i < glsl->num_shaders; ++i) + for (int i = 0; i < glsl->num_shaders; ++i) delete_shader(&glsl->shaders[i]); delete_pass(&glsl->scene); delete_pass(&glsl->fs_color); @@ -597,7 +595,7 @@ load_texture(const char *f, struct shader_texture *tex) int bpp = 4; - GLubyte *data = (GLubyte *) malloc(width * height * bpp); + GLubyte *data = (GLubyte *) malloc((size_t) width * height * bpp); int x, y, Y; for (y = 0; y < height; ++y) { @@ -622,7 +620,6 @@ load_texture(const char *f, struct shader_texture *tex) glsl_t * OpenGLRenderer::load_glslp(glsl_t *glsl, int num_shader, const char *f) { - int i, j; glslp_t *p = glslp_parse(f); if (p) { @@ -639,10 +636,10 @@ OpenGLRenderer::load_glslp(glsl_t *glsl, int num_shader, const char *f) gshader->num_lut_textures = p->num_textures; - for (i = 0; i < p->num_textures; ++i) { + for (int i = 0; i < p->num_textures; ++i) { struct texture *texture = &p->textures[i]; - sprintf(file, "%s%s", path, texture->path); + snprintf(file, sizeof(file) - 1, "%s%s", path, texture->path); struct shader_lut_texture *tex = &gshader->lut_textures[i]; strcpy(tex->name, texture->name); @@ -681,18 +678,18 @@ OpenGLRenderer::load_glslp(glsl_t *glsl, int num_shader, const char *f) gshader->input_filter_linear = p->input_filter_linear; gshader->num_parameters = p->num_parameters; - for (j = 0; j < gshader->num_parameters; ++j) + for (int j = 0; j < gshader->num_parameters; ++j) memcpy(&gshader->parameters[j], &p->parameters[j], sizeof(struct shader_parameter)); gshader->num_passes = p->num_shaders; - for (i = 0; i < p->num_shaders; ++i) { + for (int i = 0; i < p->num_shaders; ++i) { struct shader *shader = &p->shaders[i]; struct shader_pass *pass = &gshader->passes[i]; strcpy(pass->alias, shader->alias); if (!strlen(pass->alias)) - sprintf(pass->alias, "Pass %u", (i + 1)); + snprintf(pass->alias, sizeof(pass->alias) - 1, "Pass %u", (i + 1)); ogl3_log("Creating pass %u (%s)\n", (i + 1), pass->alias); ogl3_log("Loading shader %s...\n", shader->shader_fn); @@ -726,7 +723,7 @@ OpenGLRenderer::load_glslp(glsl_t *glsl, int num_shader, const char *f) if (num_shader == glsl->num_shaders - 1) { pass->fbo.id = -1; - for (j = 0; j < 2; ++j) { + for (uint8_t j = 0; j < 2; ++j) { if (pass->scale.mode[j] != SCALE_SOURCE || pass->scale.value[j] != 1) { setup_fbo(shader, &pass->fbo); break; @@ -755,7 +752,7 @@ OpenGLRenderer::load_glslp(glsl_t *glsl, int num_shader, const char *f) if (gshader->has_prev) { struct shader scene_shader_conf; memset(&scene_shader_conf, 0, sizeof(struct shader)); - for (i = 0; i < MAX_PREV; ++i) { + for (int i = 0; i < MAX_PREV; ++i) { setup_fbo(&scene_shader_conf, &gshader->prev[i].fbo); } } @@ -772,7 +769,6 @@ OpenGLRenderer::load_glslp(glsl_t *glsl, int num_shader, const char *f) glsl_t * OpenGLRenderer::load_shaders(int num, char shaders[MAX_USER_SHADERS][512]) { - int i; glsl_t *glsl; glsl = (glsl_t *) malloc(sizeof(glsl_t)); @@ -780,7 +776,7 @@ OpenGLRenderer::load_shaders(int num, char shaders[MAX_USER_SHADERS][512]) glsl->num_shaders = num; int failed = 0; - for (i = num - 1; i >= 0; --i) { + for (int i = num - 1; i >= 0; --i) { const char *f = shaders[i]; if (f && strlen(f)) { if (!load_glslp(glsl, i, f)) { @@ -800,13 +796,12 @@ void OpenGLRenderer::read_shader_config() { char s[512]; - int i, j; - for (i = 0; i < active_shader->num_shaders; ++i) { + for (int i = 0; i < active_shader->num_shaders; ++i) { struct glsl_shader *shader = &active_shader->shaders[i]; char *name = shader->name; - sprintf(s, "GL3 Shaders - %s", name); + snprintf(s, sizeof(s) -1, "GL3 Shaders - %s", name); // shader->shader_refresh_rate = config_get_float(CFG_MACHINE, s, "shader_refresh_rate", -1); - for (j = 0; j < shader->num_parameters; ++j) { + for (int j = 0; j < shader->num_parameters; ++j) { struct shader_parameter *param = &shader->parameters[j]; param->value = config_get_double(s, param->id, param->default_value); } @@ -1233,7 +1228,6 @@ OpenGLRenderer::resizeEvent(QResizeEvent *event) void OpenGLRenderer::render_pass(struct render_data *data) { - int i; GLuint texture_unit = 0; // ogl3_log("pass %d: %gx%g, %gx%g -> %gx%g, %gx%g, %gx%g\n", num_pass, pass->state.input_size[0], @@ -1278,7 +1272,7 @@ OpenGLRenderer::render_pass(struct render_data *data) if (data->shader) { /* parameters */ - for (i = 0; i < data->shader->num_parameters; ++i) + for (int i = 0; i < data->shader->num_parameters; ++i) if (u->parameters[i] >= 0) glw.glUniform1f(u->parameters[i], data->shader->parameters[i].value); @@ -1296,7 +1290,7 @@ OpenGLRenderer::render_pass(struct render_data *data) if (u->orig.texture_size >= 0) glw.glUniform2fv(u->orig.texture_size, 1, orig->state.input_texture_size); - for (i = 0; i < data->pass; ++i) { + for (int i = 0; i < data->pass; ++i) { if (u->pass[i].texture >= 0) { glw.glActiveTexture(GL_TEXTURE0 + texture_unit); glw.glBindTexture(GL_TEXTURE_2D, passes[i].fbo.texture.id); @@ -1323,7 +1317,7 @@ OpenGLRenderer::render_pass(struct render_data *data) if (data->shader->has_prev) { /* loop through each previous frame */ - for (i = 0; i < MAX_PREV; ++i) { + for (int i = 0; i < MAX_PREV; ++i) { if (u->prev[i].texture >= 0) { glw.glActiveTexture(GL_TEXTURE0 + texture_unit); glw.glBindTexture(GL_TEXTURE_2D, data->shader->prev[i].fbo.texture.id); @@ -1340,7 +1334,7 @@ OpenGLRenderer::render_pass(struct render_data *data) } } - for (i = 0; i < data->shader->num_lut_textures; ++i) { + for (int i = 0; i < data->shader->num_lut_textures; ++i) { if (u->lut_textures[i] >= 0) { glw.glActiveTexture(GL_TEXTURE0 + texture_unit); glw.glBindTexture(GL_TEXTURE_2D, data->shader->lut_textures[i].texture.id); @@ -1364,7 +1358,7 @@ OpenGLRenderer::render_pass(struct render_data *data) glw.glDisableVertexAttribArray(data->shader_pass->uniforms.color); if (data->shader && data->shader->has_prev) { - for (i = 0; i < MAX_PREV; ++i) { + for (int i = 0; i < MAX_PREV; ++i) { if (u->prev[i].tex_coord >= 0) glw.glDisableVertexAttribArray(u->prev[i].tex_coord); } @@ -1401,10 +1395,11 @@ OpenGLRenderer::render() if (notReady()) return; - int s, i, j; - struct { - uint32_t x, y, w, h; + uint32_t x; + uint32_t y; + uint32_t w; + uint32_t h; } window_rect; window_rect.x = destination.x(); @@ -1434,7 +1429,10 @@ OpenGLRenderer::render() struct shader_pass *pass = &active_shader->scene; struct { - uint32_t x, y, w, h; + uint32_t x; + uint32_t y; + uint32_t w; + uint32_t h; } rect; rect.x = 0; rect.y = 0; @@ -1496,19 +1494,20 @@ OpenGLRenderer::render() struct shader_pass *orig = &active_shader->scene; struct shader_pass *input = &active_shader->scene; - for (s = 0; s < active_shader->num_shaders; ++s) { + for (int s = 0; s < active_shader->num_shaders; ++s) { struct glsl_shader *shader = &active_shader->shaders[s]; int frame_count = frameCounter; /* loop through each pass */ - for (i = 0; i < shader->num_passes; ++i) { + for (int i = 0; i < shader->num_passes; ++i) { + bool resetFiltering = false; struct shader_pass *pass = &shader->passes[i]; memcpy(pass->state.input_size, input->state.output_size, 2 * sizeof(GLfloat)); memcpy(pass->state.input_texture_size, input->state.output_texture_size, 2 * sizeof(GLfloat)); - for (j = 0; j < 2; ++j) { + for (uint8_t j = 0; j < 2; ++j) { if (pass->scale.mode[j] == SCALE_VIEWPORT) pass->state.output_size[j] = orig_output_size[j] * pass->scale.value[j]; else if (pass->scale.mode[j] == SCALE_ABSOLUTE) @@ -1524,8 +1523,14 @@ OpenGLRenderer::render() glw.glBindFramebuffer(GL_FRAMEBUFFER, pass->fbo.id); glw.glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); - } else + } else { + resetFiltering = true; + glw.glBindTexture(GL_TEXTURE_2D, input->fbo.texture.id); + glw.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, video_filter_method ? GL_LINEAR : GL_NEAREST); + glw.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, video_filter_method ? GL_LINEAR : GL_NEAREST); + glw.glBindTexture(GL_TEXTURE_2D, 0); glw.glViewport(window_rect.x, window_rect.y, window_rect.w, window_rect.h); + } glw.glClearColor(0, 0, 0, 1); glw.glClear(GL_COLOR_BUFFER_BIT); @@ -1570,6 +1575,13 @@ OpenGLRenderer::render() glw.glBindTexture(GL_TEXTURE_2D, 0); } + if (resetFiltering) { + glw.glBindTexture(GL_TEXTURE_2D, input->fbo.texture.id); + glw.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, input->fbo.texture.min_filter); + glw.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, input->fbo.texture.mag_filter); + glw.glBindTexture(GL_TEXTURE_2D, 0); + } + input = pass; } @@ -1626,7 +1638,7 @@ OpenGLRenderer::render() memcpy(pass->state.input_size, input->state.output_size, 2 * sizeof(GLfloat)); memcpy(pass->state.input_texture_size, input->state.output_texture_size, 2 * sizeof(GLfloat)); - for (j = 0; j < 2; ++j) { + for (uint8_t j = 0; j < 2; ++j) { if (pass->scale.mode[j] == SCALE_VIEWPORT) pass->state.output_size[j] = orig_output_size[j] * pass->scale.value[j]; else if (pass->scale.mode[j] == SCALE_ABSOLUTE) @@ -1637,6 +1649,11 @@ OpenGLRenderer::render() pass->state.output_texture_size[j] = next_pow2(pass->state.output_size[j]); } + glw.glBindTexture(GL_TEXTURE_2D, input->fbo.texture.id); + glw.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, video_filter_method ? GL_LINEAR : GL_NEAREST); + glw.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, video_filter_method ? GL_LINEAR : GL_NEAREST); + glw.glBindTexture(GL_TEXTURE_2D, 0); + glw.glViewport(window_rect.x, window_rect.y, window_rect.w, window_rect.h); glw.glClearColor(0, 0, 0, 1); @@ -1692,7 +1709,7 @@ OpenGLRenderer::render() plat_tempfile(fn, NULL, (char*)".png"); strcat(path, fn); - unsigned char *rgba = (unsigned char *)calloc(1, width * height * 4); + unsigned char *rgba = (unsigned char *) calloc(1, (size_t) width * height * 4); glw.glFinish(); glw.glReadPixels(window_rect.x, window_rect.y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, rgba); diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index 4d1f68acb..776a2f53e 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -34,6 +34,7 @@ # include #endif +#include #include #include #include diff --git a/src/qt/qt_openglshaderconfig.ui b/src/qt/qt_openglshaderconfig.ui index 1aebdb6f6..dc743f57e 100644 --- a/src/qt/qt_openglshaderconfig.ui +++ b/src/qt/qt_openglshaderconfig.ui @@ -15,7 +15,7 @@ - QLayout::SizeConstraint::SetMinAndMaxSize + QLayout::SetMinAndMaxSize @@ -33,10 +33,10 @@ - QLayout::SizeConstraint::SetMaximumSize + QLayout::SetMaximumSize - QFormLayout::FieldGrowthPolicy::AllNonFixedFieldsGrow + QFormLayout::AllNonFixedFieldsGrow @@ -45,10 +45,10 @@ - Qt::Orientation::Horizontal + Qt::Horizontal - QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok|QDialogButtonBox::StandardButton::Reset + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset diff --git a/src/qt/qt_openglshadermanagerdialog.ui b/src/qt/qt_openglshadermanagerdialog.ui index 2a72c69ed..82006c713 100644 --- a/src/qt/qt_openglshadermanagerdialog.ui +++ b/src/qt/qt_openglshadermanagerdialog.ui @@ -15,8 +15,82 @@ - QLayout::SizeConstraint::SetFixedSize + QLayout::SetFixedSize + + + + Render behavior + + + + QLayout::SetDefaultConstraint + + + + + Synchronize with video + + + true + + + + + + + Use target framerate: + + + + + + + 15 + + + 240 + + + 60 + + + Qt::Horizontal + + + false + + + false + + + + + + + fps + + + 15 + + + 240 + + + 60 + + + + + + + VSync + + + + + + @@ -24,22 +98,22 @@ - QLayout::SizeConstraint::SetFixedSize + QLayout::SetFixedSize - QAbstractItemView::DragDropMode::InternalMove + QAbstractItemView::InternalMove - QAbstractItemView::SelectionBehavior::SelectItems + QAbstractItemView::SelectItems - QLayout::SizeConstraint::SetFixedSize + QLayout::SetFixedSize @@ -58,7 +132,7 @@ - Qt::Orientation::Vertical + Qt::Vertical @@ -95,7 +169,7 @@ - Qt::Orientation::Vertical + Qt::Vertical @@ -108,10 +182,10 @@ - Qt::Orientation::Vertical + Qt::Vertical - QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok false @@ -123,80 +197,6 @@ - - - - Render behavior - - - - QLayout::SizeConstraint::SetDefaultConstraint - - - - - Use target framerate: - - - - - - - 15 - - - 240 - - - 60 - - - Qt::Orientation::Horizontal - - - false - - - false - - - - - - - Synchronize with video - - - true - - - - - - - VSync - - - - - - - fps - - - 15 - - - 240 - - - 60 - - - - - - diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 3bdbdf569..5d3b76dcb 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -176,14 +177,28 @@ do_stop(void) #endif } +extern bool acp_utf8; void plat_get_exe_name(char *s, int size) { +#ifdef Q_OS_WINDOWS + wchar_t *temp; + + if (acp_utf8) + GetModuleFileNameA(NULL, s, size); + else { + temp = (wchar_t*)calloc(size, sizeof(wchar_t)); + GetModuleFileNameW(NULL, temp, size); + c16stombs(s, (uint16_t*)temp, size); + free(temp); + } +#else QByteArray exepath_temp = QCoreApplication::applicationDirPath().toLocal8Bit(); memcpy(s, exepath_temp.data(), std::min((qsizetype) exepath_temp.size(), (qsizetype) size)); path_slash(s); +#endif } uint32_t @@ -340,9 +355,25 @@ path_get_slash(char *path) void path_append_filename(char *dest, const char *s1, const char *s2) { - strcpy(dest, s1); - path_slash(dest); - strcat(dest, s2); + size_t dest_size = 260; + size_t len; + + if (!dest || !s1 || !s2) + return; + + snprintf(dest, dest_size, "%s", s1); + len = strlen(dest); + + if (len > 0 && dest[len - 1] != '/' && dest[len - 1] != '\\') { + if (len + 1 < dest_size) { + dest[len++] = '/'; + dest[len] = '\0'; + } + } + + if (len < dest_size - 1) { + strncat(dest, s2, dest_size - len - 1); + } } void @@ -571,8 +602,6 @@ c16stombs(char dst[], const uint16_t src[], int len) } #endif -# define MOUSE_CAPTURE_KEYSEQ "F8+F12" - #ifdef _WIN32 # if defined(__amd64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64) # define LIB_NAME_GS "gsdll64.dll" @@ -595,14 +624,8 @@ ProgSettings::reloadStrings() { translatedstrings.clear(); translatedstrings[STRING_MOUSE_CAPTURE] = QCoreApplication::translate("", "Click to capture mouse").toStdWString(); - - char mouseCaptureKeyseq[100]; - sprintf(mouseCaptureKeyseq, qPrintable(QCoreApplication::translate("", "Press %s to release mouse")), acc_keys[FindAccelerator("release_mouse")].seq); - translatedstrings[STRING_MOUSE_RELEASE] = QString(mouseCaptureKeyseq).toStdWString(); - - sprintf(mouseCaptureKeyseq, qPrintable(QCoreApplication::translate("", "Press %s or middle button to release mouse")), acc_keys[FindAccelerator("release_mouse")].seq); - translatedstrings[STRING_MOUSE_RELEASE_MMB] = QString(mouseCaptureKeyseq).toStdWString(); - + translatedstrings[STRING_MOUSE_RELEASE] = QCoreApplication::translate("", "Press %1 to release mouse").arg(QKeySequence(acc_keys[FindAccelerator("release_mouse")].seq, QKeySequence::PortableText).toString(QKeySequence::NativeText)).toStdWString(); + translatedstrings[STRING_MOUSE_RELEASE_MMB] = QCoreApplication::translate("", "Press %1 or middle button to release mouse").arg(QKeySequence(acc_keys[FindAccelerator("release_mouse")].seq, QKeySequence::PortableText).toString(QKeySequence::NativeText)).toStdWString(); translatedstrings[STRING_INVALID_CONFIG] = QCoreApplication::translate("", "Invalid configuration").toStdWString(); translatedstrings[STRING_NO_ST506_ESDI_CDROM] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString(); translatedstrings[STRING_PCAP_ERROR_NO_DEVICES] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); @@ -783,8 +806,8 @@ plat_set_thread_name(void *thread, const char *name) if (pSetThreadDescription) { size_t len = strlen(name) + 1; - wchar_t wname[len + 1]; - mbstowcs(wname, name, len); + wchar_t wname[2048]; + mbstowcs(wname, name, (len >= 1024) ? 1024 : len); pSetThreadDescription(thread ? (HANDLE) thread : GetCurrentThread(), wname); } #else diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index 4894b99c0..5dfae866e 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -96,7 +96,6 @@ ProgSettings::ProgSettings(QWidget *parent) ui->checkBoxConfirmExit->setChecked(confirm_exit); ui->checkBoxConfirmSave->setChecked(confirm_save); ui->checkBoxConfirmHardReset->setChecked(confirm_reset); - ui->checkBoxFullscreenFirst->setChecked(video_fullscreen_first); #ifndef Q_OS_WINDOWS ui->checkBoxMultimediaKeys->setHidden(true); @@ -111,7 +110,6 @@ ProgSettings::accept() confirm_exit = ui->checkBoxConfirmExit->isChecked() ? 1 : 0; confirm_save = ui->checkBoxConfirmSave->isChecked() ? 1 : 0; confirm_reset = ui->checkBoxConfirmHardReset->isChecked() ? 1 : 0; - video_fullscreen_first = ui->checkBoxFullscreenFirst->isChecked() ? 1 : 0; inhibit_multimedia_keys = ui->checkBoxMultimediaKeys->isChecked() ? 1 : 0; loadTranslators(QCoreApplication::instance()); @@ -175,7 +173,7 @@ ProgSettings::languageCodeToId(QString langCode) QString ProgSettings::languageIdToCode(int id) { - if ((id == 0) || (id >= languages.length())) { + if ((id <= 0) || (id >= languages.length())) { return "system"; } return languages[id].first; diff --git a/src/qt/qt_progsettings.ui b/src/qt/qt_progsettings.ui index b01199dfd..abaee5019 100644 --- a/src/qt/qt_progsettings.ui +++ b/src/qt/qt_progsettings.ui @@ -27,28 +27,15 @@ - QLayout::SizeConstraint::SetFixedSize + QLayout::SetFixedSize - - + + - Default + Language: - - - - Qt::Orientation::Horizontal - - - - 40 - 20 - - - - @@ -61,20 +48,10 @@ - - - - <html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html> - - - Select media images from program working directory - - - - Qt::Orientation::Horizontal + Qt::Horizontal @@ -84,13 +61,20 @@ - - + + Default + + + + Mouse sensitivity: + + + @@ -109,31 +93,37 @@ 100 - Qt::Orientation::Horizontal + Qt::Horizontal - - - - Language: - - - - - - - Ask for confirmation before saving settings - - - - - + + - Qt::Orientation::Horizontal + Qt::Horizontal - - QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + + + 40 + 20 + + + + + + + + Default + + + + + + + <html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html> + + + Select media images from program working directory @@ -144,17 +134,10 @@ - - + + - Mouse sensitivity: - - - - - - - Ask for confirmation before hard resetting + Ask for confirmation before saving settings @@ -165,10 +148,20 @@ - - + + - Display hotkey message when entering full-screen mode + Ask for confirmation before hard resetting + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 431b3609b..821b4c741 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -21,7 +21,6 @@ #include "qt_rendererstack.hpp" #include "ui_qt_rendererstack.h" -#include "qt_hardwarerenderer.hpp" #include "qt_openglrenderer.hpp" #include "qt_softwarerenderer.hpp" #include "qt_vulkanwindowrenderer.hpp" @@ -41,6 +40,22 @@ #include #include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef WAYLAND +# include "wl_mouse.hpp" +#endif + #ifdef __APPLE__ # include #endif @@ -61,6 +76,11 @@ struct mouseinputdata { static mouseinputdata mousedata; extern MainWindow *main_window; + +#ifdef Q_OS_WINDOWS +HWND rw_hwnd; +#endif + RendererStack::RendererStack(QWidget *parent, int monitor_index) : QStackedWidget(parent) , ui(new Ui::RendererStack) @@ -77,7 +97,7 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index) m_monitor_index = monitor_index; #if defined __unix__ && !defined __HAIKU__ - char auto_mouse_type[16]; + memset(auto_mouse_type, 0, sizeof (auto_mouse_type)); 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")) @@ -146,6 +166,10 @@ int ignoreNextMouseEvent = 1; void RendererStack::mouseReleaseEvent(QMouseEvent *event) { +#ifdef Q_OS_WINDOWS + rw_hwnd = (HWND) this->winId(); +#endif + 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)) && @@ -251,7 +275,9 @@ RendererStack::mouseMoveEvent(QMouseEvent *event) leaveEvent((QEvent *) event); ignoreNextMouseEvent--; } +#if !defined _WIN32 QCursor::setPos(mapToGlobal(QPoint(width() / 2, height() / 2))); +#endif ignoreNextMouseEvent = 2; oldPos = event->pos(); #endif @@ -329,24 +355,6 @@ RendererStack::createRenderer(Renderer renderer) #endif } break; - case Renderer::OpenGL: - { - this->createWinId(); - auto hw = new HardwareRenderer(this); - rendererWindow = hw; - connect(this, &RendererStack::blitToRenderer, hw, &HardwareRenderer::onBlit, Qt::QueuedConnection); - current.reset(this->createWindowContainer(hw, this)); - break; - } - case Renderer::OpenGLES: - { - this->createWinId(); - auto hw = new HardwareRenderer(this, HardwareRenderer::RenderType::OpenGLES); - rendererWindow = hw; - connect(this, &RendererStack::blitToRenderer, hw, &HardwareRenderer::onBlit, Qt::QueuedConnection); - current.reset(this->createWindowContainer(hw, this)); - break; - } case Renderer::OpenGL3: { this->createWinId(); @@ -405,8 +413,9 @@ RendererStack::createRenderer(Renderer renderer) } #endif } - if (current.get() == nullptr) + if (current.get() == nullptr) { return; + } current->setFocusPolicy(Qt::NoFocus); current->setFocusProxy(this); current->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -649,6 +658,14 @@ RendererStack::setFocusRenderer() void RendererStack::onResize(int width, int height) { +#ifdef Q_OS_WINDOWS + if (mouse_capture) { + RECT rect; + if (GetWindowRect((HWND)this->winId(), &rect)) { + ClipCursor(&rect); + } + } +#endif 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 172dc2fe6..99de85c99 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -80,8 +80,6 @@ public: enum class Renderer { Software, - OpenGL, - OpenGLES, OpenGL3, Vulkan, None = -1 @@ -137,6 +135,8 @@ private: std::atomic_bool rendererTakesScreenshots; std::atomic_bool switchInProgress{false}; + + char auto_mouse_type[16]; }; #endif // QT_RENDERERCONTAINER_HPP diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp index 19a537652..3d06f53e3 100644 --- a/src/qt/qt_settings.cpp +++ b/src/qt/qt_settings.cpp @@ -164,24 +164,24 @@ Settings::Settings(QWidget *parent) connect(floppyCdrom, &SettingsFloppyCDROM::cdromChannelChanged, otherRemovable, &SettingsOtherRemovable::reloadBusChannels_MO); connect(floppyCdrom, &SettingsFloppyCDROM::cdromChannelChanged, otherRemovable, - &SettingsOtherRemovable::reloadBusChannels_ZIP); + &SettingsOtherRemovable::reloadBusChannels_RDisk); connect(harddisks, &SettingsHarddisks::driveChannelChanged, floppyCdrom, &SettingsFloppyCDROM::reloadBusChannels); connect(harddisks, &SettingsHarddisks::driveChannelChanged, otherRemovable, &SettingsOtherRemovable::reloadBusChannels_MO); connect(harddisks, &SettingsHarddisks::driveChannelChanged, otherRemovable, - &SettingsOtherRemovable::reloadBusChannels_ZIP); + &SettingsOtherRemovable::reloadBusChannels_RDisk); connect(otherRemovable, &SettingsOtherRemovable::moChannelChanged, harddisks, &SettingsHarddisks::reloadBusChannels); connect(otherRemovable, &SettingsOtherRemovable::moChannelChanged, floppyCdrom, &SettingsFloppyCDROM::reloadBusChannels); connect(otherRemovable, &SettingsOtherRemovable::moChannelChanged, otherRemovable, - &SettingsOtherRemovable::reloadBusChannels_ZIP); - connect(otherRemovable, &SettingsOtherRemovable::zipChannelChanged, harddisks, + &SettingsOtherRemovable::reloadBusChannels_RDisk); + connect(otherRemovable, &SettingsOtherRemovable::rdiskChannelChanged, harddisks, &SettingsHarddisks::reloadBusChannels); - connect(otherRemovable, &SettingsOtherRemovable::zipChannelChanged, floppyCdrom, + connect(otherRemovable, &SettingsOtherRemovable::rdiskChannelChanged, floppyCdrom, &SettingsFloppyCDROM::reloadBusChannels); - connect(otherRemovable, &SettingsOtherRemovable::zipChannelChanged, otherRemovable, + connect(otherRemovable, &SettingsOtherRemovable::rdiskChannelChanged, otherRemovable, &SettingsOtherRemovable::reloadBusChannels_MO); connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, this, diff --git a/src/qt/qt_settings_bus_tracking.cpp b/src/qt/qt_settings_bus_tracking.cpp index 6fb8637da..c811cc7c0 100644 --- a/src/qt/qt_settings_bus_tracking.cpp +++ b/src/qt/qt_settings_bus_tracking.cpp @@ -23,10 +23,14 @@ #include "86box/hdd.h" #include "86box/scsi.h" +#include "86box/cdrom.h" #include "qt_settings_bus_tracking.hpp" SettingsBusTracking::SettingsBusTracking() { + mitsumi_tracking = false; + + mke_tracking = 0x0000000000000000ULL; mfm_tracking = 0x0000000000000000ULL; esdi_tracking = 0x0000000000000000ULL; xta_tracking = 0x0000000000000000ULL; @@ -38,40 +42,76 @@ SettingsBusTracking::SettingsBusTracking() scsi_tracking[i] = 0x0000000000000000ULL; } +uint8_t +SettingsBusTracking::next_free_mke_channel() +{ + uint64_t mask; + uint8_t ret = CHANNEL_NONE; + + for (uint8_t i = 0; i < 4; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + + if (!(mke_tracking & mask)) { + ret = (uint8_t) i; + break; + } + } + + return ret; +} + uint8_t SettingsBusTracking::next_free_mfm_channel() { - if ((mfm_tracking & 0xff00ULL) && !(mfm_tracking & 0x00ffULL)) - return 1; + uint64_t mask; + uint8_t ret = CHANNEL_NONE; - if (!(mfm_tracking & 0xff00ULL) && (mfm_tracking & 0x00ffULL)) - return 0; + for (uint8_t i = 0; i < 2; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); - return CHANNEL_NONE; + if (!(mfm_tracking & mask)) { + ret = (uint8_t) i; + break; + } + } + + return ret; } uint8_t SettingsBusTracking::next_free_esdi_channel() { - if ((esdi_tracking & 0xff00ULL) && !(esdi_tracking & 0x00ffULL)) - return 1; + uint64_t mask; + uint8_t ret = CHANNEL_NONE; - if (!(esdi_tracking & 0xff00ULL) && (esdi_tracking & 0x00ffULL)) - return 0; + for (uint8_t i = 0; i < 2; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); - return CHANNEL_NONE; + if (!(esdi_tracking & mask)) { + ret = (uint8_t) i; + break; + } + } + + return ret; } uint8_t SettingsBusTracking::next_free_xta_channel() { - if ((xta_tracking & 0xff00ULL) && !(xta_tracking & 0x00ffULL)) - return 1; + uint64_t mask; + uint8_t ret = CHANNEL_NONE; - if (!(xta_tracking & 0xff00ULL) && (xta_tracking & 0x00ffULL)) - return 0; + for (uint8_t i = 0; i < 2; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); - return CHANNEL_NONE; + if (!(xta_tracking & mask)) { + ret = (uint8_t) i; + break; + } + } + + return ret; } uint8_t @@ -204,22 +244,33 @@ QList SettingsBusTracking::busChannelsInUse(const int bus) { int element; uint64_t mask; switch (bus) { + case CDROM_BUS_MKE: + for (uint8_t i = 0; i < 4; i++) { + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + if (mke_tracking & mask) + channelsInUse.append(i); + } + break; + case CDROM_BUS_MITSUMI: + if (mitsumi_tracking) + channelsInUse.append(0); + break; case HDD_BUS_MFM: - for (uint8_t i = 0; i < 32; i++) { + for (uint8_t i = 0; i < 2; i++) { mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (mfm_tracking & mask) channelsInUse.append(i); } break; case HDD_BUS_ESDI: - for (uint8_t i = 0; i < 32; i++) { + for (uint8_t i = 0; i < 2; i++) { mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (esdi_tracking & mask) channelsInUse.append(i); } break; case HDD_BUS_XTA: - for (uint8_t i = 0; i < 32; i++) { + for (uint8_t i = 0; i < 2; i++) { mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (xta_tracking & mask) channelsInUse.append(i); @@ -263,6 +314,17 @@ SettingsBusTracking::device_track(int set, uint8_t dev_type, int bus, int channe uint64_t mask; switch (bus) { + case CDROM_BUS_MKE: + mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); + + if (set) + mke_tracking |= mask; + else + mke_tracking &= ~mask; + break; + case CDROM_BUS_MITSUMI: + mitsumi_tracking = set; + break; case HDD_BUS_MFM: mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); diff --git a/src/qt/qt_settings_bus_tracking.hpp b/src/qt/qt_settings_bus_tracking.hpp index 917706428..d17ed090a 100644 --- a/src/qt/qt_settings_bus_tracking.hpp +++ b/src/qt/qt_settings_bus_tracking.hpp @@ -8,7 +8,7 @@ #define DEV_HDD 0x01 #define DEV_CDROM 0x02 -#define DEV_ZIP 0x04 +#define DEV_RDISK 0x04 #define DEV_MO 0x08 #define BUS_MFM 0 @@ -31,12 +31,14 @@ public: QList busChannelsInUse(int bus); /* These return 0xff is none is free. */ + uint8_t next_free_mke_channel(); 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 mke_bus_full(); int mfm_bus_full(); int esdi_bus_full(); int xta_bus_full(); @@ -44,11 +46,13 @@ public: 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. + Device type: 1 = Hard Disk, 2 = CD-ROM, 4 = Removable disk, 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 mke_tracking { 0 }; /* 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. */ @@ -61,6 +65,8 @@ private: 8 bits per device (future-proofing) = 2048 bits. */ uint64_t scsi_tracking[32] { 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, 0, 0, 0, 0 }; + + bool mitsumi_tracking; }; #endif // QT_SETTINGS_BUS_TRACKING_HPP diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index fbe6ab5cc..15b2f4588 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -51,22 +51,29 @@ SettingsDisplay::~SettingsDisplay() void SettingsDisplay::save() { - gfxcard[0] = ui->comboBoxVideo->currentData().toInt(); // TODO +#if 0 + for (uint8_t i = 0; i < GFXCARD_MAX; ++i) { + QComboBox *cbox = findChild(QString("comboBoxVideo%1").arg(i + 1)); + gfxcard[i] = cbox->currentData().toInt(); + } +#else + gfxcard[0] = ui->comboBoxVideo->currentData().toInt(); for (uint8_t i = 1; i < GFXCARD_MAX; i ++) - gfxcard[i] = ui->comboBoxVideoSecondary->currentData().toInt(); + gfxcard[i] = ui->comboBoxVideoSecondary->currentData().toInt(); +#endif voodoo_enabled = ui->checkBoxVoodoo->isChecked() ? 1 : 0; ibm8514_standalone_enabled = ui->checkBox8514->isChecked() ? 1 : 0; xga_standalone_enabled = ui->checkBoxXga->isChecked() ? 1 : 0; - da2_standalone_enabled = ui->checkBoxDa2->isChecked() ? 1 : 0; + da2_standalone_enabled = ui->checkBoxDa2->isChecked() ? 1 : 0; } void SettingsDisplay::onCurrentMachineChanged(int machineId) { // win_settings_video_proc, WM_INITDIALOG - this->machineId = machineId; + this->machineId = machineId; auto curVideoCard = videoCard[0]; auto *model = ui->comboBoxVideo->model(); @@ -98,25 +105,26 @@ SettingsDisplay::onCurrentMachineChanged(int machineId) } model->removeRows(0, removeRows); + // TODO if (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0) { ui->comboBoxVideo->setEnabled(false); ui->comboBoxVideoSecondary->setEnabled(false); - ui->pushButtonConfigureSecondary->setEnabled(false); + ui->pushButtonConfigureVideoSecondary->setEnabled(false); selectedRow = 1; } else { ui->comboBoxVideo->setEnabled(true); ui->comboBoxVideoSecondary->setEnabled(true); - ui->pushButtonConfigureSecondary->setEnabled(true); + ui->pushButtonConfigureVideoSecondary->setEnabled(true); } ui->comboBoxVideo->setCurrentIndex(selectedRow); // TODO for (uint8_t i = 1; i < GFXCARD_MAX; i ++) if (gfxcard[i] == 0) - ui->pushButtonConfigureSecondary->setEnabled(false); + ui->pushButtonConfigureVideoSecondary->setEnabled(false); } void -SettingsDisplay::on_pushButtonConfigure_clicked() +SettingsDisplay::on_pushButtonConfigureVideo_clicked() { int videoCard = ui->comboBoxVideo->currentData().toInt(); auto *device = video_card_getdevice(videoCard); @@ -144,11 +152,8 @@ SettingsDisplay::on_pushButtonConfigure8514_clicked() void SettingsDisplay::on_pushButtonConfigureXga_clicked() { - if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { + if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) DeviceConfig::ConfigureDevice(&xga_device); - } else { - DeviceConfig::ConfigureDevice(&xga_isa_device); - } } void @@ -160,17 +165,17 @@ SettingsDisplay::on_pushButtonConfigureDa2_clicked() void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } - static QRegularExpression voodooRegex("3dfx|voodoo|banshee", QRegularExpression::CaseInsensitiveOption); + + static QRegularExpression voodooRegex("3dfx|voodoo|banshee|raven", QRegularExpression::CaseInsensitiveOption); auto curVideoCard_2 = videoCard[1]; videoCard[0] = ui->comboBoxVideo->currentData().toInt(); if (videoCard[0] == VID_INTERNAL) - ui->pushButtonConfigure->setEnabled(machine_has_flags(machineId, MACHINE_VIDEO) && - device_has_config(machine_get_vid_device(machineId))); + ui->pushButtonConfigureVideo->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); + ui->pushButtonConfigureVideo->setEnabled(video_card_has_config(videoCard[0]) > 0); bool machineHasPci = machine_has_bus(machineId, MACHINE_BUS_PCI) > 0; ui->pushButtonConfigureVoodoo->setEnabled(machineHasPci && ui->checkBoxVoodoo->isChecked()); @@ -178,10 +183,10 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) bool machineHasMca = machine_has_bus(machineId, MACHINE_BUS_MCA) > 0; bool videoCardHas8514 = ((videoCard[0] == VID_INTERNAL) ? machine_has_flags(machineId, MACHINE_VIDEO_8514A) : (video_card_get_flags(videoCard[0]) == VIDEO_FLAG_TYPE_8514)); - bool videoCardHasXga = ((videoCard[0] == VID_INTERNAL) ? machine_has_flags(machineId, MACHINE_VIDEO_XGA) : (video_card_get_flags(videoCard[0]) == VIDEO_FLAG_TYPE_XGA)); + bool videoCardHasXga = ((videoCard[0] == VID_INTERNAL) ? 0 : (video_card_get_flags(videoCard[0]) == VIDEO_FLAG_TYPE_XGA)); bool machineSupports8514 = ((machineHasIsa16 || machineHasMca) && !videoCardHas8514); - bool machineSupportsXga = (((machineHasIsa16 && device_available(&xga_isa_device)) || (machineHasMca && device_available(&xga_device))) && !videoCardHasXga); + bool machineSupportsXga = ((machineHasMca && device_available(&xga_device)) && !videoCardHasXga); bool machineSupportsDa2 = machineHasMca && device_available(&ps55da2_device); ui->checkBox8514->setEnabled(machineSupports8514); @@ -233,7 +238,7 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) if ((videoCard[1] == 0) || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) { ui->comboBoxVideoSecondary->setCurrentIndex(0); - ui->pushButtonConfigureSecondary->setEnabled(false); + ui->pushButtonConfigureVideoSecondary->setEnabled(false); } // Is the currently selected video card a voodoo? @@ -287,15 +292,15 @@ void SettingsDisplay::on_comboBoxVideoSecondary_currentIndexChanged(int index) { if (index < 0) { - ui->pushButtonConfigureSecondary->setEnabled(false); + ui->pushButtonConfigureVideoSecondary->setEnabled(false); return; } videoCard[1] = ui->comboBoxVideoSecondary->currentData().toInt(); - ui->pushButtonConfigureSecondary->setEnabled(index != 0 && video_card_has_config(videoCard[1]) > 0); + ui->pushButtonConfigureVideoSecondary->setEnabled(index != 0 && video_card_has_config(videoCard[1]) > 0); } void -SettingsDisplay::on_pushButtonConfigureSecondary_clicked() +SettingsDisplay::on_pushButtonConfigureVideoSecondary_clicked() { auto *device = video_card_getdevice(ui->comboBoxVideoSecondary->currentData().toInt()); DeviceConfig::ConfigureDevice(device); diff --git a/src/qt/qt_settingsdisplay.hpp b/src/qt/qt_settingsdisplay.hpp index 854fce658..7eca7cc60 100644 --- a/src/qt/qt_settingsdisplay.hpp +++ b/src/qt/qt_settingsdisplay.hpp @@ -22,22 +22,23 @@ public slots: void onCurrentMachineChanged(int machineId); private slots: - void on_pushButtonConfigureSecondary_clicked(); - -private slots: - void on_comboBoxVideoSecondary_currentIndexChanged(int index); - -private slots: - void on_checkBoxVoodoo_stateChanged(int state); - void on_checkBox8514_stateChanged(int state); - void on_checkBoxXga_stateChanged(int state); - void on_checkBoxDa2_stateChanged(int state); void on_comboBoxVideo_currentIndexChanged(int index); + void on_pushButtonConfigureVideo_clicked(); + + void on_comboBoxVideoSecondary_currentIndexChanged(int index); + void on_pushButtonConfigureVideoSecondary_clicked(); + + void on_checkBoxVoodoo_stateChanged(int state); void on_pushButtonConfigureVoodoo_clicked(); + + void on_checkBox8514_stateChanged(int state); void on_pushButtonConfigure8514_clicked(); + + void on_checkBoxXga_stateChanged(int state); void on_pushButtonConfigureXga_clicked(); + + void on_checkBoxDa2_stateChanged(int state); void on_pushButtonConfigureDa2_clicked(); - void on_pushButtonConfigure_clicked(); private: Ui::SettingsDisplay *ui; diff --git a/src/qt/qt_settingsdisplay.ui b/src/qt/qt_settingsdisplay.ui index a8799204c..c5eba7adf 100644 --- a/src/qt/qt_settingsdisplay.ui +++ b/src/qt/qt_settingsdisplay.ui @@ -26,28 +26,8 @@ 0 - - - - - 0 - 0 - - - - Configure - - - - - - - XGA Graphics - - - - + 0 @@ -72,15 +52,21 @@ - - + + + + + 0 + 0 + + Configure - + 0 @@ -92,10 +78,23 @@ - - + + + + + 0 + 0 + + + + 30 + + + + + - IBM 8514/A Graphics + Configure @@ -106,6 +105,20 @@ + + + + Configure + + + + + + + IBM 8514/A Graphics + + + @@ -113,6 +126,13 @@ + + + + XGA Graphics + + + @@ -134,26 +154,6 @@ - - - - Configure - - - - - - - - 0 - 0 - - - - 30 - - - diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index 5e0ec7bed..f597aebe6 100644 --- a/src/qt/qt_settingsfloppycdrom.cpp +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -69,6 +69,7 @@ setCDROMBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint case CDROM_BUS_ATAPI: case CDROM_BUS_SCSI: case CDROM_BUS_MITSUMI: + case CDROM_BUS_MKE: icon = QIcon(":/settings/qt/icons/cdrom.ico"); break; } @@ -149,7 +150,7 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) this, &SettingsFloppyCDROM::onFloppyRowChanged); ui->tableViewFloppy->setCurrentIndex(model->index(0, 0)); - Harddrives::populateRemovableBuses(ui->comboBoxBus->model()); + Harddrives::populateCDROMBuses(ui->comboBoxBus->model()); model = ui->comboBoxSpeed->model(); for (int i = 0; i < 72; i++) Models::AddEntry(model, QString("%1x").arg(i + 1), i + 1); @@ -170,11 +171,12 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) setCDROMSpeed(model, idx.siblingAtColumn(1), cdrom[i].speed); else setCDROMSpeed(model, idx.siblingAtColumn(1), speed); - if (cdrom[i].bus_type == CDROM_BUS_ATAPI) + if (cdrom[i].bus_type == CDROM_BUS_MKE) + Harddrives::busTrackClass->device_track(1, DEV_CDROM, cdrom[i].bus_type, cdrom[i].mke_channel); + else 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); } @@ -195,9 +197,10 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) 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)) && + if (((bus_type == CDROM_BUS_MKE) || (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))) { + ((cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH) && (bus_type != BUS_TYPE_MKE)))) { QString name = CDROMName(j); Models::AddEntry(modelType, name, j); if (cdrom[cdromIdx].type == j) @@ -274,7 +277,7 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) int speed = cdrom_get_speed(type); if (speed == -1) { speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); - ui->comboBoxSpeed->setEnabled(true); + ui->comboBoxSpeed->setEnabled((bus == CDROM_BUS_DISABLED) ? false : true); } else ui->comboBoxSpeed->setEnabled(false); ui->comboBoxSpeed->setCurrentIndex(speed == 0 ? 7 : speed - 1); @@ -286,9 +289,10 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) int selectedTypeRow = 0; int eligibleRows = 0; while (cdrom_drive_types[j].bus_type != BUS_TYPE_NONE) { - if (((bus == CDROM_BUS_ATAPI) || (bus == CDROM_BUS_SCSI)) && + if (((bus == CDROM_BUS_MKE) || (bus == CDROM_BUS_ATAPI) || + (bus == CDROM_BUS_SCSI)) && ((cdrom_drive_types[j].bus_type == bus) || - (cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH))) { + ((cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH) && (bus != BUS_TYPE_MKE)))) { QString name = CDROMName(j); Models::AddEntry(modelType, name, j); if (type == j) @@ -359,14 +363,16 @@ SettingsFloppyCDROM::on_comboBoxSpeed_activated(int index) void SettingsFloppyCDROM::on_comboBoxBus_activated(int) { - auto i = ui->tableViewCDROM->selectionModel()->currentIndex().siblingAtColumn(0); + auto i = ui->tableViewCDROM->selectionModel()->currentIndex().siblingAtColumn(0); uint8_t bus_type = ui->comboBoxBus->currentData().toUInt(); - int cdromIdx = ui->tableViewCDROM->selectionModel()->currentIndex().data().toInt(); + 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()); - if (bus_type == CDROM_BUS_ATAPI) + if (bus_type == CDROM_BUS_MKE) + ui->comboBoxChannel->setCurrentIndex(Harddrives::busTrackClass->next_free_mke_channel()); + else if (bus_type == CDROM_BUS_ATAPI) ui->comboBoxChannel->setCurrentIndex(Harddrives::busTrackClass->next_free_ide_channel()); else if (bus_type == CDROM_BUS_SCSI) ui->comboBoxChannel->setCurrentIndex(Harddrives::busTrackClass->next_free_scsi_id()); @@ -384,13 +390,14 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int) auto *modelType = ui->comboBoxCDROMType->model(); int removeRows = modelType->rowCount(); - uint32_t j = 0; - int selectedTypeRow = 0; - int eligibleRows = 0; + 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)) && + if (((bus_type == CDROM_BUS_MKE) || (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))) { + ((cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH) && (bus_type != BUS_TYPE_MKE)))) { QString name = CDROMName(j); Models::AddEntry(modelType, name, j); if (cdrom[cdromIdx].type == j) @@ -407,6 +414,20 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int) setCDROMType(ui->tableViewCDROM->model(), ui->tableViewCDROM->selectionModel()->currentIndex(), ui->comboBoxCDROMType->currentData().toUInt()); + + int speed = cdrom_get_speed(ui->comboBoxCDROMType->currentData().toUInt()); + if ((speed == -1) && (bus_type != CDROM_BUS_MITSUMI)) { + speed = ui->comboBoxSpeed->currentData().toUInt(); + ui->comboBoxSpeed->setEnabled(bus_type != CDROM_BUS_DISABLED); + } else { + ui->comboBoxSpeed->setEnabled(false); + if (bus_type == CDROM_BUS_MITSUMI) // temp hack + speed = 0; + } + ui->comboBoxSpeed->setCurrentIndex(speed == 0 ? 7 : speed - 1); + setCDROMSpeed(ui->tableViewCDROM->model(), + ui->tableViewCDROM->selectionModel()->currentIndex(), + speed); emit cdromChannelChanged(); } @@ -414,11 +435,10 @@ void SettingsFloppyCDROM::enableCurrentlySelectedChannel() { const auto *item_model = qobject_cast(ui->comboBoxChannel->model()); - const auto index = ui->comboBoxChannel->currentIndex(); - auto *item = item_model->item(index); - if(item) { + const auto index = ui->comboBoxChannel->currentIndex(); + auto *item = item_model->item(index); + if(item) item->setEnabled(true); - } } void @@ -449,9 +469,9 @@ SettingsFloppyCDROM::on_comboBoxCDROMType_activated(int) ui->tableViewCDROM->resizeColumnsToContents(); ui->tableViewCDROM->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - int speed = cdrom_get_speed(type); + int speed = cdrom_get_speed(type); if (speed == -1) { - speed = ui->comboBoxSpeed->currentData().toUInt(); + speed = ui->comboBoxSpeed->currentData().toUInt(); ui->comboBoxSpeed->setEnabled(true); } else ui->comboBoxSpeed->setEnabled(false); diff --git a/src/qt/qt_settingsfloppycdrom.hpp b/src/qt/qt_settingsfloppycdrom.hpp index 0a3424216..063942201 100644 --- a/src/qt/qt_settingsfloppycdrom.hpp +++ b/src/qt/qt_settingsfloppycdrom.hpp @@ -19,17 +19,20 @@ public: signals: void cdromChannelChanged(); + private slots: - void on_comboBoxCDROMType_activated(int index); - void on_comboBoxChannel_activated(int index); - void on_comboBoxBus_activated(int index); - void on_comboBoxSpeed_activated(int index); - void on_comboBoxBus_currentIndexChanged(int index); - void on_comboBoxFloppyType_activated(int index); - void on_checkBoxCheckBPB_stateChanged(int arg1); - void on_checkBoxTurboTimings_stateChanged(int arg1); void onFloppyRowChanged(const QModelIndex ¤t); + void on_comboBoxFloppyType_activated(int index); + void on_checkBoxTurboTimings_stateChanged(int arg1); + void on_checkBoxCheckBPB_stateChanged(int arg1); + void onCDROMRowChanged(const QModelIndex ¤t); + void on_comboBoxBus_activated(int index); + void on_comboBoxBus_currentIndexChanged(int index); + void on_comboBoxChannel_activated(int index); + void on_comboBoxSpeed_activated(int index); + void on_comboBoxCDROMType_activated(int index); + private: Ui::SettingsFloppyCDROM *ui; diff --git a/src/qt/qt_settingsfloppycdrom.ui b/src/qt/qt_settingsfloppycdrom.ui index b9a937d8d..6b1036b5c 100644 --- a/src/qt/qt_settingsfloppycdrom.ui +++ b/src/qt/qt_settingsfloppycdrom.ui @@ -27,7 +27,7 @@ 0 - + Floppy drives: @@ -68,7 +68,7 @@ - + Type: @@ -99,7 +99,7 @@ - + CD-ROM drives: @@ -140,33 +140,12 @@ - + Bus: - - - - Channel: - - - - - - - Speed: - - - - - - - Type: - - - @@ -174,6 +153,13 @@ + + + + Channel: + + + @@ -181,6 +167,13 @@ + + + + Speed: + + + @@ -188,6 +181,13 @@ + + + + Type: + + + @@ -200,6 +200,17 @@ + + tableViewFloppy + comboBoxFloppyType + checkBoxTurboTimings + checkBoxCheckBPB + tableViewCDROM + comboBoxBus + comboBoxChannel + comboBoxSpeed + comboBoxCDROMType + diff --git a/src/qt/qt_settingsharddisks.cpp b/src/qt/qt_settingsharddisks.cpp index 32b677888..6d82f2b77 100644 --- a/src/qt/qt_settingsharddisks.cpp +++ b/src/qt/qt_settingsharddisks.cpp @@ -49,9 +49,8 @@ static void normalize_hd_list() { hard_disk_t ihdd[HDD_NUM]; - int j; + int j = 0; - j = 0; memset(ihdd, 0x00, HDD_NUM * sizeof(hard_disk_t)); for (uint8_t i = 0; i < HDD_NUM; i++) { @@ -75,8 +74,8 @@ static void addRow(QAbstractItemModel *model, hard_disk_t *hd) { const QString userPath = usr_path; - int row = model->rowCount(); + model->insertRow(row); QString busName = Harddrives::BusChannelName(hd->bus_type, hd->channel); @@ -88,11 +87,11 @@ addRow(QAbstractItemModel *model, hard_disk_t *hd) model->setData(model->index(row, ColumnBus), hd->channel, DataBusChannelPrevious); Harddrives::busTrackClass->device_track(1, DEV_HDD, hd->bus_type, hd->channel); QString fileName = hd->fn; - if (fileName.startsWith(userPath, Qt::CaseInsensitive)) { + if (fileName.startsWith(userPath, Qt::CaseInsensitive)) model->setData(model->index(row, ColumnFilename), fileName.mid(userPath.size())); - } else { + else model->setData(model->index(row, ColumnFilename), fileName); - } + model->setData(model->index(row, ColumnFilename), fileName, Qt::UserRole); model->setData(model->index(row, ColumnCylinders), hd->tracks); @@ -120,9 +119,8 @@ SettingsHarddisks::SettingsHarddisks(QWidget *parent) ui->tableView->setModel(model); for (int i = 0; i < HDD_NUM; i++) { - if (hdd[i].bus_type > 0) { + if (hdd[i].bus_type > 0) addRow(model, &hdd[i]); - } } if (model->rowCount() == HDD_NUM) { ui->pushButtonNew->setEnabled(false); @@ -176,9 +174,8 @@ void SettingsHarddisks::reloadBusChannels() { void SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } buschangeinprogress = true; auto idx = ui->tableView->selectionModel()->currentIndex(); @@ -226,9 +223,8 @@ SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) void SettingsHarddisks::on_comboBoxChannel_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } auto idx = ui->tableView->selectionModel()->currentIndex(); if (idx.isValid()) { @@ -250,17 +246,15 @@ SettingsHarddisks::enableCurrentlySelectedChannel() const auto *item_model = qobject_cast(ui->comboBoxChannel->model()); const auto index = ui->comboBoxChannel->currentIndex(); auto *item = item_model->item(index); - if(item) { + if(item) item->setEnabled(true); - } } void SettingsHarddisks::on_comboBoxSpeed_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } auto idx = ui->tableView->selectionModel()->currentIndex(); if (idx.isValid()) { @@ -288,20 +282,19 @@ SettingsHarddisks::onTableRowChanged(const QModelIndex ¤t) 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, busChannel); - if (!match.isEmpty()) { + if (!match.isEmpty()) ui->comboBoxChannel->setCurrentIndex(match.first().row()); - } model = ui->comboBoxSpeed->model(); match = model->match(model->index(0, 0), Qt::UserRole, speed); - if (!match.isEmpty()) { + if (!match.isEmpty()) ui->comboBoxSpeed->setCurrentIndex(match.first().row()); - } + reloadBusChannels(); } @@ -358,11 +351,10 @@ void SettingsHarddisks::on_pushButtonRemove_clicked() { auto idx = ui->tableView->selectionModel()->currentIndex(); - if (!idx.isValid()) { + if (!idx.isValid()) return; - } - auto *model = ui->tableView->model(); + auto *model = ui->tableView->model(); const auto col = idx.siblingAtColumn(ColumnBus); Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannel).toInt()); model->removeRow(idx.row()); diff --git a/src/qt/qt_settingsharddisks.hpp b/src/qt/qt_settingsharddisks.hpp index 4bd287d29..f892a79cd 100644 --- a/src/qt/qt_settingsharddisks.hpp +++ b/src/qt/qt_settingsharddisks.hpp @@ -21,14 +21,13 @@ signals: void driveChannelChanged(); private slots: + void on_comboBoxBus_currentIndexChanged(int index); void on_comboBoxChannel_currentIndexChanged(int index); void on_comboBoxSpeed_currentIndexChanged(int index); -private slots: - void on_pushButtonRemove_clicked(); - void on_pushButtonExisting_clicked(); void on_pushButtonNew_clicked(); - void on_comboBoxBus_currentIndexChanged(int index); + void on_pushButtonExisting_clicked(); + void on_pushButtonRemove_clicked(); void onTableRowChanged(const QModelIndex ¤t); diff --git a/src/qt/qt_settingsharddisks.ui b/src/qt/qt_settingsharddisks.ui index ea69edc5b..f996c76d1 100644 --- a/src/qt/qt_settingsharddisks.ui +++ b/src/qt/qt_settingsharddisks.ui @@ -46,7 +46,7 @@ - + diff --git a/src/qt/qt_settingsinput.cpp b/src/qt/qt_settingsinput.cpp index f3729ab3f..d8cc7c029 100644 --- a/src/qt/qt_settingsinput.cpp +++ b/src/qt/qt_settingsinput.cpp @@ -21,12 +21,14 @@ #include #include +#include #include extern "C" { #include <86box/86box.h> #include <86box/device.h> #include <86box/machine.h> +#include <86box/keyboard.h> #include <86box/mouse.h> #include <86box/gameport.h> #include <86box/ui.h> @@ -38,7 +40,7 @@ extern "C" { #include "qt_keybind.hpp" extern MainWindow *main_window; - + // Temporary working copy of key list accelKey acc_keys_t[NUM_ACCELS]; @@ -48,41 +50,40 @@ SettingsInput::SettingsInput(QWidget *parent) { ui->setupUi(this); - QStringList horizontalHeader; - QStringList verticalHeader; - - horizontalHeader.append(tr("Action")); + QStringList horizontalHeader; + QStringList verticalHeader; + + horizontalHeader.append(tr("Action")); horizontalHeader.append(tr("Keybind")); - QTableWidget *keyTable = ui->tableKeys; - keyTable->setRowCount(10); - keyTable->setColumnCount(3); - keyTable->setColumnHidden(2, true); - keyTable->setColumnWidth(0, 200); - keyTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - QStringList headers; - //headers << "Action" << "Bound key"; - keyTable->setHorizontalHeaderLabels(horizontalHeader); - keyTable->verticalHeader()->setVisible(false); - keyTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - keyTable->setSelectionBehavior(QAbstractItemView::SelectRows); - keyTable->setSelectionMode(QAbstractItemView::SingleSelection); - keyTable->setShowGrid(true); - - // Make a working copy of acc_keys so we can check for dupes later without getting - // confused - for(int x=0;xtableKeys; + keyTable->setRowCount(NUM_ACCELS); + keyTable->setColumnCount(3); + keyTable->setColumnHidden(2, true); + keyTable->setColumnWidth(0, 200); + keyTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + QStringList headers; + //headers << "Action" << "Bound key"; + keyTable->setHorizontalHeaderLabels(horizontalHeader); + keyTable->verticalHeader()->setVisible(false); + keyTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + keyTable->setSelectionBehavior(QAbstractItemView::SelectRows); + keyTable->setSelectionMode(QAbstractItemView::SingleSelection); + keyTable->setShowGrid(true); - refreshInputList(); + // Make a working copy of acc_keys so we can check for dupes later without getting + // confused + for(int x = 0; x < NUM_ACCELS; x++) { + strcpy(acc_keys_t[x].name, acc_keys[x].name); + strcpy(acc_keys_t[x].desc, acc_keys[x].desc); + strcpy(acc_keys_t[x].seq, acc_keys[x].seq); + } + + refreshInputList(); onCurrentMachineChanged(machine); } - SettingsInput::~SettingsInput() { delete ui; @@ -91,37 +92,77 @@ SettingsInput::~SettingsInput() void SettingsInput::save() { + keyboard_type = ui->comboBoxKeyboard->currentData().toInt(); mouse_type = ui->comboBoxMouse->currentData().toInt(); + joystick_type = ui->comboBoxJoystick->currentData().toInt(); - - // Copy accelerators from working set to global set - for(int x=0;xmachineId = machineId; - auto *mouseModel = ui->comboBoxMouse->model(); - auto removeRows = mouseModel->rowCount(); + auto *keyboardModel = ui->comboBoxKeyboard->model(); + auto removeRows = keyboardModel->rowCount(); int selectedRow = 0; + + int c = 0; + int has_int_kbd = !!machine_has_flags(machineId, MACHINE_KEYBOARD); + + for (int i = 0; i < keyboard_get_ndev(); ++i) { + const auto *dev = keyboard_get_device(i); + int ikbd = (i == KEYBOARD_TYPE_INTERNAL); + + int pc5086_filter = (strstr(keyboard_get_internal_name(i), "ps") && + strstr(machine_get_internal_name_ex(machineId), "pc5086")); + + if ((ikbd != has_int_kbd) || !device_is_valid(dev, machineId) || pc5086_filter) + continue; + + QString name = DeviceConfig::DeviceName(dev, keyboard_get_internal_name(i), 0); + int row = keyboardModel->rowCount(); + keyboardModel->insertRow(row); + auto idx = keyboardModel->index(row, 0); + + keyboardModel->setData(idx, name, Qt::DisplayRole); + keyboardModel->setData(idx, i, Qt::UserRole); + + if (i == keyboard_type) + selectedRow = row - removeRows; + + c++; + } + keyboardModel->removeRows(0, removeRows); + ui->comboBoxKeyboard->setCurrentIndex(-1); + ui->comboBoxKeyboard->setCurrentIndex(selectedRow); + + if ((c == 1) || has_int_kbd) + ui->comboBoxKeyboard->setEnabled(false); + else + ui->comboBoxKeyboard->setEnabled(true); + + auto *mouseModel = ui->comboBoxMouse->model(); + removeRows = mouseModel->rowCount(); + + selectedRow = 0; for (int i = 0; i < mouse_get_ndev(); ++i) { const auto *dev = mouse_get_device(i); - if ((i == MOUSE_TYPE_INTERNAL) && (machine_has_flags(machineId, MACHINE_MOUSE) == 0)) { + if ((i == MOUSE_TYPE_INTERNAL) && (machine_has_flags(machineId, MACHINE_MOUSE) == 0)) continue; - } - if (device_is_valid(dev, machineId) == 0) { + if (device_is_valid(dev, machineId) == 0) continue; - } QString name = DeviceConfig::DeviceName(dev, mouse_get_internal_name(i), 0); int row = mouseModel->rowCount(); @@ -131,23 +172,22 @@ SettingsInput::onCurrentMachineChanged(int machineId) mouseModel->setData(idx, name, Qt::DisplayRole); mouseModel->setData(idx, i, Qt::UserRole); - if (i == mouse_type) { + if (i == mouse_type) selectedRow = row - removeRows; - } } mouseModel->removeRows(0, removeRows); + ui->comboBoxMouse->setCurrentIndex(-1); ui->comboBoxMouse->setCurrentIndex(selectedRow); int i = 0; const char *joyName = joystick_get_name(i); auto *joystickModel = ui->comboBoxJoystick->model(); - removeRows = joystickModel->rowCount(); - selectedRow = 0; + removeRows = joystickModel->rowCount(); + selectedRow = 0; while (joyName) { int row = Models::AddEntry(joystickModel, tr(joyName).toUtf8().data(), i); - if (i == joystick_type) { + if (i == joystick_type) selectedRow = row - removeRows; - } ++i; joyName = joystick_get_name(i); @@ -159,100 +199,111 @@ SettingsInput::onCurrentMachineChanged(int machineId) void SettingsInput::refreshInputList() { - - for (int x=0;xtableKeys->setItem(x, 0, new QTableWidgetItem(tr(acc_keys_t[x].desc))); - ui->tableKeys->setItem(x, 1, new QTableWidgetItem(acc_keys_t[x].seq)); - ui->tableKeys->setItem(x, 2, new QTableWidgetItem(acc_keys_t[x].name)); - } + for (int x = 0; x < NUM_ACCELS; x++) { + ui->tableKeys->setItem(x, 0, new QTableWidgetItem(tr(acc_keys_t[x].desc))); + ui->tableKeys->setItem(x, 1, new QTableWidgetItem(QKeySequence(acc_keys_t[x].seq, QKeySequence::PortableText).toString(QKeySequence::NativeText))); + ui->tableKeys->setItem(x, 2, new QTableWidgetItem(acc_keys_t[x].name)); + } } void SettingsInput::on_tableKeys_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn) { - // Enable/disable bind/clear buttons if user clicked valid row - QTableWidgetItem *cell = ui->tableKeys->item(currentRow,1); - if (!cell) - { - ui->pushButtonBind->setEnabled(false); - ui->pushButtonClearBind->setEnabled(false); - } - else - { - ui->pushButtonBind->setEnabled(true); - ui->pushButtonClearBind->setEnabled(true); - } + // Enable/disable bind/clear buttons if user clicked valid row + QTableWidgetItem *cell = ui->tableKeys->item(currentRow,1); + if (!cell) { + ui->pushButtonBind->setEnabled(false); + ui->pushButtonClearBind->setEnabled(false); + } else { + ui->pushButtonBind->setEnabled(true); + ui->pushButtonClearBind->setEnabled(true); + } } void SettingsInput::on_tableKeys_cellDoubleClicked(int row, int col) { - // Edit bind - QTableWidgetItem *cell = ui->tableKeys->item(row,1); - if (!cell) return; - - QKeySequence keyseq = KeyBinder::BindKey(this, cell->text()); - if (keyseq != false) { - // If no change was made, don't change anything. - if (keyseq.toString(QKeySequence::NativeText) == cell->text()) return; - - // Otherwise, check for conflicts. - // Check against the *working* copy - NOT the one in use by the app, - // so we don't test against shortcuts the user already changed. - for(int x=0;xshowMessage(MBX_ANSI & MBX_INFO, "Bind conflict", "This key combo is already in use", false); - return; - } - } - // If we made it here, there were no conflicts. - // Go ahead and apply the bind. - - // Find the correct accelerator key entry - int accKeyID = FindAccelerator(qPrintable(ui->tableKeys->item(row,2)->text())); - if (accKeyID < 0) return; // this should never happen - - // Make the change - cell->setText(keyseq.toString(QKeySequence::NativeText)); - strcpy(acc_keys_t[accKeyID].seq, qPrintable(keyseq.toString(QKeySequence::NativeText))); - - refreshInputList(); - } + // Edit bind + QTableWidgetItem *cell = ui->tableKeys->item(row,1); + if (!cell) + return; + + QKeySequence keyseq = KeyBinder::BindKey(this, cell->text()); + if (keyseq != false) { + // If no change was made, don't change anything. + if (keyseq.toString(QKeySequence::NativeText) == cell->text()) + return; + + // Otherwise, check for conflicts. + // Check against the *working* copy - NOT the one in use by the app, + // so we don't test against shortcuts the user already changed. + for(int x = 0; x < NUM_ACCELS; x++) { + if(QString::fromStdString(acc_keys_t[x].seq) == keyseq.toString(QKeySequence::PortableText)) { + // That key is already in use + QMessageBox::warning(this, tr("Bind conflict"), tr("This key combo is already in use."), QMessageBox::StandardButton::Ok); + return; + } + } + // If we made it here, there were no conflicts. + // Go ahead and apply the bind. + + // Find the correct accelerator key entry + int accKeyID = FindAccelerator(ui->tableKeys->item(row,2)->text().toUtf8().constData()); + if (accKeyID < 0) + return; // this should never happen + + // Make the change + cell->setText(keyseq.toString(QKeySequence::NativeText)); + strcpy(acc_keys_t[accKeyID].seq, keyseq.toString(QKeySequence::PortableText).toUtf8().constData()); + + refreshInputList(); + } } void SettingsInput::on_pushButtonBind_clicked() { - // Edit bind - QTableWidgetItem *cell = ui->tableKeys->currentItem(); - if (!cell) return; - - on_tableKeys_cellDoubleClicked(cell->row(), cell->column()); + // Edit bind + QTableWidgetItem *cell = ui->tableKeys->currentItem(); + if (!cell) + return; + + on_tableKeys_cellDoubleClicked(cell->row(), cell->column()); } void SettingsInput::on_pushButtonClearBind_clicked() { - // Wipe bind - QTableWidgetItem *cell = ui->tableKeys->item(ui->tableKeys->currentRow(), 1); - if (!cell) return; - - cell->setText(""); - // Find the correct accelerator key entry - int accKeyID = FindAccelerator(qPrintable(ui->tableKeys->item(cell->row(),2)->text())); - if (accKeyID < 0) return; // this should never happen - - // Make the change - cell->setText(""); - strcpy(acc_keys_t[accKeyID].seq, ""); + // Wipe bind + QTableWidgetItem *cell = ui->tableKeys->item(ui->tableKeys->currentRow(), 1); + if (!cell) + return; + + cell->setText(""); + // Find the correct accelerator key entry + int accKeyID = FindAccelerator(ui->tableKeys->item(cell->row(),2)->text().toUtf8().constData()); + if (accKeyID < 0) + return; // this should never happen + + // Make the change + cell->setText(""); + strcpy(acc_keys_t[accKeyID].seq, ""); +} + +void +SettingsInput::on_comboBoxKeyboard_currentIndexChanged(int index) +{ + if (index < 0) + return; + int keyboardId = ui->comboBoxKeyboard->currentData().toInt(); + ui->pushButtonConfigureKeyboard->setEnabled(keyboard_has_config(keyboardId) > 0); } void SettingsInput::on_comboBoxMouse_currentIndexChanged(int index) { + if (index < 0) + return; int mouseId = ui->comboBoxMouse->currentData().toInt(); ui->pushButtonConfigureMouse->setEnabled(mouse_has_config(mouseId) > 0); } @@ -263,13 +314,20 @@ SettingsInput::on_comboBoxJoystick_currentIndexChanged(int index) int joystickId = ui->comboBoxJoystick->currentData().toInt(); for (int i = 0; i < MAX_JOYSTICKS; ++i) { auto *btn = findChild(QString("pushButtonJoystick%1").arg(i + 1)); - if (btn == nullptr) { + if (btn == nullptr) continue; - } + btn->setEnabled(joystick_get_max_joysticks(joystickId) > i); } } +void +SettingsInput::on_pushButtonConfigureKeyboard_clicked() +{ + int keyboardId = ui->comboBoxKeyboard->currentData().toInt(); + DeviceConfig::ConfigureDevice(keyboard_get_device(keyboardId)); +} + void SettingsInput::on_pushButtonConfigureMouse_clicked() { @@ -283,9 +341,8 @@ get_axis(JoystickConfiguration &jc, int axis, int joystick_nr) int axis_sel = jc.selectedAxis(axis); int nr_axes = plat_joystick_state[joystick_state[0][joystick_nr].plat_joystick_nr - 1].nr_axes; - if (axis_sel < nr_axes) { + if (axis_sel < nr_axes) return axis_sel; - } axis_sel -= nr_axes; if (axis_sel & 1) diff --git a/src/qt/qt_settingsinput.hpp b/src/qt/qt_settingsinput.hpp index 742421f64..9a7702b4b 100644 --- a/src/qt/qt_settingsinput.hpp +++ b/src/qt/qt_settingsinput.hpp @@ -26,17 +26,23 @@ public slots: void onCurrentMachineChanged(int machineId); private slots: - void on_pushButtonConfigureMouse_clicked(); - void on_comboBoxJoystick_currentIndexChanged(int index); + void on_comboBoxKeyboard_currentIndexChanged(int index); + void on_pushButtonConfigureKeyboard_clicked(); + void on_comboBoxMouse_currentIndexChanged(int index); + void on_pushButtonConfigureMouse_clicked(); + + void on_comboBoxJoystick_currentIndexChanged(int index); void on_pushButtonJoystick1_clicked(); void on_pushButtonJoystick2_clicked(); void on_pushButtonJoystick3_clicked(); void on_pushButtonJoystick4_clicked(); + void on_tableKeys_cellDoubleClicked(int row, int col); void on_tableKeys_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn); - void on_pushButtonBind_clicked(); + void on_pushButtonClearBind_clicked(); + void on_pushButtonBind_clicked(); private: Ui::SettingsInput *ui; diff --git a/src/qt/qt_settingsinput.ui b/src/qt/qt_settingsinput.ui index b7074eeaa..8436c3a9d 100644 --- a/src/qt/qt_settingsinput.ui +++ b/src/qt/qt_settingsinput.ui @@ -23,7 +23,47 @@ 0 + + + + Keyboard: + + + + + + + 0 + 0 + + + + 30 + + + + + + + + 0 + 0 + + + + Configure + + + + + + + Mouse: + + + + @@ -36,76 +76,7 @@ - - - - Joystick 4... - - - - - - - Joystick 3... - - - - - - - false - - - Bind - - - - - - - Joystick 1... - - - - - - - 30 - - - - - - - Mouse: - - - - - - - false - - - Clear binding - - - - - - - Joystick: - - - - - - - Joystick 2... - - - - + @@ -118,17 +89,59 @@ + + + + Joystick: + + + + + + + 30 + + + - + + + Joystick 1... + + + + + + + Joystick 2... + + + + + + + Joystick 3... + + + + + + + Joystick 4... + + + + + Key Bindings: - + - QAbstractItemView::EditTrigger::NoEditTriggers + QAbstractItemView::NoEditTriggers false @@ -140,7 +153,27 @@ true - QAbstractItemView::SelectionBehavior::SelectRows + QAbstractItemView::SelectRows + + + + + + + false + + + Clear binding + + + + + + + false + + + Bind diff --git a/src/qt/qt_settingsmachine.cpp b/src/qt/qt_settingsmachine.cpp index 8548ca8cc..0063ac727 100644 --- a/src/qt/qt_settingsmachine.cpp +++ b/src/qt/qt_settingsmachine.cpp @@ -117,6 +117,9 @@ SettingsMachine::SettingsMachine(QWidget *parent) ui->comboBoxMachineType->setCurrentIndex(-1); ui->comboBoxMachineType->setCurrentIndex(selectedMachineType); + ui->radioButtonLargerFrames->setChecked(force_10ms); + ui->radioButtonSmallerFrames->setChecked(!force_10ms); + #ifndef USE_DYNAREC ui->checkBoxDynamicRecompiler->setEnabled(false); ui->checkBoxDynamicRecompiler->setVisible(false); @@ -137,6 +140,7 @@ SettingsMachine::save() fpu_type = ui->comboBoxFPU->currentData().toInt(); cpu_use_dynarec = ui->checkBoxDynamicRecompiler->isChecked() ? 1 : 0; fpu_softfloat = ui->checkBoxFPUSoftfloat->isChecked() ? 1 : 0; + force_10ms = ui->radioButtonLargerFrames->isChecked() ? 1 : 0; int64_t temp_mem_size; if (machine_get_ram_granularity(machine) < 1024) @@ -358,4 +362,16 @@ void SettingsMachine::on_checkBoxFPUSoftfloat_stateChanged(int state) { ui->softFloatWarningIcon->setVisible(false); ui->softFloatWarningText->setVisible(false); } -} \ No newline at end of file +} + +void SettingsMachine::on_radioButtonSmallerFrames_clicked() +{ + ui->radioButtonLargerFrames->setChecked(false); +} + + +void SettingsMachine::on_radioButtonLargerFrames_clicked() +{ + ui->radioButtonSmallerFrames->setChecked(false); +} + diff --git a/src/qt/qt_settingsmachine.hpp b/src/qt/qt_settingsmachine.hpp index 7e89d7fa4..36ece7f18 100644 --- a/src/qt/qt_settingsmachine.hpp +++ b/src/qt/qt_settingsmachine.hpp @@ -18,25 +18,20 @@ public: signals: void currentMachineChanged(int machineId); + private slots: void on_pushButtonConfigure_clicked(); - -private slots: void on_comboBoxFPU_currentIndexChanged(int index); - -private slots: void on_comboBoxSpeed_currentIndexChanged(int index); - -private slots: void on_comboBoxCPU_currentIndexChanged(int index); - -private slots: void on_comboBoxMachine_currentIndexChanged(int index); - -private slots: void on_comboBoxMachineType_currentIndexChanged(int index); void on_checkBoxFPUSoftfloat_stateChanged(int state); + void on_radioButtonSmallerFrames_clicked(); + + void on_radioButtonLargerFrames_clicked(); + private: Ui::SettingsMachine *ui; }; diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui index 0c9c2708e..7ed70a5cf 100644 --- a/src/qt/qt_settingsmachine.ui +++ b/src/qt/qt_settingsmachine.ui @@ -41,6 +41,13 @@ 0 + + + + Machine type: + + + @@ -48,42 +55,49 @@ - - + + - FPU: + Machine: - - - - Memory: - - - - - - - 30 - - - - - - - - 0 - 0 - - - - - - - - Machine type: - + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 30 + + + + + + + + 0 + 0 + + + + Configure + + + + @@ -147,6 +161,20 @@ + + + + FPU: + + + + + + + 30 + + + @@ -154,51 +182,6 @@ - - - - Machine: - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 30 - - - - - - - - 0 - 0 - - - - Configure - - - - - - @@ -250,6 +233,23 @@ + + + + Memory: + + + + + + + + 0 + 0 + + + + @@ -315,40 +315,102 @@ - - - - 0 - 0 - - - - Time synchronization - - - - - - Disabled - - - - - - - Enabled (local time) - - - - - - - Enabled (UTC) - - - - - + + + + + + 0 + 0 + + + + CPU frame size + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + Larger frames (less smooth) + + + + + + + Smaller frames (smoother) + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Time synchronization + + + + + + Disabled + + + + + + + Enabled (local time) + + + + + + + Enabled (UTC) + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + @@ -365,6 +427,24 @@ + + comboBoxMachineType + comboBoxMachine + pushButtonConfigure + comboBoxCPU + comboBoxSpeed + comboBoxFPU + comboBoxWaitStates + comboBoxPitMode + spinBoxRAM + checkBoxDynamicRecompiler + checkBoxFPUSoftfloat + radioButtonDisabled + radioButtonLocalTime + radioButtonUTC + radioButtonLargerFrames + radioButtonSmallerFrames + diff --git a/src/qt/qt_settingsnetwork.cpp b/src/qt/qt_settingsnetwork.cpp index 1ea48ee6b..1028262bc 100644 --- a/src/qt/qt_settingsnetwork.cpp +++ b/src/qt/qt_settingsnetwork.cpp @@ -36,31 +36,70 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) auto *nic_cbox = findChild(QString("comboBoxNIC%1").arg(i + 1)); auto *net_type_cbox = findChild(QString("comboBoxNet%1").arg(i + 1)); - auto *intf_label = findChild(QString("interfaceLabel%1").arg(i + 1)); - auto *intf_cbox = findChild(QString("comboBoxIntf%1").arg(i + 1)); + auto *intf_label = findChild(QString("labelIntf%1").arg(i + 1)); + auto *intf_cbox = findChild(QString("comboBoxIntf%1").arg(i + 1)); auto *conf_btn = findChild(QString("pushButtonConf%1").arg(i + 1)); // auto *net_type_conf_btn = findChild(QString("pushButtonNetTypeConf%1").arg(i + 1)); - auto *vde_socket_label = findChild(QString("socketVDELabel%1").arg(i + 1)); - auto *socket_line = findChild(QString("socketVDENIC%1").arg(i + 1)); + auto *vde_socket_label = findChild(QString("labelSocketVDENIC%1").arg(i + 1)); + auto *socket_line = findChild(QString("socketVDENIC%1").arg(i + 1)); - auto *option_list_label = findChild(QString("optionListLabel%1").arg(i + 1)); - auto *option_list_line = findChild(QString("optionListLine%1").arg(i + 1)); + auto *bridge_label = findChild(QString("labelBridgeTAPNIC%1").arg(i + 1)); + auto *bridge_line = findChild(QString("bridgeTAPNIC%1").arg(i + 1)); + auto *option_list_label = findChild(QString("labelOptionList%1").arg(i + 1)); + auto *option_list_line = findChild(QString("lineOptionList%1").arg(i + 1)); + + // Switch group + auto *switch_group_label = findChild(QString("labelSwitch%1").arg(i + 1)); +// auto *switch_group_hlayout = findChild(QString("HLayoutSwitch%1").arg(i + 1)); +// auto *switch_group_hspacer = findChild(QString("horizontalSpacerSwitch%1").arg(i + 1)); + auto *switch_group_value = findChild(QString("spinnerSwitch%1").arg(i + 1)); + switch_group_value->setMinimum(1); + switch_group_value->setMaximum(10); + + // Promiscuous option + auto *promisc_label = findChild(QString("labelPromisc%1").arg(i + 1)); + auto *promisc_value = findChild(QString("boxPromisc%1").arg(i + 1)); + + // Remote switch hostname + auto *hostname_label = findChild(QString("labelHostname%1").arg(i + 1)); + auto *hostname_value = findChild(QString("hostnameSwitch%1").arg(i + 1)); + + bridge_line->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_TAP); intf_cbox->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_PCAP); conf_btn->setEnabled(network_card_has_config(nic_cbox->currentData().toInt())); // net_type_conf_btn->setEnabled(network_type_has_config(netType)); + // NEW STUFF + // Make all options invisible by default + + // Switch group + switch_group_label->setVisible(false); + switch_group_value->setVisible(false); +// switch_group_hspacer->setVisible(false); + + // Promiscuous options + promisc_label->setVisible(false); + promisc_value->setVisible(false); + + // Hostname + hostname_label->setVisible(false); + hostname_value->setVisible(false); + // Option list label and line option_list_label->setVisible(false); option_list_line->setVisible(false); - // VDE vde_socket_label->setVisible(false); socket_line->setVisible(false); + // TAP + bridge_label->setVisible(false); + bridge_line->setVisible(false); + // PCAP intf_cbox->setVisible(false); intf_label->setVisible(false); @@ -69,22 +108,72 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) if(nic_cbox->currentData().toInt() != 0) { // Then only enable as needed based on network type switch (net_type_cbox->currentData().toInt()) { +#ifdef HAS_VDE case NET_TYPE_VDE: - // option_list_label->setText("VDE Options"); + // option_list_label->setText("VDE Options"); option_list_label->setVisible(true); option_list_line->setVisible(true); vde_socket_label->setVisible(true); socket_line->setVisible(true); break; +#endif + case NET_TYPE_PCAP: - // option_list_label->setText("PCAP Options"); + // option_list_label->setText("PCAP Options"); option_list_label->setVisible(true); option_list_line->setVisible(true); intf_cbox->setVisible(true); intf_label->setVisible(true); break; + +#if defined(__unix__) || defined(__APPLE__) + case NET_TYPE_TAP: + // option_list_label->setText("TAP Options"); + option_list_label->setVisible(true); + option_list_line->setVisible(true); + + bridge_label->setVisible(true); + bridge_line->setVisible(true); + break; +#endif + +#ifdef USE_NETSWITCH + case NET_TYPE_NMSWITCH: +// option_list_label->setText("Local Switch Options"); + option_list_label->setVisible(true); + option_list_line->setVisible(true); + + // Switch group + switch_group_label->setVisible(true); + switch_group_value->setVisible(true); +// switch_group_hspacer->setVisible(false); + + // Promiscuous options + promisc_label->setVisible(true); + promisc_value->setVisible(true); + break; + + case NET_TYPE_NRSWITCH: +// option_list_label->setText("Remote Switch Options"); + option_list_label->setVisible(true); + option_list_line->setVisible(true); + + // Switch group + switch_group_label->setVisible(true); + switch_group_value->setVisible(true); +// switch_group_hspacer->setVisible(false); + + // Hostname + hostname_label->setVisible(true); + hostname_value->setVisible(true); + break; +#endif /* USE_NETSWITCH */ + + case NET_TYPE_SLIRP: + default: + break; } } } @@ -118,17 +207,42 @@ SettingsNetwork::save() { for (int i = 0; i < NET_CARD_MAX; ++i) { auto *cbox = findChild(QString("comboBoxNIC%1").arg(i + 1)); +#ifdef HAS_VDE auto *socket_line = findChild(QString("socketVDENIC%1").arg(i + 1)); +#endif +#if defined(__unix__) || defined(__APPLE__) + auto *bridge_line = findChild(QString("bridgeTAPNIC%1").arg(i + 1)); +#endif net_cards_conf[i].device_num = cbox->currentData().toInt(); cbox = findChild(QString("comboBoxNet%1").arg(i + 1)); net_cards_conf[i].net_type = cbox->currentData().toInt(); cbox = findChild(QString("comboBoxIntf%1").arg(i + 1)); +#ifdef USE_NETSWITCH + auto *hostname_value = findChild(QString("hostnameSwitch%1").arg(i + 1)); + auto *promisc_value = findChild(QString("boxPromisc%1").arg(i + 1)); + auto *switch_group_value = findChild(QString("spinnerSwitch%1").arg(i + 1)); +#endif /* USE_NETSWITCH */ memset(net_cards_conf[i].host_dev_name, '\0', sizeof(net_cards_conf[i].host_dev_name)); - if (net_cards_conf[i].net_type == NET_TYPE_PCAP) { + if (net_cards_conf[i].net_type == NET_TYPE_PCAP) strncpy(net_cards_conf[i].host_dev_name, network_devs[cbox->currentData().toInt()].device, sizeof(net_cards_conf[i].host_dev_name) - 1); - } else if (net_cards_conf[i].net_type == NET_TYPE_VDE) { +#ifdef HAS_VDE + else if (net_cards_conf[i].net_type == NET_TYPE_VDE) strncpy(net_cards_conf[i].host_dev_name, socket_line->text().toUtf8().constData(), sizeof(net_cards_conf[i].host_dev_name)); +#endif +#if defined(__unix__) || defined(__APPLE__) + else if (net_cards_conf[i].net_type == NET_TYPE_TAP) + strncpy(net_cards_conf[i].host_dev_name, bridge_line->text().toUtf8().constData(), sizeof(net_cards_conf[i].host_dev_name)); +#endif +#ifdef USE_NETSWITCH + else if (net_cards_conf[i].net_type == NET_TYPE_NRSWITCH) { + memset(net_cards_conf[i].nrs_hostname, '\0', sizeof(net_cards_conf[i].nrs_hostname)); + strncpy(net_cards_conf[i].nrs_hostname, hostname_value->text().toUtf8().constData(), sizeof(net_cards_conf[i].nrs_hostname) - 1); + net_cards_conf[i].switch_group = switch_group_value->value() - 1; + } else if (net_cards_conf[i].net_type == NET_TYPE_NMSWITCH) { + net_cards_conf[i].promisc_mode = promisc_value->isChecked(); + net_cards_conf[i].switch_group = switch_group_value->value() - 1; } +#endif /* USE_NETSWITCH */ } } @@ -141,7 +255,7 @@ SettingsNetwork::onCurrentMachineChanged(int machineId) int selectedRow = 0; // Network Card - QComboBox * cbox_[NET_CARD_MAX] = { 0 }; + QComboBox *cbox_[NET_CARD_MAX] = { 0 }; QAbstractItemModel *models[NET_CARD_MAX] = { 0 }; int removeRows_[NET_CARD_MAX] = { 0 }; int selectedRows[NET_CARD_MAX] = { 0 }; @@ -192,9 +306,22 @@ SettingsNetwork::onCurrentMachineChanged(int machineId) if (network_ndev > 1) Models::AddEntry(model, "PCap", NET_TYPE_PCAP); +#ifdef HAS_VDE if (network_devmap.has_vde) Models::AddEntry(model, "VDE", NET_TYPE_VDE); +#endif +#if defined(__unix__) || defined(__APPLE__) + Models::AddEntry(model, "TAP", NET_TYPE_TAP); +#endif + +#ifdef USE_NETSWITCH + Models::AddEntry(model, "Local Switch", NET_TYPE_NMSWITCH); +#ifdef ENABLE_NET_NRSWITCH + Models::AddEntry(model, "Remote Switch", NET_TYPE_NRSWITCH); +#endif /* ENABLE_NET_NRSWITCH */ +#endif /* USE_NETSWITCH */ + model->removeRows(0, removeRows); cbox->setCurrentIndex(cbox->findData(net_cards_conf[i].net_type)); @@ -213,12 +340,34 @@ SettingsNetwork::onCurrentMachineChanged(int machineId) } model->removeRows(0, removeRows); cbox->setCurrentIndex(selectedRow); - } + } if (net_cards_conf[i].net_type == NET_TYPE_VDE) { +#ifdef HAS_VDE QString currentVdeSocket = net_cards_conf[i].host_dev_name; auto editline = findChild(QString("socketVDENIC%1").arg(i+1)); editline->setText(currentVdeSocket); +#else + ; +#endif +#if defined(__unix__) || defined(__APPLE__) + } else if (net_cards_conf[i].net_type == NET_TYPE_TAP) { + QString currentTapDevice = net_cards_conf[i].host_dev_name; + auto editline = findChild(QString("bridgeTAPNIC%1").arg(i+1)); + editline->setText(currentTapDevice); +#endif +#ifdef USE_NETSWITCH + } else if (net_cards_conf[i].net_type == NET_TYPE_NMSWITCH) { + auto *promisc_value = findChild(QString("boxPromisc%1").arg(i + 1)); + promisc_value->setCheckState(net_cards_conf[i].promisc_mode == 1 ? Qt::CheckState::Checked : Qt::CheckState::Unchecked); + auto *switch_group_value = findChild(QString("switchSpinner%1").arg(i + 1)); + switch_group_value->setValue(net_cards_conf[i].switch_group + 1); + } else if (net_cards_conf[i].net_type == NET_TYPE_NRSWITCH) { + auto *hostname_value = findChild(QString("switchHostname%1").arg(i + 1)); + hostname_value->setText(net_cards_conf[i].nrs_hostname); + auto *switch_group_value = findChild(QString("switchSpinner%1").arg(i + 1)); + switch_group_value->setValue(net_cards_conf[i].switch_group + 1); +#endif /* USE_NETSWITCH */ } } } @@ -226,9 +375,8 @@ SettingsNetwork::onCurrentMachineChanged(int machineId) void SettingsNetwork::on_comboIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } enableElements(ui); } @@ -236,8 +384,8 @@ SettingsNetwork::on_comboIndexChanged(int index) void SettingsNetwork::on_pushButtonConf1_clicked() { - int netCard = ui->comboBoxNIC1->currentData().toInt(); - auto *device = network_card_getdevice(netCard); + 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); @@ -246,23 +394,23 @@ SettingsNetwork::on_pushButtonConf1_clicked() void SettingsNetwork::on_pushButtonConf2_clicked() { - int netCard = ui->comboBoxNIC2->currentData().toInt(); - auto *device = network_card_getdevice(netCard); + int netCard = ui->comboBoxNIC2->currentData().toInt(); + auto *device = network_card_getdevice(netCard); DeviceConfig::ConfigureDevice(device, 2); } void SettingsNetwork::on_pushButtonConf3_clicked() { - int netCard = ui->comboBoxNIC3->currentData().toInt(); - auto *device = network_card_getdevice(netCard); + int netCard = ui->comboBoxNIC3->currentData().toInt(); + auto *device = network_card_getdevice(netCard); DeviceConfig::ConfigureDevice(device, 3); } void SettingsNetwork::on_pushButtonConf4_clicked() { - int netCard = ui->comboBoxNIC4->currentData().toInt(); - auto *device = network_card_getdevice(netCard); + int netCard = ui->comboBoxNIC4->currentData().toInt(); + auto *device = network_card_getdevice(netCard); DeviceConfig::ConfigureDevice(device, 4); } diff --git a/src/qt/qt_settingsnetwork.ui b/src/qt/qt_settingsnetwork.ui index 8fb048f71..767b4244d 100644 --- a/src/qt/qt_settingsnetwork.ui +++ b/src/qt/qt_settingsnetwork.ui @@ -27,15 +27,28 @@ 0 - + 0 - + Network Card #1 - + + + + + + 0 + 0 + + + + Mode: + + + @@ -50,7 +63,7 @@ - + 0 @@ -62,79 +75,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - 0 - 0 - - - - Mode: - - - - - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - Configure - - - - - - - Options - - - - - - - - 0 - 0 - - - - Interface: - - - - - - - VDE Socket: - - - @@ -151,10 +91,43 @@ - - - - 127 + + + + + 0 + 0 + + + + Configure + + + + + + + Options + + + + + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + Interface: @@ -168,15 +141,98 @@ - - - - - Network Card #2 - - - - + + + + VDE Socket: + + + + + + + 127 + + + + + + + TAP Bridge Device + + + + + + + 127 + + + + + + + Switch: + + + + + + + + + 1 + + + 10 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Hub Mode + + + + + + + + + + + + + + Hostname: + + + + + + + 128 + + + + + Qt::Vertical @@ -188,28 +244,15 @@ - - - - - 0 - 0 - - - - Interface: - - - - - - - Options - - - + + + + + Network Card #2 + + - + 0 @@ -234,22 +277,8 @@ - - - - VDE Socket: - - - - - - - Qt::Horizontal - - - - + 0 @@ -261,6 +290,22 @@ + + + + + 0 + 0 + + + + QComboBox::AdjustToContents + + + 30 + + + @@ -274,25 +319,33 @@ - - - - 30 + + + + Options + + + + + + Qt::Horizontal + + + + + - + 0 0 - - QComboBox::AdjustToContents + + Interface: - - - @@ -303,13 +356,129 @@ + + + + VDE Socket: + + + + + + + 127 + + + + + + + TAP Bridge Device + + + + + + + 127 + + + + + + + Switch: + + + + + + + + + 1 + + + 10 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Hub Mode + + + + + + + + + + + + + + Hostname: + + + + + + + 128 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + - + Network Card #3 - + + + + + + 0 + 0 + + + + Mode: + + + @@ -323,17 +492,16 @@ - - - - VDE Socket: + + + + + 0 + 0 + - - - - - Options + Adapter: @@ -353,39 +521,6 @@ - - - - - 0 - 0 - - - - Interface: - - - - - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - Mode: - - - @@ -399,8 +534,22 @@ - - + + + + Options + + + + + + + Qt::Horizontal + + + + + 0 @@ -408,13 +557,10 @@ - Adapter: + Interface: - - - @@ -425,8 +571,98 @@ - - + + + + VDE Socket: + + + + + + + 127 + + + + + + + TAP Bridge Device + + + + + + + 127 + + + + + + + Switch: + + + + + + + + + 1 + + + 10 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Hub Mode + + + + + + + + + + + + + + Hostname: + + + + + + + 128 + + + + + Qt::Vertical @@ -440,20 +676,13 @@ - + Network Card #4 - - - - - Options - - - + - + 0 @@ -465,28 +694,21 @@ - - - - Qt::Vertical + + + + 30 - - - 20 - 40 - - - - - - - - VDE Socket: + + + 0 + 0 + - + 0 @@ -498,26 +720,6 @@ - - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - Interface: - - - @@ -534,19 +736,6 @@ - - - - 30 - - - - 0 - 0 - - - - @@ -560,8 +749,32 @@ - - + + + + Options + + + + + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + Interface: + + @@ -573,6 +786,109 @@ + + + + VDE Socket: + + + + + + + 127 + + + + + + + TAP Bridge Device + + + + + + + 127 + + + + + + + Switch: + + + + + + + + + 1 + + + 10 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Hub Mode + + + + + + + + + + + + + + Hostname: + + + + + + + 128 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp index e1920bf47..0ecdc30d3 100644 --- a/src/qt/qt_settingsotherperipherals.cpp +++ b/src/qt/qt_settingsotherperipherals.cpp @@ -11,8 +11,10 @@ * * * Authors: Joakim L. Gilje + * Jasmine Iwanek * * Copyright 2021 Joakim L. Gilje + * Copyright 2025 Jasmine Iwanek */ #include "qt_settingsotherperipherals.hpp" #include "ui_qt_settingsotherperipherals.h" @@ -22,6 +24,7 @@ extern "C" { #include <86box/device.h> #include <86box/machine.h> #include <86box/isamem.h> +#include <86box/isarom.h> #include <86box/isartc.h> #include <86box/unittester.h> #include <86box/novell_cardkey.h> @@ -44,84 +47,131 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) this->machineId = machineId; bool machineHasIsa = (machine_has_bus(machineId, MACHINE_BUS_ISA) > 0); + + ui->pushButtonConfigureRTC->setEnabled(machineHasIsa); + ui->comboBoxRTC->setEnabled(machineHasIsa); + ui->checkBoxISABugger->setEnabled(machineHasIsa); + ui->pushButtonConfigureUT->setEnabled(unittester_enabled > 0); + ui->checkBoxKeyCard->setEnabled(machineHasIsa); + ui->pushButtonConfigureKeyCard->setEnabled(novell_keycard_enabled > 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->checkBoxKeyCard->setChecked((machineHasIsa && (novell_keycard_enabled > 0)) ? true : false); - ui->checkBoxISABugger->setEnabled(machineHasIsa); - ui->checkBoxKeyCard->setEnabled(machineHasIsa); - ui->pushButtonConfigureKeyCard->setEnabled(novell_keycard_enabled > 0); - ui->pushButtonConfigureUT->setEnabled(unittester_enabled > 0); - ui->comboBoxRTC->setEnabled(machineHasIsa); - ui->pushButtonConfigureRTC->setEnabled(machineHasIsa); - ui->comboBoxCard1->clear(); - ui->comboBoxCard2->clear(); - ui->comboBoxCard3->clear(); - ui->comboBoxCard4->clear(); ui->comboBoxRTC->clear(); - auto *model = ui->comboBoxRTC->model(); - int d = 0; + for (uint8_t i = 0; i < ISAMEM_MAX; ++i) + if (auto *cb = findChild(QString("comboBoxIsaMemCard%1").arg(i + 1))) + cb->clear(); + + for (uint8_t i = 0; i < ISAROM_MAX; ++i) + if (auto *cb = findChild(QString("comboBoxIsaRomCard%1").arg(i + 1))) + cb->clear(); + + int c = 0; int selectedRow = 0; + + // ISA RTC Cards + auto *model = ui->comboBoxRTC->model(); while (true) { - QString name = DeviceConfig::DeviceName(isartc_get_device(d), isartc_get_internal_name(d), 0); - if (name.isEmpty()) { + const QString name = DeviceConfig::DeviceName(isartc_get_device(c), isartc_get_internal_name(c), 0); + if (name.isEmpty()) break; - } - if (!device_is_valid(isartc_get_device(d), machineId)) { + if (!device_is_valid(isartc_get_device(c), machineId)) break; - } - int row = Models::AddEntry(model, name, d); - if (d == isartc_type) { + int row = Models::AddEntry(model, name, c); + if (c == isartc_type) selectedRow = row; - } - ++d; + + ++c; } ui->comboBoxRTC->setCurrentIndex(selectedRow); ui->pushButtonConfigureRTC->setEnabled((isartc_type != 0) && isartc_has_config(isartc_type) && machineHasIsa); - // ISA Memory Expansion Card - QComboBox * cbox[ISAMEM_MAX] = { 0 }; - QAbstractItemModel *models[ISAMEM_MAX] = { 0 }; - int removeRows_[ISAMEM_MAX] = { 0 }; - int selectedRows[ISAMEM_MAX] = { 0 }; + // ISA Memory Expansion Cards + QComboBox *isamem_cbox[ISAMEM_MAX] = { 0 }; + QAbstractItemModel *isamem_models[ISAMEM_MAX] = { 0 }; + int isamem_removeRows_[ISAMEM_MAX] = { 0 }; + int isamem_selectedRows[ISAMEM_MAX] = { 0 }; - for (uint8_t c = 0; c < ISAMEM_MAX; ++c) { - cbox[c] = findChild(QString("comboBoxCard%1").arg(c + 1)); - models[c] = cbox[c]->model(); - removeRows_[c] = models[c]->rowCount(); + for (uint8_t i = 0; i < ISAMEM_MAX; ++i) { + isamem_cbox[i] = findChild(QString("comboBoxIsaMemCard%1").arg(i + 1)); + isamem_models[i] = isamem_cbox[i]->model(); + isamem_removeRows_[i] = isamem_models[i]->rowCount(); } - d = 0; + c = 0; while (true) { - const QString name = DeviceConfig::DeviceName(isamem_get_device(d), - isamem_get_internal_name(d), 0); + const QString name = DeviceConfig::DeviceName(isamem_get_device(c), + isamem_get_internal_name(c), 0); if (name.isEmpty()) break; - if (device_is_valid(isamem_get_device(d), machineId)) { - for (uint8_t c = 0; c < ISAMEM_MAX; ++c) { - int row = Models::AddEntry(models[c], name, d); + if (device_is_valid(isamem_get_device(c), machineId)) { + for (uint8_t i = 0; i < ISAMEM_MAX; ++i) { + int row = Models::AddEntry(isamem_models[i], name, c); - if (d == isamem_type[c]) - selectedRows[c] = row - removeRows_[c]; + if (c == isamem_type[i]) + isamem_selectedRows[i] = row - isamem_removeRows_[i]; } } - d++; + c++; } - for (uint8_t c = 0; c < ISAMEM_MAX; ++c) { - models[c]->removeRows(0, removeRows_[c]); - cbox[c]->setEnabled(models[c]->rowCount() > 1); - cbox[c]->setCurrentIndex(-1); - cbox[c]->setCurrentIndex(selectedRows[c]); - findChild(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled((isamem_type[c] != 0) && - isamem_has_config(isamem_type[c]) && machineHasIsa); + for (uint8_t i = 0; i < ISAMEM_MAX; ++i) { + isamem_models[i]->removeRows(0, isamem_removeRows_[i]); + isamem_cbox[i]->setEnabled(isamem_models[i]->rowCount() > 1); + isamem_cbox[i]->setCurrentIndex(-1); + isamem_cbox[i]->setCurrentIndex(isamem_selectedRows[i]); + findChild(QString("pushButtonConfigureIsaMemCard%1").arg(i + 1))->setEnabled((isamem_type[i] != 0) && + isamem_has_config(isamem_type[i]) && machineHasIsa); + } + + // ISA ROM Expansion Cards + QComboBox *isarom_cbox[ISAROM_MAX] = { 0 }; + QAbstractItemModel *isarom_models[ISAROM_MAX] = { 0 }; + int isarom_removeRows_[ISAROM_MAX] = { 0 }; + int isarom_selectedRows[ISAROM_MAX] = { 0 }; + + for (uint8_t i = 0; i < ISAROM_MAX; ++i) { + isarom_cbox[i] = findChild(QString("comboBoxIsaRomCard%1").arg(i + 1)); + isarom_models[i] = isarom_cbox[i]->model(); + isarom_removeRows_[i] = isarom_models[i]->rowCount(); + } + + c = 0; + while (true) { + const QString name = DeviceConfig::DeviceName(isarom_get_device(c), + isarom_get_internal_name(c), 0); + + if (name.isEmpty()) + break; + + if (device_is_valid(isarom_get_device(c), machineId)) { + for (uint8_t i = 0; i < ISAROM_MAX; ++i) { + int row = Models::AddEntry(isarom_models[i], name, c); + + if (c == isarom_type[i]) + isarom_selectedRows[i] = row - isarom_removeRows_[i]; + } + } + + c++; + } + + for (uint8_t i = 0; i < ISAROM_MAX; ++i) { + isarom_models[i]->removeRows(0, isarom_removeRows_[i]); + isarom_cbox[i]->setEnabled(isarom_models[i]->rowCount() > 1); + isarom_cbox[i]->setCurrentIndex(-1); + isarom_cbox[i]->setCurrentIndex(isarom_selectedRows[i]); + findChild(QString("pushButtonConfigureIsaRomCard%1").arg(i + 1))->setEnabled((isarom_type[i] != 0) && + isarom_has_config(isarom_type[i]) && machineHasIsa); } } @@ -134,25 +184,31 @@ void SettingsOtherPeripherals::save() { /* Other peripherals category */ + 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; novell_keycard_enabled = ui->checkBoxKeyCard->isChecked() ? 1 : 0; - isartc_type = ui->comboBoxRTC->currentData().toInt(); /* ISA memory boards. */ for (int i = 0; i < ISAMEM_MAX; i++) { - auto *cbox = findChild(QString("comboBoxCard%1").arg(i + 1)); + auto *cbox = findChild(QString("comboBoxIsaMemCard%1").arg(i + 1)); isamem_type[i] = cbox->currentData().toInt(); } + + /* ISA ROM boards. */ + for (int i = 0; i < ISAROM_MAX; i++) { + auto *cbox = findChild(QString("comboBoxIsaRomCard%1").arg(i + 1)); + isarom_type[i] = cbox->currentData().toInt(); + } } void SettingsOtherPeripherals::on_comboBoxRTC_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } + ui->pushButtonConfigureRTC->setEnabled((index != 0) && isartc_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); } @@ -163,63 +219,123 @@ SettingsOtherPeripherals::on_pushButtonConfigureRTC_clicked() } void -SettingsOtherPeripherals::on_comboBoxCard1_currentIndexChanged(int index) +SettingsOtherPeripherals::on_comboBoxIsaMemCard1_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } - ui->pushButtonConfigureCard1->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); + + ui->pushButtonConfigureIsaMemCard1->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); } void -SettingsOtherPeripherals::on_pushButtonConfigureCard1_clicked() +SettingsOtherPeripherals::on_pushButtonConfigureIsaMemCard1_clicked() { - DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard1->currentData().toInt()), 1); + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxIsaMemCard1->currentData().toInt()), 1); } void -SettingsOtherPeripherals::on_comboBoxCard2_currentIndexChanged(int index) +SettingsOtherPeripherals::on_comboBoxIsaMemCard2_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } - ui->pushButtonConfigureCard2->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); + + ui->pushButtonConfigureIsaMemCard2->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); } void -SettingsOtherPeripherals::on_pushButtonConfigureCard2_clicked() +SettingsOtherPeripherals::on_pushButtonConfigureIsaMemCard2_clicked() { - DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard2->currentData().toInt()), 2); + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxIsaMemCard2->currentData().toInt()), 2); } void -SettingsOtherPeripherals::on_comboBoxCard3_currentIndexChanged(int index) +SettingsOtherPeripherals::on_comboBoxIsaMemCard3_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } - ui->pushButtonConfigureCard3->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); + + ui->pushButtonConfigureIsaMemCard3->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); } void -SettingsOtherPeripherals::on_pushButtonConfigureCard3_clicked() +SettingsOtherPeripherals::on_pushButtonConfigureIsaMemCard3_clicked() { - DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard3->currentData().toInt()), 3); + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxIsaMemCard3->currentData().toInt()), 3); } void -SettingsOtherPeripherals::on_comboBoxCard4_currentIndexChanged(int index) +SettingsOtherPeripherals::on_comboBoxIsaMemCard4_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } - ui->pushButtonConfigureCard4->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); + + ui->pushButtonConfigureIsaMemCard4->setEnabled((index != 0) && isamem_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); } void -SettingsOtherPeripherals::on_pushButtonConfigureCard4_clicked() +SettingsOtherPeripherals::on_pushButtonConfigureIsaMemCard4_clicked() { - DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard4->currentData().toInt()), 4); + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxIsaMemCard4->currentData().toInt()), 4); +} + +void +SettingsOtherPeripherals::on_comboBoxIsaRomCard1_currentIndexChanged(int index) +{ + if (index < 0) + return; + + ui->pushButtonConfigureIsaRomCard1->setEnabled((index != 0) && isarom_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); +} + +void +SettingsOtherPeripherals::on_pushButtonConfigureIsaRomCard1_clicked() +{ + DeviceConfig::ConfigureDevice(isarom_get_device(ui->comboBoxIsaRomCard1->currentData().toInt()), 1); +} + +void +SettingsOtherPeripherals::on_comboBoxIsaRomCard2_currentIndexChanged(int index) +{ + if (index < 0) + return; + + ui->pushButtonConfigureIsaRomCard2->setEnabled((index != 0) && isarom_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); +} + +void +SettingsOtherPeripherals::on_pushButtonConfigureIsaRomCard2_clicked() +{ + DeviceConfig::ConfigureDevice(isarom_get_device(ui->comboBoxIsaRomCard2->currentData().toInt()), 2); +} + +void +SettingsOtherPeripherals::on_comboBoxIsaRomCard3_currentIndexChanged(int index) +{ + if (index < 0) + return; + + ui->pushButtonConfigureIsaRomCard3->setEnabled((index != 0) && isarom_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); +} + +void +SettingsOtherPeripherals::on_pushButtonConfigureIsaRomCard3_clicked() +{ + DeviceConfig::ConfigureDevice(isarom_get_device(ui->comboBoxIsaRomCard3->currentData().toInt()), 3); +} + +void +SettingsOtherPeripherals::on_comboBoxIsaRomCard4_currentIndexChanged(int index) +{ + if (index < 0) + return; + + ui->pushButtonConfigureIsaRomCard4->setEnabled((index != 0) && isarom_has_config(index) && machine_has_bus(machineId, MACHINE_BUS_ISA)); +} + +void +SettingsOtherPeripherals::on_pushButtonConfigureIsaRomCard4_clicked() +{ + DeviceConfig::ConfigureDevice(isarom_get_device(ui->comboBoxIsaRomCard4->currentData().toInt()), 4); } void @@ -234,13 +350,12 @@ SettingsOtherPeripherals::on_pushButtonConfigureUT_clicked() DeviceConfig::ConfigureDevice(&unittester_device); } -void SettingsOtherPeripherals::on_pushButtonConfigureKeyCard_clicked() -{ - DeviceConfig::ConfigureDevice(&novell_keycard_device); -} - void SettingsOtherPeripherals::on_checkBoxKeyCard_stateChanged(int arg1) { ui->pushButtonConfigureKeyCard->setEnabled(arg1 != 0); } +void SettingsOtherPeripherals::on_pushButtonConfigureKeyCard_clicked() +{ + DeviceConfig::ConfigureDevice(&novell_keycard_device); +} diff --git a/src/qt/qt_settingsotherperipherals.hpp b/src/qt/qt_settingsotherperipherals.hpp index d5804a68b..991759259 100644 --- a/src/qt/qt_settingsotherperipherals.hpp +++ b/src/qt/qt_settingsotherperipherals.hpp @@ -20,22 +20,32 @@ public slots: void onCurrentMachineChanged(int machineId); private slots: - void on_pushButtonConfigureCard4_clicked(); - void on_comboBoxCard4_currentIndexChanged(int index); - void on_pushButtonConfigureCard3_clicked(); - void on_comboBoxCard3_currentIndexChanged(int index); - void on_pushButtonConfigureCard2_clicked(); - void on_comboBoxCard2_currentIndexChanged(int index); - void on_pushButtonConfigureCard1_clicked(); - void on_comboBoxCard1_currentIndexChanged(int index); - void on_pushButtonConfigureRTC_clicked(); void on_comboBoxRTC_currentIndexChanged(int index); + void on_pushButtonConfigureRTC_clicked(); + + void on_comboBoxIsaMemCard1_currentIndexChanged(int index); + void on_pushButtonConfigureIsaMemCard1_clicked(); + void on_comboBoxIsaMemCard2_currentIndexChanged(int index); + void on_pushButtonConfigureIsaMemCard2_clicked(); + void on_comboBoxIsaMemCard3_currentIndexChanged(int index); + void on_pushButtonConfigureIsaMemCard3_clicked(); + void on_comboBoxIsaMemCard4_currentIndexChanged(int index); + void on_pushButtonConfigureIsaMemCard4_clicked(); + + void on_comboBoxIsaRomCard1_currentIndexChanged(int index); + void on_pushButtonConfigureIsaRomCard1_clicked(); + void on_comboBoxIsaRomCard2_currentIndexChanged(int index); + void on_pushButtonConfigureIsaRomCard2_clicked(); + void on_comboBoxIsaRomCard3_currentIndexChanged(int index); + void on_pushButtonConfigureIsaRomCard3_clicked(); + void on_comboBoxIsaRomCard4_currentIndexChanged(int index); + void on_pushButtonConfigureIsaRomCard4_clicked(); + void on_checkBoxUnitTester_stateChanged(int arg1); void on_pushButtonConfigureUT_clicked(); - void on_pushButtonConfigureKeyCard_clicked(); - void on_checkBoxKeyCard_stateChanged(int arg1); + void on_pushButtonConfigureKeyCard_clicked(); private: Ui::SettingsOtherPeripherals *ui; diff --git a/src/qt/qt_settingsotherperipherals.ui b/src/qt/qt_settingsotherperipherals.ui index 41df2deac..0a366b833 100644 --- a/src/qt/qt_settingsotherperipherals.ui +++ b/src/qt/qt_settingsotherperipherals.ui @@ -27,9 +27,9 @@ 0 - + - + ISA RTC: @@ -58,20 +58,74 @@ - + ISA Memory Expansion - - - + + + + + Card 1: + + + + + + + + 0 + 0 + + + + 30 + + + + + Configure + + + + Card 2: + + + - + + + + 0 + 0 + + + + 30 + + + + + + + Configure + + + + + + + Card 3: + + + + + 0 @@ -84,68 +138,21 @@ - + Configure - - + + - Card 2: - - - - - - - Card 3: - - - - - - - Configure - - - - - - - - 0 - 0 - - - - 30 - - - - - - - Card 1: - - - - - - - - 0 - 0 - - - - 30 + Card 4: - + 0 @@ -158,24 +165,134 @@ - + Configure - - - - Card 4: - - - - + + + ISA ROM Cards + + + + + + Card 1: + + + + + + + + 0 + 0 + + + + 30 + + + + + + + Configure + + + + + + + Card 2: + + + + + + + + 0 + 0 + + + + 30 + + + + + + + Configure + + + + + + + Card 3: + + + + + + + + 0 + 0 + + + + 30 + + + + + + + Configure + + + + + + + Card 4: + + + + + + + + 0 + 0 + + + + 30 + + + + + + + Configure + + + + + + + + @@ -193,7 +310,7 @@ - + @@ -217,7 +334,7 @@ - + 0 @@ -265,6 +382,32 @@ + + comboBoxRTC + pushButtonConfigureRTC + comboBoxIsaMemCard1 + pushButtonConfigureIsaMemCard1 + comboBoxIsaMemCard2 + pushButtonConfigureIsaMemCard2 + comboBoxIsaMemCard3 + pushButtonConfigureIsaMemCard3 + comboBoxIsaMemCard4 + pushButtonConfigureIsaMemCard4 + comboBoxIsaRomCard1 + pushButtonConfigureIsaRomCard1 + comboBoxIsaRomCard2 + pushButtonConfigureIsaRomCard2 + comboBoxIsaRomCard3 + pushButtonConfigureIsaRomCard3 + comboBoxIsaRomCard4 + pushButtonConfigureIsaRomCard4 + checkBoxISABugger + checkBoxPOSTCard + checkBoxUnitTester + pushButtonConfigureUT + checkBoxKeyCard + pushButtonConfigureKeyCard + diff --git a/src/qt/qt_settingsotherremovable.cpp b/src/qt/qt_settingsotherremovable.cpp index 8a810a4fb..4ba07161c 100644 --- a/src/qt/qt_settingsotherremovable.cpp +++ b/src/qt/qt_settingsotherremovable.cpp @@ -23,7 +23,7 @@ extern "C" { #include <86box/timer.h> #include <86box/scsi_device.h> #include <86box/mo.h> -#include <86box/zip.h> +#include <86box/rdisk.h> } #include @@ -40,6 +40,13 @@ moDriveTypeName(int i) mo_drive_types[i].revision); } +static QString +rdiskDriveTypeName(int i) +{ + return QString("%1 %2 %3").arg(rdisk_drive_types[i].vendor, rdisk_drive_types[i].model, + rdisk_drive_types[i].revision); +} + static void setMOBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel) { @@ -65,27 +72,16 @@ setMOBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t } 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) - model->setData(i, QCoreApplication::translate("", "None")); - else - model->setData(i, moDriveTypeName(type)); - model->setData(i, type, Qt::UserRole); -} - -static void -setZIPBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel) +setRDiskBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel) { QIcon icon; switch (bus) { - case ZIP_BUS_DISABLED: - icon = QIcon(":/settings/qt/icons/zip_disabled.ico"); + case RDISK_BUS_DISABLED: + icon = QIcon(":/settings/qt/icons/rdisk_disabled.ico"); break; - case ZIP_BUS_ATAPI: - case ZIP_BUS_SCSI: - icon = QIcon(":/settings/qt/icons/zip.ico"); + case RDISK_BUS_ATAPI: + case RDISK_BUS_SCSI: + icon = QIcon(":/settings/qt/icons/rdisk.ico"); break; default: @@ -100,11 +96,25 @@ setZIPBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_ } static void -setZIPType(QAbstractItemModel *model, const QModelIndex &idx, bool is250) +setMOType(QAbstractItemModel *model, const QModelIndex &idx, uint32_t type) { auto i = idx.siblingAtColumn(1); - model->setData(i, is250 ? "ZIP 250" : "ZIP 100"); - model->setData(i, is250, Qt::UserRole); + if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() == MO_BUS_DISABLED) + model->setData(i, QCoreApplication::translate("", "None")); + else + model->setData(i, moDriveTypeName(type)); + model->setData(i, type, Qt::UserRole); +} + +static void +setRDiskType(QAbstractItemModel *model, const QModelIndex &idx, uint32_t type) +{ + auto i = idx.siblingAtColumn(1); + if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() == RDISK_BUS_DISABLED) + model->setData(i, QCoreApplication::translate("", "None")); + else + model->setData(i, rdiskDriveTypeName(type)); + model->setData(i, type, Qt::UserRole); } SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) @@ -114,6 +124,7 @@ SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) ui->setupUi(this); Harddrives::populateRemovableBuses(ui->comboBoxMOBus->model()); + ui->comboBoxMOBus->model()->removeRows(3, ui->comboBoxMOBus->model()->rowCount() - 3); auto *model = ui->comboBoxMOType->model(); for (uint32_t i = 0; i < KNOWN_MO_DRIVE_TYPES; i++) { Models::AddEntry(model, moDriveTypeName(i), i); @@ -136,24 +147,30 @@ SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) connect(ui->tableViewMO->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsOtherRemovable::onMORowChanged); ui->tableViewMO->setCurrentIndex(model->index(0, 0)); - Harddrives::populateRemovableBuses(ui->comboBoxZIPBus->model()); + Harddrives::populateRemovableBuses(ui->comboBoxRDiskBus->model()); + if ((ui->comboBoxRDiskBus->model()->rowCount() - 3) > 0) + ui->comboBoxRDiskBus->model()->removeRows(3, ui->comboBoxRDiskBus->model()->rowCount() - 3); + model = ui->comboBoxRDiskType->model(); + for (uint32_t i = 0; i < KNOWN_RDISK_DRIVE_TYPES; i++) { + Models::AddEntry(model, rdiskDriveTypeName(i), i); + } model = new QStandardItemModel(0, 2, this); - ui->tableViewZIP->setModel(model); + ui->tableViewRDisk->setModel(model); model->setHeaderData(0, Qt::Horizontal, tr("Bus")); model->setHeaderData(1, Qt::Horizontal, tr("Type")); - model->insertRows(0, ZIP_NUM); - for (int i = 0; i < ZIP_NUM; i++) { + model->insertRows(0, RDISK_NUM); + for (int i = 0; i < RDISK_NUM; i++) { auto idx = model->index(i, 0); - setZIPBus(model, idx, zip_drives[i].bus_type, zip_drives[i].res); - setZIPType(model, idx, zip_drives[i].is_250 > 0); - Harddrives::busTrackClass->device_track(1, DEV_ZIP, zip_drives[i].bus_type, zip_drives[i].bus_type == ZIP_BUS_ATAPI ? zip_drives[i].ide_channel : zip_drives[i].scsi_device_id); + setRDiskBus(model, idx, rdisk_drives[i].bus_type, rdisk_drives[i].res); + setRDiskType(model, idx.siblingAtColumn(1), rdisk_drives[i].type); + Harddrives::busTrackClass->device_track(1, DEV_MO, rdisk_drives[i].bus_type, rdisk_drives[i].bus_type == RDISK_BUS_ATAPI ? rdisk_drives[i].ide_channel : rdisk_drives[i].scsi_device_id); } - ui->tableViewZIP->resizeColumnsToContents(); - ui->tableViewZIP->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + ui->tableViewRDisk->resizeColumnsToContents(); + ui->tableViewRDisk->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - connect(ui->tableViewZIP->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsOtherRemovable::onZIPRowChanged); - ui->tableViewZIP->setCurrentIndex(model->index(0, 0)); + connect(ui->tableViewRDisk->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsOtherRemovable::onRDiskRowChanged); + ui->tableViewRDisk->setCurrentIndex(model->index(0, 0)); } SettingsOtherRemovable::~SettingsOtherRemovable() @@ -173,13 +190,13 @@ SettingsOtherRemovable::save() mo_drives[i].type = model->index(i, 1).data(Qt::UserRole).toUInt(); } - model = ui->tableViewZIP->model(); - 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(); - zip_drives[i].is_250 = model->index(i, 1).data(Qt::UserRole).toBool() ? 1 : 0; + model = ui->tableViewRDisk->model(); + for (uint8_t i = 0; i < RDISK_NUM; i++) { + rdisk_drives[i].fp = NULL; + rdisk_drives[i].priv = NULL; + rdisk_drives[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); + rdisk_drives[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); + rdisk_drives[i].type = model->index(i, 1).data(Qt::UserRole).toUInt(); } } @@ -205,24 +222,24 @@ SettingsOtherRemovable::onMORowChanged(const QModelIndex ¤t) } void -SettingsOtherRemovable::onZIPRowChanged(const QModelIndex ¤t) +SettingsOtherRemovable::onRDiskRowChanged(const QModelIndex ¤t) { uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt(); - bool is250 = current.siblingAtColumn(1).data(Qt::UserRole).toBool(); + uint8_t type = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); - ui->comboBoxZIPBus->setCurrentIndex(-1); - const auto *model = ui->comboBoxZIPBus->model(); + ui->comboBoxRDiskBus->setCurrentIndex(-1); + const auto *model = ui->comboBoxRDiskBus->model(); auto match = model->match(model->index(0, 0), Qt::UserRole, bus); if (!match.isEmpty()) - ui->comboBoxZIPBus->setCurrentIndex(match.first().row()); + ui->comboBoxRDiskBus->setCurrentIndex(match.first().row()); - model = ui->comboBoxZIPChannel->model(); + model = ui->comboBoxRDiskChannel->model(); match = model->match(model->index(0, 0), Qt::UserRole, channel); if (!match.isEmpty()) - ui->comboBoxZIPChannel->setCurrentIndex(match.first().row()); - ui->checkBoxZIP250->setChecked(is250); - enableCurrentlySelectedChannel_ZIP(); + ui->comboBoxRDiskChannel->setCurrentIndex(match.first().row()); + ui->comboBoxRDiskType->setCurrentIndex(type); + enableCurrentlySelectedChannel_RDisk(); } void @@ -234,6 +251,15 @@ SettingsOtherRemovable::reloadBusChannels_MO() { enableCurrentlySelectedChannel_MO(); } +void +SettingsOtherRemovable::reloadBusChannels_RDisk() { + auto selected = ui->comboBoxRDiskChannel->currentIndex(); + Harddrives::populateBusChannels(ui->comboBoxRDiskChannel->model(), + ui->comboBoxRDiskBus->currentData().toInt(), Harddrives::busTrackClass); + ui->comboBoxRDiskChannel->setCurrentIndex(selected); + enableCurrentlySelectedChannel_RDisk(); +} + void SettingsOtherRemovable::on_comboBoxMOBus_currentIndexChanged(int index) { @@ -246,6 +272,18 @@ SettingsOtherRemovable::on_comboBoxMOBus_currentIndexChanged(int index) } } +void +SettingsOtherRemovable::on_comboBoxRDiskBus_currentIndexChanged(int index) +{ + if (index >= 0) { + int bus = ui->comboBoxRDiskBus->currentData().toInt(); + bool enabled = (bus != RDISK_BUS_DISABLED); + ui->comboBoxRDiskChannel->setEnabled(enabled); + ui->comboBoxRDiskType->setEnabled(enabled); + Harddrives::populateBusChannels(ui->comboBoxRDiskChannel->model(), bus, Harddrives::busTrackClass); + } +} + void SettingsOtherRemovable::on_comboBoxMOBus_activated(int) { @@ -253,9 +291,9 @@ SettingsOtherRemovable::on_comboBoxMOBus_activated(int) 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->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(), @@ -272,6 +310,32 @@ SettingsOtherRemovable::on_comboBoxMOBus_activated(int) emit moChannelChanged(); } +void +SettingsOtherRemovable::on_comboBoxRDiskBus_activated(int) +{ + auto i = ui->tableViewRDisk->selectionModel()->currentIndex().siblingAtColumn(0); + Harddrives::busTrackClass->device_track(0, DEV_RDISK, ui->tableViewRDisk->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewRDisk->model()->data(i, + Qt::UserRole + 1).toInt()); + ui->comboBoxRDiskChannel->setCurrentIndex(ui->comboBoxRDiskBus->currentData().toUInt() == RDISK_BUS_ATAPI ? + Harddrives::busTrackClass->next_free_ide_channel() : + Harddrives::busTrackClass->next_free_scsi_id()); + ui->tableViewRDisk->model()->data(i, Qt::UserRole + 1); + setRDiskBus(ui->tableViewRDisk->model(), + ui->tableViewRDisk->selectionModel()->currentIndex(), + ui->comboBoxRDiskBus->currentData().toUInt(), + ui->comboBoxRDiskChannel->currentData().toUInt()); + setRDiskType(ui->tableViewRDisk->model(), + ui->tableViewRDisk->selectionModel()->currentIndex(), + ui->comboBoxRDiskType->currentData().toUInt()); + ui->tableViewRDisk->resizeColumnsToContents(); + ui->tableViewRDisk->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + Harddrives::busTrackClass->device_track(1, DEV_RDISK, ui->tableViewRDisk->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewRDisk->model()->data(i, + Qt::UserRole + 1).toInt()); + emit rdiskChannelChanged(); +} + void SettingsOtherRemovable::enableCurrentlySelectedChannel_MO() { @@ -282,6 +346,15 @@ SettingsOtherRemovable::enableCurrentlySelectedChannel_MO() item->setEnabled(true); } +void +SettingsOtherRemovable::enableCurrentlySelectedChannel_RDisk() +{ + const auto *item_model = qobject_cast(ui->comboBoxRDiskChannel->model()); + const auto index = ui->comboBoxRDiskChannel->currentIndex(); + auto *item = item_model->item(index); + if (item) + item->setEnabled(true); +} void SettingsOtherRemovable::on_comboBoxMOChannel_activated(int) { @@ -299,6 +372,23 @@ SettingsOtherRemovable::on_comboBoxMOChannel_activated(int) emit moChannelChanged(); } +void +SettingsOtherRemovable::on_comboBoxRDiskChannel_activated(int) +{ + auto i = ui->tableViewRDisk->selectionModel()->currentIndex().siblingAtColumn(0); + Harddrives::busTrackClass->device_track(0, DEV_RDISK, ui->tableViewRDisk->model()->data(i, + Qt::UserRole).toInt(), ui->tableViewRDisk->model()->data(i, + Qt::UserRole + 1).toInt()); + setRDiskBus(ui->tableViewRDisk->model(), + ui->tableViewRDisk->selectionModel()->currentIndex(), + ui->comboBoxRDiskBus->currentData().toUInt(), + ui->comboBoxRDiskChannel->currentData().toUInt()); + Harddrives::busTrackClass->device_track(1, DEV_RDISK, ui->tableViewRDisk->model()->data(i, + Qt::UserRole).toInt(), + ui->tableViewRDisk->model()->data(i, Qt::UserRole + 1).toInt()); + emit rdiskChannelChanged(); +} + void SettingsOtherRemovable::on_comboBoxMOType_activated(int) { @@ -310,77 +400,11 @@ SettingsOtherRemovable::on_comboBoxMOType_activated(int) } void -SettingsOtherRemovable::reloadBusChannels_ZIP() { - auto selected = ui->comboBoxZIPChannel->currentIndex(); - Harddrives::populateBusChannels(ui->comboBoxZIPChannel->model(), - ui->comboBoxZIPBus->currentData().toInt(), Harddrives::busTrackClass); - ui->comboBoxZIPChannel->setCurrentIndex(selected); - enableCurrentlySelectedChannel_ZIP(); -} - -void -SettingsOtherRemovable::on_comboBoxZIPBus_currentIndexChanged(int index) +SettingsOtherRemovable::on_comboBoxRDiskType_activated(int) { - 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, Harddrives::busTrackClass); - } -} - -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()); - emit zipChannelChanged(); -} - -void -SettingsOtherRemovable::enableCurrentlySelectedChannel_ZIP() -{ - const auto *item_model = qobject_cast(ui->comboBoxZIPChannel->model()); - const auto index = ui->comboBoxZIPChannel->currentIndex(); - auto *item = item_model->item(index); - if (item) - item->setEnabled(true); -} - -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()); - emit zipChannelChanged(); -} - -void -SettingsOtherRemovable::on_checkBoxZIP250_stateChanged(int state) -{ - setZIPType(ui->tableViewZIP->model(), - ui->tableViewZIP->selectionModel()->currentIndex(), - state == Qt::Checked); + setRDiskType(ui->tableViewRDisk->model(), + ui->tableViewRDisk->selectionModel()->currentIndex(), + ui->comboBoxRDiskType->currentData().toUInt()); + ui->tableViewRDisk->resizeColumnsToContents(); + ui->tableViewRDisk->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); } diff --git a/src/qt/qt_settingsotherremovable.hpp b/src/qt/qt_settingsotherremovable.hpp index cea1d202b..79fcfbf3f 100644 --- a/src/qt/qt_settingsotherremovable.hpp +++ b/src/qt/qt_settingsotherremovable.hpp @@ -14,45 +14,31 @@ public: explicit SettingsOtherRemovable(QWidget *parent = nullptr); ~SettingsOtherRemovable(); void reloadBusChannels_MO(); - void reloadBusChannels_ZIP(); + void reloadBusChannels_RDisk(); void save(); signals: void moChannelChanged(); - void zipChannelChanged(); -private slots: - void on_checkBoxZIP250_stateChanged(int arg1); - -private slots: - void on_comboBoxZIPChannel_activated(int index); - -private slots: - void on_comboBoxZIPBus_activated(int index); - -private slots: - void on_comboBoxZIPBus_currentIndexChanged(int index); - -private slots: - void on_comboBoxMOType_activated(int index); - -private slots: - void on_comboBoxMOChannel_activated(int index); - -private slots: - void on_comboBoxMOBus_activated(int index); - -private slots: - void on_comboBoxMOBus_currentIndexChanged(int index); + void rdiskChannelChanged(); private slots: void onMORowChanged(const QModelIndex ¤t); - void onZIPRowChanged(const QModelIndex ¤t); + void on_comboBoxMOBus_currentIndexChanged(int index); + void on_comboBoxMOBus_activated(int index); + void on_comboBoxMOChannel_activated(int index); + void on_comboBoxMOType_activated(int index); + + void onRDiskRowChanged(const QModelIndex ¤t); + void on_comboBoxRDiskBus_currentIndexChanged(int index); + void on_comboBoxRDiskBus_activated(int index); + void on_comboBoxRDiskChannel_activated(int index); + void on_comboBoxRDiskType_activated(int index); private: Ui::SettingsOtherRemovable *ui; void enableCurrentlySelectedChannel_MO(); - void enableCurrentlySelectedChannel_ZIP(); + void enableCurrentlySelectedChannel_RDisk(); }; #endif // QT_SETTINGSOTHERREMOVABLE_HPP diff --git a/src/qt/qt_settingsotherremovable.ui b/src/qt/qt_settingsotherremovable.ui index 8962184fc..8224d67f6 100644 --- a/src/qt/qt_settingsotherremovable.ui +++ b/src/qt/qt_settingsotherremovable.ui @@ -27,7 +27,7 @@ 0 - + MO drives: @@ -68,19 +68,12 @@ - + Bus: - - - - Channel: - - - @@ -88,6 +81,13 @@ + + + + Channel: + + + @@ -96,7 +96,7 @@ - + Type: @@ -113,14 +113,14 @@ - + - ZIP drives: + Removable disk drives: - + 0 @@ -151,40 +151,47 @@ - - - - + + + + Bus: - - + + 30 - - + + Channel: - - + + 30 - - + + - ZIP 250 + Type: + + + + + + + 30 @@ -193,6 +200,16 @@ + + tableViewMO + comboBoxMOBus + comboBoxMOChannel + comboBoxMOType + tableViewRDisk + comboBoxRDiskBus + comboBoxRDiskChannel + comboBoxRDiskType + diff --git a/src/qt/qt_settingsports.cpp b/src/qt/qt_settingsports.cpp index 7e8f2aeda..5abe0a805 100644 --- a/src/qt/qt_settingsports.cpp +++ b/src/qt/qt_settingsports.cpp @@ -51,7 +51,7 @@ SettingsPorts::save() { for (int i = 0; i < PARALLEL_MAX; i++) { auto *cbox = findChild(QString("comboBoxLpt%1").arg(i + 1)); - auto *checkBox = findChild(QString("checkBoxParallel%1").arg(i + 1)); + auto *checkBox = findChild(QString("checkBoxParallel%1").arg(i + 1)); if (cbox != NULL) lpt_ports[i].device = cbox->currentData().toInt(); if (checkBox != NULL) @@ -73,7 +73,7 @@ SettingsPorts::onCurrentMachineChanged(int machineId) { this->machineId = machineId; - int c = 0; + int c = 0; // LPT Device QComboBox * cbox[PARALLEL_MAX] = { 0 }; @@ -93,7 +93,7 @@ SettingsPorts::onCurrentMachineChanged(int machineId) if (lptName == nullptr) break; - const QString name = tr(lptName); + const QString name = tr(lptName); for (uint8_t i = 0; i < PARALLEL_MAX; ++i) { int row = Models::AddEntry(models[i], name, c); @@ -111,11 +111,17 @@ SettingsPorts::onCurrentMachineChanged(int machineId) cbox[i]->setCurrentIndex(-1); cbox[i]->setCurrentIndex(selectedRows[i]); - auto *checkBox = findChild(QString("checkBoxParallel%1").arg(i + 1)); + auto *checkBox = findChild(QString("checkBoxParallel%1").arg(i + 1)); + auto *buttonCfg = findChild(QString("pushButtonConfigureLpt%1").arg(i + 1)); if (checkBox != NULL) checkBox->setChecked(lpt_ports[i].enabled > 0); - if (cbox[i] != NULL) + if (cbox[i] != NULL) { cbox[i]->setEnabled(lpt_ports[i].enabled > 0); + if (buttonCfg != NULL) { + int lptDevice = cbox[i]->currentData().toInt(); + buttonCfg->setEnabled(lpt_device_has_config(lptDevice) && (lpt_ports[i].enabled > 0)); + } + } } for (int i = 0; i < (SERIAL_MAX - 1); i++) { @@ -132,6 +138,86 @@ SettingsPorts::onCurrentMachineChanged(int machineId) } } +void +SettingsPorts::on_comboBoxLpt1_currentIndexChanged(int index) +{ + if (index < 0) + return; + + int lptDevice = ui->comboBoxLpt1->currentData().toInt(); + + ui->pushButtonConfigureLpt1->setEnabled(lpt_device_has_config(lptDevice)); +} + +void +SettingsPorts::on_pushButtonConfigureLpt1_clicked() +{ + int lptDevice = ui->comboBoxLpt1->currentData().toInt(); + auto *device = lpt_device_getdevice(lptDevice); + + DeviceConfig::ConfigureDevice(device, 1); +} + +void +SettingsPorts::on_comboBoxLpt2_currentIndexChanged(int index) +{ + if (index < 0) + return; + + int lptDevice = ui->comboBoxLpt2->currentData().toInt(); + + ui->pushButtonConfigureLpt2->setEnabled(lpt_device_has_config(lptDevice)); +} + +void +SettingsPorts::on_pushButtonConfigureLpt2_clicked() +{ + int lptDevice = ui->comboBoxLpt2->currentData().toInt(); + auto *device = lpt_device_getdevice(lptDevice); + + DeviceConfig::ConfigureDevice(device, 1); +} + +void +SettingsPorts::on_comboBoxLpt3_currentIndexChanged(int index) +{ + if (index < 0) + return; + + int lptDevice = ui->comboBoxLpt3->currentData().toInt(); + + ui->pushButtonConfigureLpt3->setEnabled(lpt_device_has_config(lptDevice)); +} + +void +SettingsPorts::on_pushButtonConfigureLpt3_clicked() +{ + int lptDevice = ui->comboBoxLpt3->currentData().toInt(); + auto *device = lpt_device_getdevice(lptDevice); + + DeviceConfig::ConfigureDevice(device, 1); +} + +void +SettingsPorts::on_comboBoxLpt4_currentIndexChanged(int index) +{ + if (index < 0) + return; + + int lptDevice = ui->comboBoxLpt4->currentData().toInt(); + + ui->pushButtonConfigureLpt4->setEnabled(lpt_device_has_config(lptDevice)); +} + +void +SettingsPorts::on_pushButtonConfigureLpt4_clicked() +{ + int lptDevice = ui->comboBoxLpt4->currentData().toInt(); + auto *device = lpt_device_getdevice(lptDevice); + + DeviceConfig::ConfigureDevice(device, 1); +} + void SettingsPorts::on_checkBoxParallel1_stateChanged(int state) { diff --git a/src/qt/qt_settingsports.hpp b/src/qt/qt_settingsports.hpp index 83560914f..f6024b094 100644 --- a/src/qt/qt_settingsports.hpp +++ b/src/qt/qt_settingsports.hpp @@ -20,6 +20,15 @@ public slots: void onCurrentMachineChanged(int machineId); private slots: + void on_comboBoxLpt1_currentIndexChanged(int index); + void on_pushButtonConfigureLpt1_clicked(); + void on_comboBoxLpt2_currentIndexChanged(int index); + void on_pushButtonConfigureLpt2_clicked(); + void on_comboBoxLpt3_currentIndexChanged(int index); + void on_pushButtonConfigureLpt3_clicked(); + void on_comboBoxLpt4_currentIndexChanged(int index); + void on_pushButtonConfigureLpt4_clicked(); + void on_checkBoxParallel1_stateChanged(int state); void on_checkBoxParallel2_stateChanged(int state); void on_checkBoxParallel3_stateChanged(int state); @@ -35,22 +44,25 @@ private slots: void on_checkBoxSerial7_stateChanged(int state); #endif void on_checkBoxSerialPassThru1_stateChanged(int state); + void on_pushButtonSerialPassThru1_clicked(); + void on_checkBoxSerialPassThru2_stateChanged(int state); + void on_pushButtonSerialPassThru2_clicked(); + void on_checkBoxSerialPassThru3_stateChanged(int state); + void on_pushButtonSerialPassThru3_clicked(); + void on_checkBoxSerialPassThru4_stateChanged(int state); + void on_pushButtonSerialPassThru4_clicked(); + #if 0 void on_checkBoxSerialPassThru5_stateChanged(int state); - void on_checkBoxSerialPassThru6_stateChanged(int state); - void on_checkBoxSerialPassThru7_stateChanged(int state); -#endif - - void on_pushButtonSerialPassThru1_clicked(); - void on_pushButtonSerialPassThru2_clicked(); - void on_pushButtonSerialPassThru3_clicked(); - void on_pushButtonSerialPassThru4_clicked(); -#if 0 void on_pushButtonSerialPassThru5_clicked(); + + void on_checkBoxSerialPassThru6_stateChanged(int state); void on_pushButtonSerialPassThru6_clicked(); + + void on_checkBoxSerialPassThru7_stateChanged(int state); void on_pushButtonSerialPassThru7_clicked(); #endif diff --git a/src/qt/qt_settingsports.ui b/src/qt/qt_settingsports.ui index bca870e5d..0ac4cb92c 100644 --- a/src/qt/qt_settingsports.ui +++ b/src/qt/qt_settingsports.ui @@ -13,7 +13,7 @@ Form - + 0 @@ -27,88 +27,119 @@ 0 - + - + LPT1 Device: - + + + + 0 + 0 + + 30 + + + + Configure + + + - + LPT2 Device: - + + + + 0 + 0 + + 30 + + + + Configure + + + - + LPT3 Device: - + + + + 0 + 0 + + 30 + + + + Configure + + + - + LPT4 Device: - + + + + 0 + 0 + + 30 + + + + Configure + + + - - - - Parallel port 2 - - - - - - - Parallel port 3 - - - - - - - Serial port 3 - - - @@ -116,20 +147,6 @@ - - - - Parallel port 4 - - - - - - - Serial port 2 - - - @@ -137,6 +154,34 @@ + + + + Serial port 2 + + + + + + + Parallel port 2 + + + + + + + Serial port 3 + + + + + + + Parallel port 3 + + + @@ -144,13 +189,76 @@ + + + + Parallel port 4 + + + - + QLayout::SetDefaultConstraint + + + + Serial port passthrough 1 + + + + + + + Configure + + + + + + + Serial port passthrough 2 + + + + + + + Configure + + + + + + + Serial port passthrough 3 + + + + + + + Configure + + + + + + + Serial port passthrough 4 + + + + + + + Configure + + + @@ -164,13 +272,6 @@ - - - - Serial port passthrough 3 - - - @@ -184,55 +285,6 @@ - - - - Configure - - - - - - - Serial port passthrough 1 - - - - - - - Serial port passthrough 2 - - - - - - - Serial port passthrough 4 - - - - - - - Configure - - - - - - - Configure - - - - - - - Configure - - - diff --git a/src/qt/qt_settingssound.cpp b/src/qt/qt_settingssound.cpp index e49e1ae27..57e278515 100644 --- a/src/qt/qt_settingssound.cpp +++ b/src/qt/qt_settingssound.cpp @@ -14,7 +14,7 @@ * Jasmine Iwanek * * Copyright 2021 Joakim L. Gilje - * Copyright 2022-2023 Jasmine Iwanek + * Copyright 2022-2025 Jasmine Iwanek */ #include "qt_settingssound.hpp" #include "ui_qt_settingssound.h" @@ -76,8 +76,8 @@ SettingsSound::onCurrentMachineChanged(const int machineId) int c; int selectedRow; - // Sound Card - QComboBox * cbox[SOUND_CARD_MAX] = { 0 }; + // Sound Cards + QComboBox *cbox[SOUND_CARD_MAX] = { 0 }; QAbstractItemModel *models[SOUND_CARD_MAX] = { 0 }; int removeRows_[SOUND_CARD_MAX] = { 0 }; int selectedRows[SOUND_CARD_MAX] = { 0 }; @@ -89,7 +89,7 @@ SettingsSound::onCurrentMachineChanged(const int machineId) removeRows_[i] = models[i]->rowCount(); } - c = 0; + c = 0; while (true) { const QString name = DeviceConfig::DeviceName(sound_card_getdevice(c), sound_card_get_internal_name(c), 1); @@ -110,7 +110,7 @@ SettingsSound::onCurrentMachineChanged(const int machineId) } } - c++; + c++; } for (uint8_t i = 0; i < SOUND_CARD_MAX; ++i) { @@ -122,21 +122,19 @@ SettingsSound::onCurrentMachineChanged(const int machineId) // Midi Out c = 0; - auto model = ui->comboBoxMidiOut->model(); + auto *model = ui->comboBoxMidiOut->model(); auto removeRows = model->rowCount(); selectedRow = 0; while (true) { const QString name = DeviceConfig::DeviceName(midi_out_device_getdevice(c), midi_out_device_get_internal_name(c), 0); - if (name.isEmpty()) { + if (name.isEmpty()) break; - } if (midi_out_device_available(c)) { int row = Models::AddEntry(model, name, c); - if (c == midi_output_device_current) { + if (c == midi_output_device_current) selectedRow = row - removeRows; - } } c++; @@ -155,15 +153,13 @@ SettingsSound::onCurrentMachineChanged(const int machineId) while (true) { const QString name = DeviceConfig::DeviceName(midi_in_device_getdevice(c), midi_in_device_get_internal_name(c), 0); - if (name.isEmpty()) { + if (name.isEmpty()) break; - } if (midi_in_device_available(c)) { int row = Models::AddEntry(model, name, c); - if (c == midi_input_device_current) { + if (c == midi_input_device_current) selectedRow = row - removeRows; - } } c++; @@ -198,13 +194,11 @@ allowMpu401(Ui::SettingsSound *ui) QString midiOut = midi_out_device_get_internal_name(ui->comboBoxMidiOut->currentData().toInt()); QString midiIn = midi_in_device_get_internal_name(ui->comboBoxMidiIn->currentData().toInt()); - if (midiOut.isEmpty()) { + if (midiOut.isEmpty()) return false; - } - if (midiOut == QStringLiteral("none") && midiIn == QStringLiteral("none")) { + if (midiOut == QStringLiteral("none") && midiIn == QStringLiteral("none")) return false; - } return true; } @@ -212,9 +206,9 @@ allowMpu401(Ui::SettingsSound *ui) void SettingsSound::on_comboBoxSoundCard1_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } + int sndCard = ui->comboBoxSoundCard1->currentData().toInt(); if (sndCard == SOUND_INTERNAL) @@ -238,9 +232,8 @@ SettingsSound::on_pushButtonConfigureSoundCard1_clicked() void SettingsSound::on_comboBoxSoundCard2_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } int sndCard = ui->comboBoxSoundCard2->currentData().toInt(); @@ -258,9 +251,8 @@ SettingsSound::on_pushButtonConfigureSoundCard2_clicked() void SettingsSound::on_comboBoxSoundCard3_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } int sndCard = ui->comboBoxSoundCard3->currentData().toInt(); @@ -279,9 +271,8 @@ SettingsSound::on_pushButtonConfigureSoundCard3_clicked() void SettingsSound::on_comboBoxSoundCard4_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } int sndCard = ui->comboBoxSoundCard4->currentData().toInt(); @@ -300,9 +291,8 @@ SettingsSound::on_pushButtonConfigureSoundCard4_clicked() void SettingsSound::on_comboBoxMidiOut_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } ui->pushButtonConfigureMidiOut->setEnabled(midi_out_device_has_config(ui->comboBoxMidiOut->currentData().toInt())); ui->checkBoxMPU401->setEnabled(allowMpu401(ui) && (machine_has_bus(machineId, MACHINE_BUS_ISA) || machine_has_bus(machineId, MACHINE_BUS_MCA))); @@ -318,9 +308,8 @@ SettingsSound::on_pushButtonConfigureMidiOut_clicked() void SettingsSound::on_comboBoxMidiIn_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } ui->pushButtonConfigureMidiIn->setEnabled(midi_in_device_has_config(ui->comboBoxMidiIn->currentData().toInt())); ui->checkBoxMPU401->setEnabled(allowMpu401(ui) && (machine_has_bus(machineId, MACHINE_BUS_ISA) || machine_has_bus(machineId, MACHINE_BUS_MCA))); diff --git a/src/qt/qt_settingssound.hpp b/src/qt/qt_settingssound.hpp index 92b700c92..cc2926d5d 100644 --- a/src/qt/qt_settingssound.hpp +++ b/src/qt/qt_settingssound.hpp @@ -20,20 +20,26 @@ public slots: void onCurrentMachineChanged(int machineId); private slots: - void on_pushButtonConfigureMPU401_clicked(); - void on_checkBoxMPU401_stateChanged(int arg1); - void on_pushButtonConfigureMidiIn_clicked(); - void on_pushButtonConfigureMidiOut_clicked(); - void on_comboBoxMidiIn_currentIndexChanged(int index); - void on_comboBoxMidiOut_currentIndexChanged(int index); - void on_pushButtonConfigureSoundCard1_clicked(); void on_comboBoxSoundCard1_currentIndexChanged(int index); - void on_pushButtonConfigureSoundCard2_clicked(); + void on_pushButtonConfigureSoundCard1_clicked(); + void on_comboBoxSoundCard2_currentIndexChanged(int index); - void on_pushButtonConfigureSoundCard3_clicked(); + void on_pushButtonConfigureSoundCard2_clicked(); + void on_comboBoxSoundCard3_currentIndexChanged(int index); - void on_pushButtonConfigureSoundCard4_clicked(); + void on_pushButtonConfigureSoundCard3_clicked(); + void on_comboBoxSoundCard4_currentIndexChanged(int index); + void on_pushButtonConfigureSoundCard4_clicked(); + + void on_comboBoxMidiOut_currentIndexChanged(int index); + void on_pushButtonConfigureMidiOut_clicked(); + + void on_comboBoxMidiIn_currentIndexChanged(int index); + void on_pushButtonConfigureMidiIn_clicked(); + + void on_checkBoxMPU401_stateChanged(int arg1); + void on_pushButtonConfigureMPU401_clicked(); private: Ui::SettingsSound *ui; diff --git a/src/qt/qt_settingssound.ui b/src/qt/qt_settingssound.ui index 1d5ab0050..97ef7c3ff 100644 --- a/src/qt/qt_settingssound.ui +++ b/src/qt/qt_settingssound.ui @@ -26,17 +26,23 @@ 0 - - + + - MIDI In Device: + Sound card #1: - - - - Sound card #1: + + + + 30 + + + + 0 + 0 + @@ -48,12 +54,25 @@ - + Sound card #2: + + + + 30 + + + + 0 + 0 + + + + @@ -62,12 +81,25 @@ - + Sound card #3: + + + + 30 + + + + 0 + 0 + + + + @@ -75,14 +107,26 @@ - - + Sound card #4: + + + + 30 + + + + 0 + 0 + + + + @@ -90,49 +134,13 @@ - - - - - - 30 - - - - 0 - 0 - - - - - + MIDI Out Device: - - - - Standalone MPU-401 - - - - - - - Configure - - - - - - - Configure - - - @@ -153,6 +161,47 @@ + + + + MIDI In Device: + + + + + + + 30 + + + + 0 + 0 + + + + + + + + Configure + + + + + + + Standalone MPU-401 + + + + + + + Configure + + + @@ -171,7 +220,7 @@ FM synth driver - + @@ -202,58 +251,6 @@ - - - - 30 - - - - 0 - 0 - - - - - - - - 30 - - - - 0 - 0 - - - - - - - - 30 - - - - 0 - 0 - - - - - - - - 30 - - - - 0 - 0 - - - - diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 48fa04892..8614852eb 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -52,17 +52,17 @@ void SettingsStorageControllers::save() { /* Storage devices category */ + for (uint8_t i = 0; i < HDC_MAX; ++i) { + QComboBox *cbox = findChild(QString("comboBoxHD%1").arg(i + 1)); + hdc_current[i] = cbox->currentData().toInt(); + } for (uint8_t i = 0; i < SCSI_CARD_MAX; ++i) { QComboBox *cbox = findChild(QString("comboBoxSCSI%1").arg(i + 1)); scsi_card_current[i] = cbox->currentData().toInt(); } - hdc_current[0] = ui->comboBoxHD->currentData().toInt(); fdc_current[0] = ui->comboBoxFD->currentData().toInt(); cdrom_interface_current = ui->comboBoxCDInterface->currentData().toInt(); - ide_ter_enabled = ui->checkBoxTertiaryIDE->isChecked() ? 1 : 0; - ide_qua_enabled = ui->checkBoxQuaternaryIDE->isChecked() ? 1 : 0; cassette_enable = ui->checkBoxCassette->isChecked() ? 1 : 0; - lba_enhancer_enabled = ui->checkBoxLbaEnhancer->isChecked() ? 1 : 0; } void @@ -70,46 +70,12 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) { this->machineId = machineId; - /*HD controller config*/ + /* FD controller config */ int c = 0; - auto *model = ui->comboBoxHD->model(); + auto *model = ui->comboBoxFD->model(); auto removeRows = model->rowCount(); int selectedRow = 0; - while (true) { - /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && (machine_has_flags(machineId, MACHINE_HDC) == 0)) { - c++; - continue; - } - - QString name = DeviceConfig::DeviceName(hdc_get_device(c), hdc_get_internal_name(c), 1); - if (name.isEmpty()) { - break; - } - - if (hdc_available(c)) { - const device_t *hdc_dev = hdc_get_device(c); - - if (device_is_valid(hdc_dev, machineId)) { - int row = Models::AddEntry(model, name, c); - if (c == hdc_current[0]) { - selectedRow = row - removeRows; - } - } - } - c++; - } - model->removeRows(0, removeRows); - ui->comboBoxHD->setEnabled(model->rowCount() > 0); - ui->comboBoxHD->setCurrentIndex(-1); - ui->comboBoxHD->setCurrentIndex(selectedRow); - - /*FD controller config*/ - model = ui->comboBoxFD->model(); - removeRows = model->rowCount(); - c = 0; - selectedRow = 0; while (true) { #if 0 /* Skip "internal" if machine doesn't have it. */ @@ -142,15 +108,10 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->comboBoxFD->setCurrentIndex(selectedRow); /*CD interface controller config*/ -#ifdef USE_CDROM_MITSUMI - ui->label_7->setVisible(true); + ui->labelCDInterface->setVisible(true); ui->comboBoxCDInterface->setVisible(true); ui->pushButtonCDInterface->setVisible(true); -#else - ui->label_7->setVisible(false); - ui->comboBoxCDInterface->setVisible(false); - ui->pushButtonCDInterface->setVisible(false); -#endif + c = 0; model = ui->comboBoxCDInterface->model(); removeRows = model->rowCount(); @@ -180,6 +141,51 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->comboBoxCDInterface->setCurrentIndex(-1); ui->comboBoxCDInterface->setCurrentIndex(selectedRow); + // HD Controller + QComboBox * hd_cbox[HDC_MAX] = { 0 }; + QAbstractItemModel *hd_models[HDC_MAX] = { 0 }; + int hd_removeRows_[HDC_MAX] = { 0 }; + int hd_selectedRows[HDC_MAX] = { 0 }; + + for (uint8_t i = 0; i < HDC_MAX; ++i) { + hd_cbox[i] = findChild(QString("comboBoxHD%1").arg(i + 1)); + hd_models[i] = hd_cbox[i]->model(); + hd_removeRows_[i] = hd_models[i]->rowCount(); + } + + c = 0; + while (true) { + const QString name = DeviceConfig::DeviceName(hdc_get_device(c), + hdc_get_internal_name(c), 1); + + if (name.isEmpty()) + break; + + if (hdc_available(c)) { + if (device_is_valid(hdc_get_device(c), machineId)) { + for (uint8_t i = 0; i < HDC_MAX; ++i) { + /* Skip "internal" if machine doesn't have it. */ + if ((c == 1) && ((i > 0) || (machine_has_flags(machineId, MACHINE_HDC) == 0))) + continue; + + int row = Models::AddEntry(hd_models[i], name, c); + + if (c == hdc_current[i]) + hd_selectedRows[i] = row - hd_removeRows_[i]; + } + } + } + + c++; + } + + for (uint8_t i = 0; i < HDC_MAX; ++i) { + hd_models[i]->removeRows(0, hd_removeRows_[i]); + hd_cbox[i]->setEnabled(hd_models[i]->rowCount() > 1); + hd_cbox[i]->setCurrentIndex(-1); + hd_cbox[i]->setCurrentIndex(hd_selectedRows[i]); + } + // SCSI Card QComboBox * cbox[SCSI_CARD_MAX] = { 0 }; QAbstractItemModel *models[SCSI_CARD_MAX] = { 0 }; @@ -211,7 +217,7 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) } } - c++; + c++; } for (uint8_t i = 0; i < SCSI_CARD_MAX; ++i) { @@ -221,12 +227,6 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) cbox[i]->setCurrentIndex(selectedRows[i]); } - int is_at = IS_AT(machineId); - ui->checkBoxTertiaryIDE->setEnabled(is_at > 0); - ui->checkBoxQuaternaryIDE->setEnabled(is_at > 0); - ui->checkBoxTertiaryIDE->setChecked(ui->checkBoxTertiaryIDE->isEnabled() && ide_ter_enabled); - ui->checkBoxQuaternaryIDE->setChecked(ui->checkBoxQuaternaryIDE->isEnabled() && ide_qua_enabled); - if (machine_has_bus(machineId, MACHINE_BUS_CASSETTE)) { ui->checkBoxCassette->setChecked(cassette_enable > 0); ui->checkBoxCassette->setEnabled(true); @@ -234,113 +234,131 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->checkBoxCassette->setChecked(false); ui->checkBoxCassette->setEnabled(false); } - - ui->checkBoxLbaEnhancer->setChecked(lba_enhancer_enabled > 0 && device_available(&lba_enhancer_device)); - ui->pushButtonConfigureLbaEnhancer->setEnabled(ui->checkBoxLbaEnhancer->isChecked()); -} - -void -SettingsStorageControllers::on_comboBoxHD_currentIndexChanged(int index) -{ - if (index < 0) { - return; - } - ui->pushButtonHD->setEnabled(hdc_has_config(ui->comboBoxHD->currentData().toInt()) > 0); } void SettingsStorageControllers::on_comboBoxFD_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } - ui->pushButtonFD->setEnabled(hdc_has_config(ui->comboBoxFD->currentData().toInt()) > 0); + + ui->pushButtonFD->setEnabled(fdc_card_has_config(ui->comboBoxFD->currentData().toInt()) > 0); +} + +void +SettingsStorageControllers::on_comboBoxHD1_currentIndexChanged(int index) +{ + if (index < 0) + return; + + ui->pushButtonHD1->setEnabled(hdc_has_config(ui->comboBoxHD1->currentData().toInt()) > 0); +} + +void +SettingsStorageControllers::on_comboBoxHD2_currentIndexChanged(int index) +{ + if (index < 0) + return; + + ui->pushButtonHD2->setEnabled(hdc_has_config(ui->comboBoxHD2->currentData().toInt()) > 0); +} + +void +SettingsStorageControllers::on_comboBoxHD3_currentIndexChanged(int index) +{ + if (index < 0) + return; + + ui->pushButtonHD3->setEnabled(hdc_has_config(ui->comboBoxHD3->currentData().toInt()) > 0); +} + +void +SettingsStorageControllers::on_comboBoxHD4_currentIndexChanged(int index) +{ + if (index < 0) + return; + + ui->pushButtonHD4->setEnabled(hdc_has_config(ui->comboBoxHD4->currentData().toInt()) > 0); } void SettingsStorageControllers::on_comboBoxCDInterface_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } + ui->pushButtonCDInterface->setEnabled(cdrom_interface_has_config(ui->comboBoxCDInterface->currentData().toInt()) > 0); } -void -SettingsStorageControllers::on_checkBoxTertiaryIDE_stateChanged(int arg1) -{ - ui->pushButtonTertiaryIDE->setEnabled(arg1 == Qt::Checked); -} - -void -SettingsStorageControllers::on_checkBoxQuaternaryIDE_stateChanged(int arg1) -{ - ui->pushButtonQuaternaryIDE->setEnabled(arg1 == Qt::Checked); -} - -void -SettingsStorageControllers::on_pushButtonHD_clicked() -{ - DeviceConfig::ConfigureDevice(hdc_get_device(ui->comboBoxHD->currentData().toInt())); -} - void SettingsStorageControllers::on_pushButtonFD_clicked() { DeviceConfig::ConfigureDevice(fdc_card_getdevice(ui->comboBoxFD->currentData().toInt())); } +void +SettingsStorageControllers::on_pushButtonHD1_clicked() +{ + DeviceConfig::ConfigureDevice(hdc_get_device(ui->comboBoxHD1->currentData().toInt()), 1); +} + +void +SettingsStorageControllers::on_pushButtonHD2_clicked() +{ + DeviceConfig::ConfigureDevice(hdc_get_device(ui->comboBoxHD2->currentData().toInt()), 2); +} + +void +SettingsStorageControllers::on_pushButtonHD3_clicked() +{ + DeviceConfig::ConfigureDevice(hdc_get_device(ui->comboBoxHD3->currentData().toInt()), 3); +} + +void +SettingsStorageControllers::on_pushButtonHD4_clicked() +{ + DeviceConfig::ConfigureDevice(hdc_get_device(ui->comboBoxHD4->currentData().toInt()), 4); +} + void SettingsStorageControllers::on_pushButtonCDInterface_clicked() { DeviceConfig::ConfigureDevice(cdrom_interface_get_device(ui->comboBoxCDInterface->currentData().toInt())); } -void -SettingsStorageControllers::on_pushButtonTertiaryIDE_clicked() -{ - DeviceConfig::ConfigureDevice(&ide_ter_device); -} - -void -SettingsStorageControllers::on_pushButtonQuaternaryIDE_clicked() -{ - DeviceConfig::ConfigureDevice(&ide_qua_device); -} - void SettingsStorageControllers::on_comboBoxSCSI1_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } + ui->pushButtonSCSI1->setEnabled(scsi_card_has_config(ui->comboBoxSCSI1->currentData().toInt()) > 0); } void SettingsStorageControllers::on_comboBoxSCSI2_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } + ui->pushButtonSCSI2->setEnabled(scsi_card_has_config(ui->comboBoxSCSI2->currentData().toInt()) > 0); } void SettingsStorageControllers::on_comboBoxSCSI3_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } + ui->pushButtonSCSI3->setEnabled(scsi_card_has_config(ui->comboBoxSCSI3->currentData().toInt()) > 0); } void SettingsStorageControllers::on_comboBoxSCSI4_currentIndexChanged(int index) { - if (index < 0) { + if (index < 0) return; - } + ui->pushButtonSCSI4->setEnabled(scsi_card_has_config(ui->comboBoxSCSI4->currentData().toInt()) > 0); } @@ -367,15 +385,3 @@ SettingsStorageControllers::on_pushButtonSCSI4_clicked() { DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI4->currentData().toInt()), 4); } - -void -SettingsStorageControllers::on_checkBoxLbaEnhancer_stateChanged(int arg1) -{ - ui->pushButtonConfigureLbaEnhancer->setEnabled(arg1 != 0); -} - -void -SettingsStorageControllers::on_pushButtonConfigureLbaEnhancer_clicked() -{ - DeviceConfig::ConfigureDevice(&lba_enhancer_device); -} diff --git a/src/qt/qt_settingsstoragecontrollers.hpp b/src/qt/qt_settingsstoragecontrollers.hpp index c50a94574..7ba862e0c 100644 --- a/src/qt/qt_settingsstoragecontrollers.hpp +++ b/src/qt/qt_settingsstoragecontrollers.hpp @@ -20,28 +20,29 @@ public slots: void onCurrentMachineChanged(int machineId); private slots: - void on_pushButtonSCSI4_clicked(); - void on_pushButtonSCSI3_clicked(); - void on_pushButtonSCSI2_clicked(); - void on_pushButtonSCSI1_clicked(); - void on_comboBoxSCSI4_currentIndexChanged(int index); - void on_comboBoxSCSI3_currentIndexChanged(int index); - void on_comboBoxSCSI2_currentIndexChanged(int index); - void on_comboBoxSCSI1_currentIndexChanged(int index); - void on_pushButtonQuaternaryIDE_clicked(); - void on_pushButtonTertiaryIDE_clicked(); - void on_pushButtonFD_clicked(); - void on_pushButtonHD_clicked(); - void on_pushButtonCDInterface_clicked(); - void on_checkBoxQuaternaryIDE_stateChanged(int arg1); - void on_checkBoxTertiaryIDE_stateChanged(int arg1); void on_comboBoxFD_currentIndexChanged(int index); - void on_comboBoxHD_currentIndexChanged(int index); + void on_pushButtonFD_clicked(); + + void on_comboBoxHD1_currentIndexChanged(int index); + void on_pushButtonHD1_clicked(); + void on_comboBoxHD2_currentIndexChanged(int index); + void on_pushButtonHD2_clicked(); + void on_comboBoxHD3_currentIndexChanged(int index); + void on_pushButtonHD3_clicked(); + void on_comboBoxHD4_currentIndexChanged(int index); + void on_pushButtonHD4_clicked(); + void on_comboBoxCDInterface_currentIndexChanged(int index); + void on_pushButtonCDInterface_clicked(); - void on_checkBoxLbaEnhancer_stateChanged(int arg1); - - void on_pushButtonConfigureLbaEnhancer_clicked(); + void on_comboBoxSCSI1_currentIndexChanged(int index); + void on_pushButtonSCSI1_clicked(); + void on_comboBoxSCSI2_currentIndexChanged(int index); + void on_pushButtonSCSI2_clicked(); + void on_comboBoxSCSI3_currentIndexChanged(int index); + void on_pushButtonSCSI3_clicked(); + void on_comboBoxSCSI4_currentIndexChanged(int index); + void on_pushButtonSCSI4_clicked(); private: Ui::SettingsStorageControllers *ui; diff --git a/src/qt/qt_settingsstoragecontrollers.ui b/src/qt/qt_settingsstoragecontrollers.ui index a167e5bc1..2d6fa9d32 100644 --- a/src/qt/qt_settingsstoragecontrollers.ui +++ b/src/qt/qt_settingsstoragecontrollers.ui @@ -29,13 +29,20 @@ - + - HD Controller: + FD Controller: - + + + + 30 + + + + Configure @@ -43,123 +50,158 @@ - - - FD Controller: - - - - - + CD-ROM Controller: - + 30 - + Configure - - - - - 0 - 0 - - - - 30 - - - - - - - Configure - - - - - - - 30 - - - - - - - Tertiary IDE Controller - - - - - - - Quaternary IDE Controller - - - - - - - false - - - Configure - - - - - - - false - - - Configure - - - - + - SCSI + Hard disk - - - + + + + + Controller 1: + + + + + + + + 0 + 0 + + + + 30 + + + + + Configure - - + + + + Controller 2: + + + + + + + + 0 + 0 + + + + 30 + + + + + Configure - + Controller 3: + + + + + 0 + 0 + + + + 30 + + + + + + + Configure + + + + + + + Controller 4: + + + + + + + + 0 + 0 + + + + 30 + + + + + + + Configure + + + + + + + + + + SCSI + + + + + + Controller 1: + + + @@ -180,6 +222,13 @@ + + + + Controller 2: + + + @@ -193,6 +242,20 @@ + + + + Configure + + + + + + + Controller 3: + + + @@ -206,6 +269,20 @@ + + + + Configure + + + + + + + Controller 4: + + + @@ -219,29 +296,8 @@ - - - - Controller 1: - - - - - - - Controller 2: - - - - - - - Controller 4: - - - - - + + Configure @@ -257,43 +313,6 @@ - - - - 0 - - - 0 - - - - - Vision Systems LBA Enhancer - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Configure - - - - - @@ -309,6 +328,29 @@ + + comboBoxFD + pushButtonFD + comboBoxCDInterface + pushButtonCDInterface + comboBoxHD1 + pushButtonHD1 + comboBoxHD2 + pushButtonHD2 + comboBoxHD3 + pushButtonHD3 + comboBoxHD4 + pushButtonHD4 + comboBoxSCSI1 + pushButtonSCSI1 + comboBoxSCSI2 + pushButtonSCSI2 + comboBoxSCSI3 + pushButtonSCSI3 + comboBoxSCSI4 + pushButtonSCSI4 + checkBoxCassette + diff --git a/src/qt/qt_styleoverride.cpp b/src/qt/qt_styleoverride.cpp index 0bade8fa6..adfae0734 100644 --- a/src/qt/qt_styleoverride.cpp +++ b/src/qt/qt_styleoverride.cpp @@ -22,6 +22,11 @@ #include #include +extern "C" { +#include <86box/86box.h> +#include <86box/plat.h> +} + #ifdef Q_OS_WINDOWS #include #ifndef DWMWA_USE_IMMERSIVE_DARK_MODE @@ -37,7 +42,7 @@ StyleOverride::styleHint( QStyleHintReturn *returnData) const { /* Disable using menu with alt key */ - if (hint == QStyle::SH_MenuBar_AltKeyNavigation) + if (!vmm_enabled && (!kbd_req_capture || mouse_capture) && (hint == QStyle::SH_MenuBar_AltKeyNavigation)) return 0; return QProxyStyle::styleHint(hint, option, widget, returnData); diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 5a6bda852..d4a257887 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -23,6 +23,7 @@ #include #include +#include #include "qt_mainwindow.hpp" #include "qt_machinestatus.hpp" @@ -49,7 +50,7 @@ extern "C" { #include <86box/cartridge.h> #include <86box/cassette.h> #include <86box/cdrom.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/mo.h> #include <86box/hdd.h> #include <86box/thread.h> @@ -122,6 +123,10 @@ plat_resize(int w, int h, int monitor_index) main_window->resizeContents(w, h); } +#if defined _WIN32 +extern HWND rw_hwnd; +#endif + void plat_mouse_capture(int on) { @@ -129,6 +134,26 @@ plat_mouse_capture(int on) return; main_window->setMouseCapture(on > 0 ? true : false); + +#if defined _WIN32 + if (on) { + QCursor cursor(Qt::BlankCursor); + + QApplication::setOverrideCursor(cursor); + QApplication::changeOverrideCursor(cursor); + + RECT rect; + + GetWindowRect(rw_hwnd, &rect); + + ClipCursor(&rect); + + } else { + ClipCursor(NULL); + + QApplication::restoreOverrideCursor(); + } +#endif } int @@ -237,6 +262,34 @@ ui_sb_set_ready(int ready) } } +void +ui_sb_update_icon_wp(int tag, int state) +{ + const auto temp = static_cast(tag); + const int category = static_cast(temp & 0xfffffff0); + const int item = tag & 0xf; + + switch (category) { + default: + break; + case SB_CASSETTE: + machine_status.cassette.write_prot = state > 0 ? true : false; + break; + case SB_FLOPPY: + machine_status.fdd[item].write_prot = state > 0 ? true : false; + break; + case SB_RDISK: + machine_status.rdisk[item].write_prot = state > 0 ? true : false; + break; + case SB_MO: + machine_status.mo[item].write_prot = state > 0 ? true : false; + break; + } + + if (main_window != nullptr) + main_window->updateStatusEmptyIcons(); +} + void ui_sb_update_icon_state(int tag, int state) { @@ -259,8 +312,8 @@ ui_sb_update_icon_state(int tag, int state) case SB_CDROM: machine_status.cdrom[item].empty = state > 0 ? true : false; break; - case SB_ZIP: - machine_status.zip[item].empty = state > 0 ? true : false; + case SB_RDISK: + machine_status.rdisk[item].empty = state > 0 ? true : false; break; case SB_MO: machine_status.mo[item].empty = state > 0 ? true : false; @@ -297,8 +350,8 @@ ui_sb_update_icon(int tag, int active) case SB_CDROM: machine_status.cdrom[item].active = active > 0 ? true : false; break; - case SB_ZIP: - machine_status.zip[item].active = active > 0 ? true : false; + case SB_RDISK: + machine_status.rdisk[item].active = active > 0 ? true : false; break; case SB_MO: machine_status.mo[item].active = active > 0 ? true : false; @@ -333,8 +386,8 @@ ui_sb_update_icon_write(int tag, int write) case SB_CDROM: machine_status.cdrom[item].write_active = write > 0 ? true : false; break; - case SB_ZIP: - machine_status.zip[item].write_active = write > 0 ? true : false; + case SB_RDISK: + machine_status.rdisk[item].write_active = write > 0 ? true : false; break; case SB_MO: machine_status.mo[item].write_active = write > 0 ? true : false; diff --git a/src/qt/qt_updatecheck.cpp b/src/qt/qt_updatecheck.cpp new file mode 100644 index 000000000..83e2b34d9 --- /dev/null +++ b/src/qt/qt_updatecheck.cpp @@ -0,0 +1,360 @@ +/* + * 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. + * + * Update check module + * + * + * + * Authors: cold-brewed + * + * Copyright 2024 cold-brewed + */ + +#include +#include +#include +#include +#include + +#include "qt_updatecheck.hpp" +#include "qt_downloader.hpp" +#include "qt_updatedetails.hpp" + +extern "C" { +#include <86box/version.h> +} + +UpdateCheck:: +UpdateCheck(const UpdateChannel channel, QObject *parent) : QObject(parent) +{ + updateChannel = channel; + currentVersion = getCurrentVersion(channel); +} + +UpdateCheck::~ +UpdateCheck() + = default; + +void +UpdateCheck::checkForUpdates() +{ + if (updateChannel == UpdateChannel::Stable) { + const auto githubDownloader = new Downloader(Downloader::DownloadLocation::Temp); + connect(githubDownloader, &Downloader::downloadCompleted, this, &UpdateCheck::githubDownloadComplete); + connect(githubDownloader, &Downloader::errorOccurred, this, &UpdateCheck::generalDownloadError); + githubDownloader->download(QUrl(githubReleaseApi), "github_releases.json"); + } else { + const auto jenkinsDownloader = new Downloader(Downloader::DownloadLocation::Temp); + connect(jenkinsDownloader, &Downloader::downloadCompleted, this, &UpdateCheck::jenkinsDownloadComplete); + connect(jenkinsDownloader, &Downloader::errorOccurred, this, &UpdateCheck::generalDownloadError); + jenkinsDownloader->download(jenkinsLatestNReleasesUrl(10), "jenkins_list.json"); + } +} + +void +UpdateCheck::jenkinsDownloadComplete(const QString &filename, const QVariant &varData) +{ + auto generalError = tr("Unable to determine release information"); + auto jenkinsReleaseListResult = parseJenkinsJson(filename); + auto latestVersion = 0; // NOLINT (Default value as a fallback) + + if(!jenkinsReleaseListResult.has_value() || jenkinsReleaseListResult.value().isEmpty()) { + generalDownloadError(generalError); + return; + } + const auto jenkinsReleaseList = jenkinsReleaseListResult.value(); + latestVersion = jenkinsReleaseListResult->first().buildNumber; + + // If we can't determine the local build (blank current version), always show an update as available. + // Callers can adjust accordingly. + // Otherwise, do a comparison with EMU_BUILD_NUM + bool updateAvailable = false; + bool upToDate = true; + if(currentVersion.isEmpty() || EMU_BUILD_NUM < latestVersion) { + updateAvailable = true; + upToDate = false; + } + + const auto updateResult = UpdateResult { + .channel = updateChannel, + .updateAvailable = updateAvailable, + .upToDate = upToDate, + .currentVersion = currentVersion, + .latestVersion = QString::number(latestVersion), + .githubInfo = {}, + .jenkinsInfo = jenkinsReleaseList, + }; + + emit updateCheckComplete(updateResult); +} + +void +UpdateCheck::generalDownloadError(const QString &error) +{ + emit updateCheckError(error); +} + +void +UpdateCheck::githubDownloadComplete(const QString &filename, const QVariant &varData) +{ + const auto generalError = tr("Unable to determine release information"); + const auto githubReleaseListResult = parseGithubJson(filename); + QString latestVersion = "0.0"; + if(!githubReleaseListResult.has_value() || githubReleaseListResult.value().isEmpty()) { + generalDownloadError(generalError); + } + auto githubReleaseList = githubReleaseListResult.value(); + // Warning: this check (using the tag name) relies on a consistent naming scheme: "v" + // where is the release number. For example, 4.2 from v4.2 as the tag name. + // Another option would be parsing the name field which is generally "86Box " but + // either option requires a consistent naming scheme. + latestVersion = githubReleaseList.first().tag_name.replace("v", ""); + for (const auto &release: githubReleaseList) { + qDebug().noquote().nospace() << release.name << ": " << release.html_url << " (" << release.created_at << ")"; + } + + // const auto updateDetails = new UpdateDetails(githubReleaseList, currentVersion); + bool updateAvailable = false; + bool upToDate = true; + if(currentVersion.isEmpty() || (versionCompare(currentVersion, latestVersion) < 0)) { + updateAvailable = true; + upToDate = false; + } + + const auto updateResult = UpdateResult { + .channel = updateChannel, + .updateAvailable = updateAvailable, + .upToDate = upToDate, + .currentVersion = currentVersion, + .latestVersion = latestVersion, + .githubInfo = githubReleaseList, + .jenkinsInfo = {}, + }; + + emit updateCheckComplete(updateResult); + +} + +QUrl +UpdateCheck::jenkinsLatestNReleasesUrl(const int &count) +{ + const auto urlPath = QString("https://ci.86box.net/job/86box/api/json?tree=builds[number,result,timestamp,changeSets[items[commitId,affectedPaths,author[fullName],msg,id]]]{0,%1}").arg(count); + return { urlPath }; +} + +QString +UpdateCheck::getCurrentVersion(const UpdateChannel &updateChannel) +{ + if (updateChannel == UpdateChannel::Stable) { + return {EMU_VERSION}; + } + // If EMU_BUILD_NUM is anything other than the default of zero it was set by the build process + if constexpr (EMU_BUILD_NUM != 0) { + return QString::number(EMU_BUILD_NUM); // NOLINT because EMU_BUILD_NUM is defined as 0 by default and is set at build time + } + // EMU_BUILD_NUM is not set, most likely a local build + return {}; // NOLINT (Having EMU_BUILD_NUM assigned to a default number throws off the linter) +} + +std::optional> +UpdateCheck::parseJenkinsJson(const QString &filename) +{ + QList releaseInfoList; + QFile json_file(filename); + if (!json_file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning() << "Couldn't open the json file: error" << json_file.error(); + return std::nullopt; + } + + const QString read_file = json_file.readAll(); + json_file.close(); + + const auto json_doc = QJsonDocument::fromJson(read_file.toUtf8()); + + if (json_doc.isNull()) { + qWarning("Failed to create QJsonDocument, possibly invalid JSON"); + return std::nullopt; + } + + if (!json_doc.isObject()) { + qWarning("JSON does not have the expected format (object in root), cannot continue"); + return std::nullopt; + } + + auto json_object = json_doc.object(); + + // The json contains multiple release + if(json_object.contains("builds") && json_object["builds"].isArray()) { + + QJsonArray builds = json_object["builds"].toArray(); + for (const auto &each_build: builds) { + if (auto build = parseJenkinsRelease(each_build.toObject()); build.has_value() && build.value().result == "SUCCESS") { + releaseInfoList.append(build.value()); + } + } + } else if(json_object.contains("changeSets") && json_object["changeSets"].isArray()) { + // The json contains only one release, as obtained by the lastSuccessfulBuild api + if (const auto build = parseJenkinsRelease(json_object); build.has_value()) { + releaseInfoList.append(build.value()); + } + } else { + qWarning("JSON is missing data or has invalid data, cannot continue"); + qDebug() << json_object; + return std::nullopt; + } + + return releaseInfoList; +} + +std::optional +UpdateCheck::parseJenkinsRelease(const QJsonObject &json) +{ + // The root should contain number, result, and timestamp. + if (!json.contains("number") || !json.contains("result") || !json.contains("timestamp")) { + return std::nullopt; + } + + auto releaseInfo = JenkinsReleaseInfo { + .buildNumber = json["number"].toInt(), + .result = json["result"].toString(), + .timestamp = static_cast(json["timestamp"].toDouble()) + }; + + // Overview + // Each build should contain a changeSets object with an array. Only the first element is needed. + // The first element should be an object containing an items object with an array. + // Each array element in the items object has information releated to the build. More or less: commit data + // In jq parlance it would be similar to `builds[].changeSets[0].items[]` + + // To break down the somewhat complicated if-init statement below: + // * Get the object for `changeSets` + // * Convert the value to array + // * Grab the first element in the array + // Proceed if + // * the element (first in changeSets) is an object that contains the key `items` + if (const auto changeSet = json["changeSets"].toArray().first(); changeSet.isObject() && changeSet.toObject().contains("items")) { + // Then proceed to process each `items` array element + for (const auto &item : changeSet.toObject()["items"].toArray()) { + auto itemObject = item.toObject(); + // Basic validation + if (!itemObject.contains("commitId") || !itemObject.contains("msg") || !itemObject.contains("affectedPaths")) { + return std::nullopt; + } + // Convert the paths for each commit to a string list + QStringList paths; + for (const auto &each_path : itemObject["affectedPaths"].toArray().toVariantList()) { + if (each_path.type() == QVariant::String) { + paths.append(each_path.toString()); + } + } + // Build the structure + const auto releaseItem = JenkinsChangeSetItem { + .buildId = itemObject["commitId"].toString(), + .author = itemObject["author"].toObject()["fullName"].toString(), + .message = itemObject["msg"].toString(), + .affectedPaths = paths, + }; + releaseInfo.changeSetItems.append(releaseItem); + } + } else { + qWarning("Could not parse release information, possibly invalid JSON"); + } + return releaseInfo; +} + +std::optional> +UpdateCheck::parseGithubJson(const QString &filename) +{ + QList releaseInfoList; + QFile json_file(filename); + if (!json_file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning("Couldn't open the json file: error %d", json_file.error()); + return std::nullopt; + } + + const QString read_file = json_file.readAll(); + json_file.close(); + + const auto json_doc = QJsonDocument::fromJson(read_file.toUtf8()); + + if (json_doc.isNull()) { + qWarning("Failed to create QJsonDocument, possibly invalid JSON"); + return std::nullopt; + } + + if (!json_doc.isArray()) { + qWarning("JSON does not have the expected format (array in root), cannot continue"); + return std::nullopt; + } + + auto release_array = json_doc.array(); + + for (const auto &each_release: release_array) { + if (auto release = parseGithubRelease(each_release.toObject()); release.has_value()) { + releaseInfoList.append(release.value()); + } + } + return releaseInfoList; +} +std::optional +UpdateCheck::parseGithubRelease(const QJsonObject &json) +{ + // Perform some basic validation + if (!json.contains("name") || !json.contains("tag_name") || !json.contains("html_url")) { + return std::nullopt; + } + + auto githubRelease = GithubReleaseInfo { + .name = json["name"].toString(), + .tag_name = json["tag_name"].toString(), + .html_url = json["html_url"].toString(), + .target_commitish = json["target_commitish"].toString(), + .created_at = json["created_at"].toString(), + .published_at = json["published_at"].toString(), + .body = json["body"].toString(), + }; + + return githubRelease; +} + +// A simple method to compare version numbers +// Should work for comparing x.y.z and x.y. Missing +// values (parts) will be treated as zeroes +int +UpdateCheck::versionCompare(const QString &version1, const QString &version2) +{ + // Split both + QStringList v1List = version1.split('.'); + QStringList v2List = version2.split('.'); + + // Out of the two versions get the maximum amount of "parts" + const int maxParts = std::max(v1List.size(), v2List.size()); + + // Initialize both with zeros + QVector v1Parts(maxParts, 0); + QVector v2Parts(maxParts, 0); + + for (int i = 0; i < v1List.size(); ++i) { + v1Parts[i] = v1List[i].toInt(); + } + + for (int i = 0; i < v2List.size(); ++i) { + v2Parts[i] = v2List[i].toInt(); + } + + for (int i = 0; i < maxParts; ++i) { + // First version is greater + if (v1Parts[i] > v2Parts[i]) + return 1; + // First version is less + if (v1Parts[i] < v2Parts[i]) + return -1; + } + // They are equal + return 0; +} diff --git a/src/qt/qt_updatecheck.hpp b/src/qt/qt_updatecheck.hpp new file mode 100644 index 000000000..2c04993fc --- /dev/null +++ b/src/qt/qt_updatecheck.hpp @@ -0,0 +1,104 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header for the update check module + * + * + * + * Authors: cold-brewed + * + * Copyright 2024 cold-brewed + */ + +#ifndef QT_UPDATECHECK_HPP +#define QT_UPDATECHECK_HPP + +#include +#include +#include +#include + +#include + +class UpdateCheck final : public QObject { + Q_OBJECT +public: + enum class UpdateChannel { + Stable, + CI, + }; + + struct JenkinsChangeSetItem { + QString buildId; // sha hash + QString author; // github username + QString message; // commit message + QStringList affectedPaths; // list of files in the change + }; + + struct JenkinsReleaseInfo { + int buildNumber = 0; + QString result; + qint64 timestamp = 0; + QList changeSetItems; + }; + + struct GithubReleaseInfo { + QString name; + QString tag_name; + QString html_url; + QString target_commitish; + QString created_at; + QString published_at; + QString body; + }; + + struct UpdateResult { + UpdateChannel channel; + bool updateAvailable = false; + bool upToDate = false; + QString currentVersion; + QString latestVersion; + QList githubInfo; + QList jenkinsInfo; + }; + + explicit UpdateCheck(UpdateChannel channel, QObject *parent = nullptr); + ~UpdateCheck() override; + void checkForUpdates(); + static int versionCompare(const QString &version1, const QString &version2); + [[nodiscard]] static QString getCurrentVersion(const UpdateChannel &updateChannel = UpdateChannel::Stable); + +signals: + // void updateCheckComplete(const UpdateCheck::UpdateChannel &channel, const QVariant &updateData); + void updateCheckComplete(const UpdateCheck::UpdateResult &result); + void updateCheckError(const QString &errorMsg); + +private: + UpdateChannel updateChannel = UpdateChannel::Stable; + + const QUrl githubReleaseApi = QUrl("https://api.github.com/repos/86box/86Box/releases"); + const QUrl jenkinsLatestApi = QUrl("https://ci.86box.net/job/86box/lastSuccessfulBuild/api/json"); + QString jenkinsLatestVersion; + QString currentVersion; + + static QUrl jenkinsLatestNReleasesUrl(const int &count); + + static std::optional> parseJenkinsJson(const QString &filename); + static std::optional parseJenkinsRelease(const QJsonObject &json); + + static std::optional> parseGithubJson(const QString &filename); + static std::optional parseGithubRelease(const QJsonObject &json); + + +private slots: + void jenkinsDownloadComplete(const QString &filename, const QVariant& varData); + void githubDownloadComplete(const QString &filename, const QVariant& varData); + void generalDownloadError(const QString &error); +}; + +#endif // QT_UPDATECHECK_HPP diff --git a/src/qt/qt_updatecheckdialog.cpp b/src/qt/qt_updatecheckdialog.cpp new file mode 100644 index 000000000..71db9f31b --- /dev/null +++ b/src/qt/qt_updatecheckdialog.cpp @@ -0,0 +1,90 @@ +/* + * 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. + * + * Update check dialog module + * + * + * + * Authors: cold-brewed + * + * Copyright 2024 cold-brewed + */ + +#include +#include + +#include "qt_updatecheckdialog.hpp" +#include "ui_qt_updatecheckdialog.h" +#include "qt_updatedetails.hpp" + +extern "C" { +#include <86box/version.h> +} + +UpdateCheckDialog:: +UpdateCheckDialog(const UpdateCheck::UpdateChannel channel, QWidget *parent) : QDialog(parent), ui(new Ui::UpdateCheckDialog), updateCheck(new UpdateCheck(channel)) +{ + ui->setupUi(this); + ui->statusLabel->setHidden(true); + this->setFixedSize(400, 130); + updateChannel = channel; + currentVersion = UpdateCheck::getCurrentVersion(updateChannel); + connect(updateCheck, &UpdateCheck::updateCheckError, [=](const QString &errorMsg) { + generalDownloadError(errorMsg); + }); + connect(updateCheck, &UpdateCheck::updateCheckComplete, this, &UpdateCheckDialog::downloadComplete); + + QTimer::singleShot(0, [this] { + updateCheck->checkForUpdates(); + }); +} + +UpdateCheckDialog::~ +UpdateCheckDialog() + = default; + +void +UpdateCheckDialog::generalDownloadError(const QString &error) const +{ + ui->progressBar->setMaximum(100); + ui->progressBar->setValue(100); + ui->statusLabel->setVisible(true); + const auto statusText = tr("There was an error checking for updates:\n\n%1\n\nPlease try again later.").arg(error); + ui->statusLabel->setText(statusText); + ui->buttonBox->setStandardButtons(QDialogButtonBox::Ok); +} + +void +UpdateCheckDialog::downloadComplete(const UpdateCheck::UpdateResult &result) +{ + if (result.upToDate) { + upToDate(); + return; + } + + const auto updateDetails = new UpdateDetails(result, this); + connect(updateDetails, &QDialog::accepted, [this] { + accept(); + }); + connect(updateDetails, &QDialog::rejected, [this] { + reject(); + }); + updateDetails->exec(); +} + +void +UpdateCheckDialog::upToDate() +{ + ui->titleLabel->setText(tr("Update check complete")); + ui->progressBar->setMaximum(100); + ui->progressBar->setValue(100); + ui->statusLabel->setVisible(true); + const auto statusText = tr("You are running the latest %1 version of 86Box: %2").arg(updateChannel == UpdateCheck::UpdateChannel::Stable ? "stable" : "beta", currentVersion); + ui->statusLabel->setText(statusText); + ui->buttonBox->setStandardButtons(QDialogButtonBox::Ok); +} diff --git a/src/qt/qt_updatecheckdialog.hpp b/src/qt/qt_updatecheckdialog.hpp new file mode 100644 index 000000000..0f1c0dfa8 --- /dev/null +++ b/src/qt/qt_updatecheckdialog.hpp @@ -0,0 +1,47 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header for the update check dialog module + * + * + * + * Authors: cold-brewed + * + * Copyright 2024 cold-brewed + */ + +#ifndef QT_UPDATECHECKDIALOG_HPP +#define QT_UPDATECHECKDIALOG_HPP + +#include + +#include + +namespace Ui { +class UpdateCheckDialog; +} + +class UpdateCheckDialog final : public QDialog { + Q_OBJECT +public: + explicit UpdateCheckDialog(UpdateCheck::UpdateChannel channel, QWidget *parent = nullptr); + ~UpdateCheckDialog() override; + +private: + Ui::UpdateCheckDialog *ui; + UpdateCheck::UpdateChannel updateChannel = UpdateCheck::UpdateChannel::Stable; + UpdateCheck *updateCheck; + QString currentVersion; + void upToDate(); + +private slots: + void downloadComplete(const UpdateCheck::UpdateResult &result); + void generalDownloadError(const QString &error) const; +}; + +#endif // QT_UPDATECHECKDIALOG_HPP diff --git a/src/qt/qt_updatecheckdialog.ui b/src/qt/qt_updatecheckdialog.ui new file mode 100644 index 000000000..c70ca8de2 --- /dev/null +++ b/src/qt/qt_updatecheckdialog.ui @@ -0,0 +1,106 @@ + + + UpdateCheckDialog + + + + 0 + 0 + 400 + 130 + + + + + 0 + 0 + + + + Update check + + + + + + + 0 + 0 + + + + Checking for updates.. + + + Qt::AlignCenter + + + + + + + 0 + + + -1 + + + + + + + Status text here + + + + + + + true + + + Qt::Horizontal + + + QDialogButtonBox::Cancel + + + + + + + + + buttonBox + accepted() + UpdateCheckDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + UpdateCheckDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/qt_updatedetails.cpp b/src/qt/qt_updatedetails.cpp new file mode 100644 index 000000000..f043c9504 --- /dev/null +++ b/src/qt/qt_updatedetails.cpp @@ -0,0 +1,110 @@ +/* + * 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. + * + * Update details module + * + * + * + * Authors: cold-brewed + * + * Copyright 2024 cold-brewed + */ + +#include "qt_updatedetails.hpp" +#include "ui_qt_updatedetails.h" + +#include +#include + + +UpdateDetails:: +UpdateDetails(const UpdateCheck::UpdateResult &updateResult, QWidget *parent) : QDialog(parent), ui(new Ui::UpdateDetails) +{ + ui->setupUi(this); + ui->updateTitle->setText("An update to 86Box is available!"); + QString currentVersionText; + QString releaseType = updateResult.channel == UpdateCheck::UpdateChannel::Stable ? tr("version") : tr("build"); + if(!updateResult.currentVersion.isEmpty()) { + currentVersionText = tr("You are currently running %1 %2. ").arg(releaseType, updateResult.currentVersion); + } + + const auto updateDetailsText = tr("%1 %2 is now available. %3Would you like to visit the download page?").arg(releaseType[0].toUpper() + releaseType.mid(1), updateResult.latestVersion, currentVersionText); + ui->updateDetails->setText(updateDetailsText); + + if(updateResult.channel == UpdateCheck::UpdateChannel::Stable) { + ui->updateText->setMarkdown(githubUpdateToMarkdown(updateResult.githubInfo)); + } else { + ui->updateText->setMarkdown(jenkinsUpdateToMarkdown(updateResult.jenkinsInfo)); + } + + const auto downloadButton = new QPushButton(tr("Visit download page")); + ui->buttonBox->addButton(downloadButton, QDialogButtonBox::AcceptRole); + // Override accepted to mean "I want to visit the download page" + connect(ui->buttonBox, &QDialogButtonBox::accepted, [updateResult] { + visitDownloadPage(updateResult.channel); + }); + const auto logo = QPixmap(":/assets/86box.png").scaled(QSize(64, 64), Qt::KeepAspectRatio, Qt::SmoothTransformation); + + ui->icon->setPixmap(logo); +} + +UpdateDetails::~ +UpdateDetails() + = default; + +QString +UpdateDetails::jenkinsUpdateToMarkdown(const QList &releaseInfoList) +{ + QStringList fullText; + for (const auto &update : releaseInfoList) { + fullText.append(QString("### Build %1").arg(update.buildNumber)); + fullText.append("Changes:"); + for (const auto &item : update.changeSetItems) { + fullText.append(QString("* %1").arg(item.message)); + } + fullText.append("\n\n\n---\n\n\n"); + } + // pop off the last hr + fullText.removeLast(); + // return fullText.join("\n\n---\n\n"); + return fullText.join("\n"); +} + +QString +UpdateDetails::githubUpdateToMarkdown(const QList &releaseInfoList) +{ + // The github release info can be rather large so we'll only + // display the most recent one + QList singleRelease; + if (!releaseInfoList.isEmpty()) { + singleRelease.append(releaseInfoList.first()); + } + QStringList fullText; + for (const auto &release : singleRelease) { + fullText.append(QString("#### %1").arg(release.name)); + // Github body text should already be in markdown and can just + // be placed here as-is + fullText.append(release.body); + fullText.append("\n\n\n---\n\n\n"); + } + // pop off the last hr + fullText.removeLast(); + return fullText.join("\n"); +} +void +UpdateDetails::visitDownloadPage(const UpdateCheck::UpdateChannel &channel) +{ + switch (channel) { + case UpdateCheck::UpdateChannel::Stable: + QDesktopServices::openUrl(QUrl("https://github.com/86Box/86Box/releases/latest")); + break; + case UpdateCheck::UpdateChannel::CI: + QDesktopServices::openUrl(QUrl("https://ci.86box.net/job/86Box/lastSuccessfulBuild/artifact/")); + break; + } +} diff --git a/src/qt/qt_updatedetails.hpp b/src/qt/qt_updatedetails.hpp new file mode 100644 index 000000000..8c3528e11 --- /dev/null +++ b/src/qt/qt_updatedetails.hpp @@ -0,0 +1,43 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header for the update details module + * + * + * + * Authors: cold-brewed + * + * Copyright 2024 cold-brewed + */ + +#ifndef QT_UPDATEDETAILS_HPP +#define QT_UPDATEDETAILS_HPP + +#include +#include +#include "qt_updatecheck.hpp" + +namespace Ui { +class UpdateDetails; +} + +class UpdateDetails final : public QDialog { + Q_OBJECT +public: + explicit UpdateDetails(const UpdateCheck::UpdateResult &updateResult, QWidget *parent = nullptr); + ~UpdateDetails() override; +private: + Ui::UpdateDetails *ui; + static QString jenkinsUpdateToMarkdown(const QList &releaseInfoList); + static QString githubUpdateToMarkdown(const QList &releaseInfoList); +private slots: + static void visitDownloadPage(const UpdateCheck::UpdateChannel &channel); +}; + + +#endif // QT_UPDATEDETAILS_HPP diff --git a/src/qt/qt_updatedetails.ui b/src/qt/qt_updatedetails.ui new file mode 100644 index 000000000..7798896a9 --- /dev/null +++ b/src/qt/qt_updatedetails.ui @@ -0,0 +1,192 @@ + + + UpdateDetails + + + + 0 + 0 + 700 + 500 + + + + + 600 + 400 + + + + 86Box Update + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 12 + + + 12 + + + 12 + + + 0 + + + + + + 0 + 0 + + + + + 32 + 0 + + + + + 64 + 16777215 + + + + + + + false + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Title + + + + + + + Details + + + true + + + + + + + Release notes: + + + + + + + true + + + true + + + false + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel + + + + + + + + + buttonBox + accepted() + UpdateDetails + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + UpdateDetails + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/qt_util.cpp b/src/qt/qt_util.cpp index 0c78c2f5e..bc9b9f1f8 100644 --- a/src/qt/qt_util.cpp +++ b/src/qt/qt_util.cpp @@ -92,13 +92,41 @@ DlgFilter(std::initializer_list extensions, bool last) return " (" % temp.join(' ') % ")" % (!last ? ";;" : ""); } +QString +DlgFilter(QStringList extensions, bool last) +{ + QStringList temp; + + for (auto ext : extensions) { +#ifdef Q_OS_UNIX + if (ext == "*") { + temp.append("*"); + continue; + } + temp.append("*." % ext.toUpper()); +#endif + temp.append("*." % ext); + } + +#ifdef Q_OS_UNIX + temp.removeDuplicates(); +#endif + return " (" % temp.join(' ') % ")" % (!last ? ";;" : ""); +} + + QString currentUuid() { - auto configPath = QFileInfo(cfg_path).dir().canonicalPath(); - if(!configPath.endsWith("/")) { - configPath.append("/"); + return generateUuid(QString(cfg_path)); +} + +QString generateUuid(const QString &path) +{ + auto dirPath = QFileInfo(path).dir().canonicalPath(); + if(!dirPath.endsWith("/")) { + dirPath.append("/"); } - return QUuid::createUuidV5(QUuid{}, configPath).toString(QUuid::WithoutBraces); + return QUuid::createUuidV5(QUuid{}, dirPath).toString(QUuid::WithoutBraces); } bool compareUuid() diff --git a/src/qt/qt_util.hpp b/src/qt/qt_util.hpp index 9432610b6..de3457a88 100644 --- a/src/qt/qt_util.hpp +++ b/src/qt/qt_util.hpp @@ -11,12 +11,14 @@ namespace util { static constexpr auto UUID_MIN_LENGTH = 36; /* Creates extension list for qt filedialog */ QString DlgFilter(std::initializer_list extensions, bool last = false); +QString DlgFilter(QStringList extensions, bool last = false); /* Returns screen the widget is on */ QScreen *screenOfWidget(QWidget *widget); #ifdef Q_OS_WINDOWS void setWin11RoundedCorners(WId hwnd, bool enable); #endif QString currentUuid(); +QString generateUuid(const QString &path); void storeCurrentUuid(); bool compareUuid(); void generateNewMacAdresses(); diff --git a/src/qt/qt_vmmanager_addmachine.cpp b/src/qt/qt_vmmanager_addmachine.cpp new file mode 100644 index 000000000..55ff7274b --- /dev/null +++ b/src/qt/qt_vmmanager_addmachine.cpp @@ -0,0 +1,382 @@ +/* +* 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. +* +* 86Box VM manager add machine wizard +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "qt_vmmanager_addmachine.hpp" + +extern "C" { +#include <86box/86box.h> +} + +// Implementation note: There are several classes in this file: +// One for the main Wizard class and one for each page of the wizard + +VMManagerAddMachine:: +VMManagerAddMachine(QWidget *parent) : QWizard(parent) +{ + setPage(Page_Intro, new IntroPage); + setPage(Page_WithExistingConfig, new WithExistingConfigPage); + setPage(Page_NameAndLocation, new NameAndLocationPage); + setPage(Page_Conclusion, new ConclusionPage); + + // Need to create a better image + // QPixmap originalPixmap(":/assets/86box.png"); + // QPixmap scaledPixmap = originalPixmap.scaled(150, 150, Qt::KeepAspectRatio); + QPixmap wizardPixmap(":/assets/86box-wizard.png"); + +#ifndef Q_OS_MACOS + setWizardStyle(ModernStyle); + // setPixmap(LogoPixmap, scaledPixmap); + // setPixmap(LogoPixmap, wizardPixmap); + // setPixmap(WatermarkPixmap, scaledPixmap); + setPixmap(WatermarkPixmap, wizardPixmap); +#else + // macos + // setPixmap(BackgroundPixmap, scaledPixmap); + setPixmap(BackgroundPixmap, wizardPixmap); +#endif + + // Wizard wants to resize based on image. This keeps the size + setMinimumSize(size()); + setOption(HaveHelpButton, false); + // setPixmap(LogoPixmap, QPixmap(":/settings/qt/icons/86Box-gray.ico")); + +#if 0 + connect(this, &QWizard::helpRequested, this, &VMManagerAddMachine::showHelp); +#endif + + setWindowTitle(tr("Add new system wizard")); +} + +#if 0 +void +VMManagerAddMachine::showHelp() +{ + // TBD + static QString lastHelpMessage; + + QString message; + + // Help will depend on the current page + switch (currentId()) { + case Page_Intro: + message = tr("This is the into page."); + break; + default: + message = tr("No help has been added yet, you're on your own."); + break; + } + + if (lastHelpMessage == message) { + message = tr("Did you click help twice?"); + } + + QMessageBox::information(this, tr("Add new system wizard help"), message); + lastHelpMessage = message; +} +#endif + +IntroPage:: +IntroPage(QWidget *parent) +{ + setTitle(tr("Introduction")); + + setPixmap(QWizard::WatermarkPixmap, QPixmap(":/assets/qt/assets/86box.png")); + + topLabel = new QLabel(tr("This will help you add a new system to 86Box.")); + // topLabel = new QLabel(tr("This will help you add a new system to 86Box.\n\n Choose \"New configuration\" if you'd like to create a new machine.\n\nChoose \"Use existing configuration\" if you'd like to paste in an existing configuration from elsewhere.")); + topLabel->setWordWrap(true); + + newConfigRadioButton = new QRadioButton(tr("New configuration")); + // auto newDescription = new QLabel(tr("Choose this option to start with a fresh configuration.")); + existingConfigRadioButton = new QRadioButton(tr("Use existing configuraion")); + // auto existingDescription = new QLabel(tr("Use this option if you'd like to paste in the configuration file from an existing system.")); + newConfigRadioButton->setChecked(true); + + const auto layout = new QVBoxLayout(); + layout->addWidget(topLabel); + layout->addWidget(newConfigRadioButton); + // layout->addWidget(newDescription); + layout->addWidget(existingConfigRadioButton); + // layout->addWidget(existingDescription); + + setLayout(layout); +} + +int +IntroPage::nextId() const +{ + if (newConfigRadioButton->isChecked()) { + return VMManagerAddMachine::Page_NameAndLocation; + } else { + return VMManagerAddMachine::Page_WithExistingConfig; + } +} + +WithExistingConfigPage:: +WithExistingConfigPage(QWidget *parent) +{ + setTitle(tr("Use existing configuration")); + + const auto topLabel = new QLabel(tr("Paste the contents of the existing configuration file into the box below.")); + topLabel->setWordWrap(true); + + existingConfiguration = new QPlainTextEdit(); + const auto monospaceFont = new QFont(); +#ifdef Q_OS_WINDOWS + monospaceFont->setFamily("Consolas"); +#elif defined(Q_OS_MACOS) + monospaceFont->setFamily("Menlo"); +#else + monospaceFont->setFamily("Monospace"); +#endif + monospaceFont->setStyleHint(QFont::Monospace); + monospaceFont->setFixedPitch(true); + existingConfiguration->setFont(*monospaceFont); + connect(existingConfiguration, &QPlainTextEdit::textChanged, this, &WithExistingConfigPage::completeChanged); + registerField("existingConfiguration*", this, "configuration"); + + const auto layout = new QVBoxLayout(); + layout->addWidget(topLabel); + layout->addWidget(existingConfiguration); + const auto loadFileButton = new QPushButton(); + const auto loadFileLabel = new QLabel(tr("Load configuration from file")); + const auto hLayout = new QHBoxLayout(); + loadFileButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_FileIcon)); + loadFileButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + connect(loadFileButton, &QPushButton::clicked, this, &WithExistingConfigPage::chooseExistingConfigFile); + hLayout->addWidget(loadFileButton); + hLayout->addWidget(loadFileLabel); + layout->addLayout(hLayout); + setLayout(layout); +} + +void +WithExistingConfigPage::chooseExistingConfigFile() +{ + // TODO: FIXME: This is using the CLI arg and needs to instead use a proper variable + const auto startDirectory = QString(vmm_path); + const auto selectedConfigFile = QFileDialog::getOpenFileName(this, tr("Choose configuration file"), + startDirectory, + tr("86Box configuration files (86box.cfg)")); + // Empty value means the dialog was canceled + if (!selectedConfigFile.isEmpty()) { + QFile configFile(selectedConfigFile); + if (!configFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + QMessageBox::critical(this, tr("Configuration read failed"), tr("Unable to open the selected configuration file for reading: %1").arg(configFile.errorString())); + return; + } + const QString configFileContents = configFile.readAll(); + existingConfiguration->setPlainText(configFileContents); + configFile.close(); + emit completeChanged(); + } +} + +QString +WithExistingConfigPage::configuration() const +{ + return existingConfiguration->toPlainText(); +} +void +WithExistingConfigPage::setConfiguration(const QString &configuration) +{ + if (configuration != existingConfiguration->toPlainText()) { + existingConfiguration->setPlainText(configuration); + emit configurationChanged(configuration); + } +} + +int +WithExistingConfigPage::nextId() const +{ + return VMManagerAddMachine::Page_NameAndLocation; +} + +bool +WithExistingConfigPage::isComplete() const +{ + return !existingConfiguration->toPlainText().isEmpty(); +} + +NameAndLocationPage:: +NameAndLocationPage(QWidget *parent) +{ + setTitle(tr("System name and location")); + +#if defined(_WIN32) + dirValidate = QRegularExpression(R"(^[^\\/:*?"<>|]+$)"); +#elif defined(__APPLE__) + dirValidate = QRegularExpression(R"(^[^/:]+$)"); +#else + dirValidate = QRegularExpression(R"(^[^/]+$)"); +#endif + + const auto topLabel = new QLabel(tr("Enter the name of the system and choose the location")); + topLabel->setWordWrap(true); + + const auto chooseDirectoryButton = new QPushButton(); + chooseDirectoryButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_DirIcon)); + + const auto systemNameLabel = new QLabel(tr("System Name")); + systemName = new QLineEdit(); + // Special event filter to override enter key + systemName->installEventFilter(this); + registerField("systemName*", systemName); + systemNameValidation = new QLabel(); + + const auto systemLocationLabel = new QLabel(tr("System Location")); + systemLocation = new QLineEdit(); + // TODO: FIXME: This is using the CLI arg and needs to instead use a proper variable + systemLocation->setText(QDir::toNativeSeparators(vmm_path)); + registerField("systemLocation*", systemLocation); + systemLocationValidation = new QLabel(); + systemLocationValidation->setWordWrap(true); + + const auto layout = new QGridLayout(); + layout->addWidget(topLabel, 0, 0, 1, -1); + // Spacer row + layout->setRowMinimumHeight(1, 20); + layout->addWidget(systemNameLabel, 2, 0); + layout->addWidget(systemName, 2, 1); + // Validation text, appears only as necessary + layout->addWidget(systemNameValidation, 3, 0, 1, -1); + // Set height on validation because it may not always be present + layout->setRowMinimumHeight(3, 20); + + // Another spacer + layout->setRowMinimumHeight(4, 20); + layout->addWidget(systemLocationLabel, 5, 0); + layout->addWidget(systemLocation, 5, 1); + layout->addWidget(chooseDirectoryButton, 5, 2); + // Validation text + layout->addWidget(systemLocationValidation, 6, 0, 1, -1); + layout->setRowMinimumHeight(6, 20); + + setLayout(layout); + + + connect(chooseDirectoryButton, &QPushButton::clicked, this, &NameAndLocationPage::chooseDirectoryLocation); +} + +int +NameAndLocationPage::nextId() const +{ + return VMManagerAddMachine::Page_Conclusion; +} + +void +NameAndLocationPage::chooseDirectoryLocation() +{ + // TODO: FIXME: This is pulling in the CLI directory! Needs to be set properly elsewhere + const auto directory = QFileDialog::getExistingDirectory(this, "Choose directory", QDir(vmm_path).path()); + systemLocation->setText(QDir::toNativeSeparators(directory)); + emit completeChanged(); +} +bool +NameAndLocationPage::isComplete() const +{ + bool nameValid = false; + bool locationValid = false; + // return true if complete + if (systemName->text().isEmpty()) { + systemNameValidation->setText(tr("Please enter a system name")); + } else if (!systemName->text().contains(dirValidate)) { + systemNameValidation->setText(tr("System name cannot contain certain characters")); + } else if (const QDir newDir = QDir::cleanPath(systemLocation->text() + "/" + systemName->text()); newDir.exists()) { + systemNameValidation->setText(tr("System name already exists")); + } else { + systemNameValidation->clear(); + nameValid = true; + } + + if (systemLocation->text().isEmpty()) { + systemLocationValidation->setText(tr("Please enter a directory for the system")); + } else if (const auto dir = QDir(systemLocation->text()); !dir.exists()) { + systemLocationValidation->setText(tr("Directory does not exist")); + } else { + systemLocationValidation->setText("A new directory for the system will be created in the selected directory above"); + locationValid = true; + } + + return nameValid && locationValid; +} +bool +NameAndLocationPage::eventFilter(QObject *watched, QEvent *event) +{ + // Override the enter key to hit the next wizard button + // if the validator (isComplete) is satisfied + if (event->type() == QEvent::KeyPress) { + const auto keyEvent = dynamic_cast(event); + if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) { + // Only advance if the validator is satisfied (isComplete) + if(const auto wizard = qobject_cast(this->wizard())) { + if (wizard->currentPage()->isComplete()) { + wizard->next(); + } + } + // Discard the key event + return true; + } + } + return QWizardPage::eventFilter(watched, event); +} + +ConclusionPage:: +ConclusionPage(QWidget *parent) +{ + setTitle(tr("Complete")); + + topLabel = new QLabel(tr("The wizard will now launch the configuration for the new system.")); + topLabel->setWordWrap(true); + + const auto systemNameLabel = new QLabel(tr("System name:")); + systemNameLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + systemName = new QLabel(); + const auto systemLocationLabel = new QLabel(tr("System location:")); + systemLocationLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + systemLocation = new QLabel(); + + const auto layout = new QGridLayout(); + layout->addWidget(topLabel, 0, 0, 1, -1); + layout->setRowMinimumHeight(1, 20); + layout->addWidget(systemNameLabel, 2, 0); + layout->addWidget(systemName, 2, 1); + layout->addWidget(systemLocationLabel, 3, 0); + layout->addWidget(systemLocation, 3, 1); + + setLayout(layout); +} + +// initializePage() runs after the page has been created with the constructor +void +ConclusionPage::initializePage() +{ + const auto finalPath = QDir::cleanPath(field("systemLocation").toString() + "/" + field("systemName").toString()); + const auto nativePath = QDir::toNativeSeparators(finalPath); + const auto systemNameDisplay = field("systemName").toString(); + + systemName->setText(systemNameDisplay); + systemLocation->setText(nativePath); +} diff --git a/src/qt/qt_vmmanager_addmachine.hpp b/src/qt/qt_vmmanager_addmachine.hpp new file mode 100644 index 000000000..6ba1a53ce --- /dev/null +++ b/src/qt/qt_vmmanager_addmachine.hpp @@ -0,0 +1,117 @@ +/* +* 86Box A hypervisor and IBM PC system emulator that specializes in +* running old operating systems and software designed for IBM +* PC systems and compatibles from 1981 through fairly recent +* system designs based on the PCI bus. +* +* This file is part of the 86Box distribution. +* +* Header for 86Box VM manager add machine wizard +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#ifndef QT_VMMANAGER_ADDMACHINE_H +#define QT_VMMANAGER_ADDMACHINE_H + +#include +#include +#include +#include +#include +#include + +// Implementation note: There are several classes in this header: +// One for the main Wizard class and one for each page of the wizard + +class VMManagerAddMachine final : public QWizard { + Q_OBJECT + +public: + enum { + Page_Intro, + Page_Fresh, + Page_WithExistingConfig, + Page_NameAndLocation, + Page_Conclusion + }; + + explicit VMManagerAddMachine(QWidget *parent = nullptr); + +#if 0 +private slots: + void showHelp(); +#endif +}; + +class IntroPage : public QWizardPage { + Q_OBJECT + +public: + explicit IntroPage(QWidget *parent = nullptr); + [[nodiscard]] int nextId() const override; + +private: + QLabel *topLabel; + QRadioButton *newConfigRadioButton; + QRadioButton *existingConfigRadioButton; +}; + +class WithExistingConfigPage final : public QWizardPage { + Q_OBJECT + Q_PROPERTY(QString configuration READ configuration WRITE setConfiguration NOTIFY configurationChanged) + +public: + explicit WithExistingConfigPage(QWidget *parent = nullptr); + // These extra functions are required to register QPlainTextEdit fields + [[nodiscard]] QString configuration() const; + void setConfiguration(const QString &configuration); +signals: + void configurationChanged(const QString &configuration); +private: + QPlainTextEdit *existingConfiguration; +private slots: + void chooseExistingConfigFile(); +protected: + [[nodiscard]] int nextId() const override; + [[nodiscard]] bool isComplete() const override; + +}; + +class NameAndLocationPage final : public QWizardPage { + Q_OBJECT + +public: + explicit NameAndLocationPage(QWidget *parent = nullptr); + [[nodiscard]] int nextId() const override; +private: + QLineEdit *systemName; + QLineEdit *systemLocation; + QLabel *systemNameValidation; + QLabel *systemLocationValidation; + QRegularExpression dirValidate; +private slots: + void chooseDirectoryLocation(); +protected: + [[nodiscard]] bool isComplete() const override; + bool eventFilter(QObject *watched, QEvent *event) override; + +}; + +class ConclusionPage final : public QWizardPage { + Q_OBJECT +public: + explicit ConclusionPage(QWidget *parent = nullptr); +private: + QLabel *topLabel; + QLabel *systemName; + QLabel *systemLocation; +protected: + void initializePage() override; +}; + +#endif // QT_VMMANAGER_ADDMACHINE_H \ No newline at end of file diff --git a/src/qt/qt_vmmanager_clientsocket.cpp b/src/qt/qt_vmmanager_clientsocket.cpp new file mode 100644 index 000000000..ffe4fb5f7 --- /dev/null +++ b/src/qt/qt_vmmanager_clientsocket.cpp @@ -0,0 +1,255 @@ +/* +* 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. +* +* 86Box VM manager client socket module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#include "qt_vmmanager_clientsocket.hpp" +#include "qt_vmmanager_protocol.hpp" +#include +#include +#include + +extern "C" { +#include "86box/plat.h" +} + +VMManagerClientSocket::VMManagerClientSocket(QObject* obj) : server_connected(false) +{ + socket = new QLocalSocket; + +} + +void +VMManagerClientSocket::dataReady() +{ + // emit signal? + QDataStream stream(socket); + stream.setVersion(QDataStream::Qt_5_7); + QByteArray jsonData; + for (;;) { + // start a transaction + stream.startTransaction(); + // try to read the data + stream >> jsonData; + if (stream.commitTransaction()) { + // first try to successfully read some data + // need to also make sure it's valid json + QJsonParseError parse_error{}; + // try to create a document with the data received + const QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parse_error); + if (parse_error.error == QJsonParseError::NoError) { + // the data received was valid json + if (jsonDoc.isObject()) { + // and is a valid json object + // parse the json + jsonReceived(jsonDoc.object()); + } + } + // If the received data isn't valid json, + // loop and try to read more if available + } else { + // read failed, socket is reverted to its previous state (before the transaction) + // Exit the loop and wait for more data to become available + break; + } + } + +} + +bool +VMManagerClientSocket::IPCConnect(const QString &server) +{ + server_name = server; + connect(socket, &QLocalSocket::connected, this, &VMManagerClientSocket::connected); + connect(socket, &QLocalSocket::disconnected, this, &VMManagerClientSocket::disconnected); + connect(socket, &QLocalSocket::errorOccurred, this, &VMManagerClientSocket::connectionError); + connect(socket, &QLocalSocket::readyRead, this, &VMManagerClientSocket::dataReady); + + socket->connectToServer(server_name); + + if(!socket->isValid()) { + qInfo("Could not connect to server: %s", qPrintable(socket->errorString())); + return false; + } + + qInfo("Connection Successful"); + return true; +} + +void +VMManagerClientSocket::connected() const +{ + // TODO: signal + qDebug("Connected to %s", qPrintable(server_name)); +} + +void +VMManagerClientSocket::disconnected() const +{ + // TODO: signal + qDebug("Disconnected from %s", qPrintable(server_name)); +} + +void +VMManagerClientSocket::sendMessage(const VMManagerProtocol::ClientMessage protocol_message) const +{ + sendMessageFull(protocol_message, QStringList(), QJsonObject()); +} + +void +VMManagerClientSocket::sendMessageWithList(const VMManagerProtocol::ClientMessage protocol_message, const QStringList &list) const +{ + sendMessageFull(protocol_message, list, QJsonObject()); +} + +void +VMManagerClientSocket::sendMessageWithObject(const VMManagerProtocol::ClientMessage protocol_message, const QJsonObject &json) const +{ + sendMessageFull(protocol_message, QStringList(), json); +} + +void +VMManagerClientSocket::sendMessageFull(const VMManagerProtocol::ClientMessage protocol_message, const QStringList &list, const QJsonObject &json) const +{ + QDataStream clientStream(socket); + clientStream.setVersion(QDataStream::Qt_5_7); + auto packet = new VMManagerProtocol(VMManagerProtocol::Sender::Client); + auto jsonMessage = packet->protocolClientMessage(protocol_message); + if (!list.isEmpty()) { + jsonMessage["list"] = QJsonArray::fromStringList(list); + } + // TODO: Add the logic for including objects + if(!json.isEmpty()) { + jsonMessage["params"] = json; + } + clientStream << QJsonDocument(jsonMessage).toJson(QJsonDocument::Compact); +} + +void +VMManagerClientSocket::jsonReceived(const QJsonObject &json) +{ + // The serialization portion has already validated the message as json. + // Ensure it has the required fields + if (!VMManagerProtocol::hasRequiredFields(json)) { + // TODO: Error handling of some sort, emit signals + qDebug("Invalid message received from client: required fields missing. Object:"); + qDebug() << json; + return; + } + // qDebug() << Q_FUNC_INFO << json; + + // Parsing happens here. When adding new types, make sure to first add them + // to VMManagerProtocol::ManagerMessage and then add it to the list here. + // If a signal needs to be emitted, add that as well and connect to slots + // as appropriate. + + switch (VMManagerProtocol::getManagerMessageType(json)) { + case VMManagerProtocol::ManagerMessage::Pause: + qDebug("Pause command received from manager"); + emit pause(); + break; + case VMManagerProtocol::ManagerMessage::ResetVM: + qDebug("Reset VM command received from manager"); + emit resetVM(); + break; + case VMManagerProtocol::ManagerMessage::ShowSettings: + qDebug("Show settings command received from manager"); + emit showsettings(); + break; + case VMManagerProtocol::ManagerMessage::CtrlAltDel: + qDebug("CtrlAltDel command received from manager"); + emit ctrlaltdel(); + break; + case VMManagerProtocol::ManagerMessage::RequestShutdown: + qDebug("RequestShutdown command received from manager"); + emit request_shutdown(); + break; + case VMManagerProtocol::ManagerMessage::ForceShutdown: + qDebug("ForceShutdown command received from manager"); + emit force_shutdown(); + break; + case VMManagerProtocol::ManagerMessage::RequestStatus: + qDebug("Status request command received from manager"); + break; + default: + qDebug("Unknown client message type received:"); + qDebug() << json; + break; + } +} + +void +VMManagerClientSocket::connectionError(const QLocalSocket::LocalSocketError socketError) +{ + qInfo("A connection error has occurred: "); + switch (socketError) { + case QLocalSocket::ServerNotFoundError: + qInfo("Server not found"); + break; + case QLocalSocket::ConnectionRefusedError: + qInfo("Connection refused"); + break; + case QLocalSocket::PeerClosedError: + qInfo("Peer closed"); + break; + default: + qInfo() << "QLocalSocket::LocalSocketError " << socketError; + break; + } +} + +bool +VMManagerClientSocket::eventFilter(QObject *obj, QEvent *event) +{ + if (socket->state() == QLocalSocket::ConnectedState) { + VMManagerProtocol::RunningState running_state; + if (event->type() == QEvent::WindowBlocked) { + running_state = dopause ? VMManagerProtocol::RunningState::PausedWaiting : VMManagerProtocol::RunningState::RunningWaiting; + clientRunningStateChanged(running_state); + window_blocked = true; + } else if (event->type() == QEvent::WindowUnblocked) { + window_blocked = false; + running_state = dopause ? VMManagerProtocol::RunningState::Paused : VMManagerProtocol::RunningState::Running; + clientRunningStateChanged(running_state); + } + } + return QObject::eventFilter(obj, event); +} + +void +VMManagerClientSocket::sendWinIdMessage(WId id) +{ + QJsonObject extra_object; + extra_object["params"] = static_cast(id); + sendMessageWithObject(VMManagerProtocol::ClientMessage::WinIdMessage, extra_object); +} + +void +VMManagerClientSocket::clientRunningStateChanged(VMManagerProtocol::RunningState state) const +{ + QJsonObject extra_object; + if ((state == VMManagerProtocol::RunningState::Paused + || state == VMManagerProtocol::RunningState::Running) && window_blocked) { + state = (state == VMManagerProtocol::RunningState::Paused) ? VMManagerProtocol::RunningState::PausedWaiting : VMManagerProtocol::RunningState::RunningWaiting; + } + extra_object["status"] = static_cast(state); + sendMessageWithObject(VMManagerProtocol::ClientMessage::RunningStateChanged, extra_object); +} + +void +VMManagerClientSocket::configurationChanged() const +{ + sendMessage(VMManagerProtocol::ClientMessage::ConfigurationChanged); +} diff --git a/src/qt/qt_vmmanager_clientsocket.hpp b/src/qt/qt_vmmanager_clientsocket.hpp new file mode 100644 index 000000000..50657a27b --- /dev/null +++ b/src/qt/qt_vmmanager_clientsocket.hpp @@ -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. +* +* Header file for 86Box VM manager client socket module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#ifndef QT_VMMANAGER_CLIENTSOCKET_HPP +#define QT_VMMANAGER_CLIENTSOCKET_HPP + +#include "qt_vmmanager_protocol.hpp" +#include +#include +#include +#include + +class VMManagerClientSocket final : public QObject { + Q_OBJECT + +public: + explicit VMManagerClientSocket(QObject* object = nullptr); + bool IPCConnect(const QString &server); + + void sendWinIdMessage(WId id); + +signals: + void pause(); + void ctrlaltdel(); + void showsettings(); + void resetVM(); + void request_shutdown(); + void force_shutdown(); + void dialogstatus(bool open); + +public slots: + void clientRunningStateChanged(VMManagerProtocol::RunningState state) const; + void configurationChanged() const; + +private: + QString server_name; + QLocalSocket *socket; + bool server_connected; + bool window_blocked = false; + void connected() const; + void disconnected() const; + static void connectionError(QLocalSocket::LocalSocketError socketError); + + // Main convenience send function + void sendMessage(VMManagerProtocol::ClientMessage protocol_message) const; + // Send message with optional params array convenience function + void sendMessageWithList(VMManagerProtocol::ClientMessage protocol_message, const QStringList &list) const; + // Send message with optional json object convenience function + void sendMessageWithObject(VMManagerProtocol::ClientMessage protocol_message, const QJsonObject &json) const; + // Full send message function called by all convenience functions + void sendMessageFull(VMManagerProtocol::ClientMessage protocol_message, const QStringList &list, const QJsonObject &json) const; + void jsonReceived(const QJsonObject &json); + + void dataReady(); + +protected: + bool eventFilter(QObject *obj, QEvent *event) override; + +}; + +#endif // QT_VMMANAGER_CLIENTSOCKET_HPP diff --git a/src/qt/qt_vmmanager_config.cpp b/src/qt/qt_vmmanager_config.cpp new file mode 100644 index 000000000..08bf4e7c4 --- /dev/null +++ b/src/qt/qt_vmmanager_config.cpp @@ -0,0 +1,76 @@ +/* +* 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. +* +* 86Box VM manager configuration module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#include +#include +#include "qt_vmmanager_config.hpp" + +extern "C" { +#include <86box/plat.h> +} + +VMManagerConfig::VMManagerConfig(const ConfigType type, const QString& section) +{ + char BUF[256]; + plat_get_global_config_dir(BUF, 255); + const auto configDir = QString(BUF); + const auto configFile = QDir::cleanPath(configDir + "/" + "vmm.ini"); + + config_type = type; + + settings = new QSettings(configFile, QSettings::IniFormat, this); + settings->setFallbacksEnabled(false); + if(type == ConfigType::System && !section.isEmpty()) { + settings->beginGroup(section); + } +} + +VMManagerConfig::~VMManagerConfig() { + settings->endGroup(); +} + +QString +VMManagerConfig::getStringValue(const QString& key) const +{ + const auto value = settings->value(key); + // An invalid QVariant with toString will give a default QString value which is blank. + // Therefore any variables that do not exist will return blank strings + return value.toString(); +} + +void +VMManagerConfig::setStringValue(const QString &key, const QString &value) const +{ + if (value.isEmpty()) { + remove(key); + return; + } + settings->setValue(key, value); +} + +void +VMManagerConfig::remove(const QString &key) const +{ + settings->remove(key); +} + +void +VMManagerConfig::sync() const +{ + settings->sync(); +} + diff --git a/src/qt/qt_vmmanager_config.hpp b/src/qt/qt_vmmanager_config.hpp new file mode 100644 index 000000000..bc63aaa03 --- /dev/null +++ b/src/qt/qt_vmmanager_config.hpp @@ -0,0 +1,46 @@ +/* +* 86Box A hypervisor and IBM PC system emulator that specializes in +* running old operating systems and software designed for IBM +* PC systems and compatibles from 1981 through fairly recent +* system designs based on the PCI bus. +* +* This file is part of the 86Box distribution. +* +* Header for the 86Box VM manager configuration module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#ifndef QT_VMMANAGER_CONFIG_H +#define QT_VMMANAGER_CONFIG_H + +#include + +class VMManagerConfig : QObject { + Q_OBJECT + +public: + enum class ConfigType { + General, + System, + }; + Q_ENUM(ConfigType); + + explicit VMManagerConfig(ConfigType type, const QString& section = {}); + ~VMManagerConfig() override; + [[nodiscard]] QString getStringValue(const QString& key) const; + void setStringValue(const QString& key, const QString& value) const; + void remove(const QString &key) const; + + void sync() const; + + QSettings *settings; + ConfigType config_type; + QString system_name; +}; + +#endif // QT_VMMANAGER_CONFIG_H \ No newline at end of file diff --git a/src/qt/qt_vmmanager_details.cpp b/src/qt/qt_vmmanager_details.cpp new file mode 100644 index 000000000..9292c7039 --- /dev/null +++ b/src/qt/qt_vmmanager_details.cpp @@ -0,0 +1,433 @@ +/* +* 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. +* +* 86Box VM manager system details module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#include +#include +#include + +#include "qt_vmmanager_details.hpp" +#include "ui_qt_vmmanager_details.h" + +#ifdef Q_OS_WINDOWS +extern bool windows_is_light_theme(); +#endif + +using namespace VMManager; + +VMManagerDetails::VMManagerDetails(QWidget *parent) : + QWidget(parent), ui(new Ui::VMManagerDetails) { + ui->setupUi(this); + + const auto leftColumnLayout = qobject_cast(ui->leftColumn->layout()); + + // Each section here gets its own VMManagerDetailSection, named in the constructor. + // When a system is selected in the list view it is updated through this object + // See updateData() for the implementation + + systemSection = new VMManagerDetailSection(tr("System", "Header for System section in VM Manager Details")); + ui->leftColumn->layout()->addWidget(systemSection); + // These horizontal lines are used for the alternate layout which may possibly + // be a preference one day. + // ui->leftColumn->layout()->addWidget(createHorizontalLine()); + + videoSection = new VMManagerDetailSection(tr("Display", "Header for Display section in VM Manager Details")); + ui->leftColumn->layout()->addWidget(videoSection); + // ui->leftColumn->layout()->addWidget(createHorizontalLine()); + + storageSection = new VMManagerDetailSection(tr("Storage", "Header for Storage section in VM Manager Details")); + ui->leftColumn->layout()->addWidget(storageSection); + // ui->leftColumn->layout()->addWidget(createHorizontalLine()); + + audioSection = new VMManagerDetailSection(tr("Audio", "Header for Audio section in VM Manager Details")); + ui->leftColumn->layout()->addWidget(audioSection); + // ui->leftColumn->layout()->addWidget(createHorizontalLine()); + + networkSection = new VMManagerDetailSection(tr("Network", "Header for Network section in VM Manager Details")); + ui->leftColumn->layout()->addWidget(networkSection); + // ui->leftColumn->layout()->addWidget(createHorizontalLine()); + + inputSection = new VMManagerDetailSection(tr("Input devices", "Header for Input section in VM Manager Details")); + ui->leftColumn->layout()->addWidget(inputSection); + // ui->leftColumn->layout()->addWidget(createHorizontalLine()); + + portsSection = new VMManagerDetailSection(tr("Ports", "Header for Input section in VM Manager Details")); + ui->leftColumn->layout()->addWidget(portsSection); + + otherSection = new VMManagerDetailSection(tr("Other devices", "Header for Other devices section in VM Manager Details")); + ui->leftColumn->layout()->addWidget(otherSection); + + // This is like adding a spacer + leftColumnLayout->addStretch(); + + // Event filter for the notes to save when it loses focus + ui->notesTextEdit->installEventFilter(this); + + // Default screenshot label and thumbnail (image inside the label) sizes + screenshotThumbnailSize = QSize(240, 160); + + // Set the icons for the screenshot navigation buttons + ui->screenshotNext->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowRight)); + ui->screenshotPrevious->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowLeft)); + ui->screenshotNextTB->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowRight)); + ui->screenshotPreviousTB->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowLeft)); + // Disabled by default + ui->screenshotNext->setEnabled(false); + ui->screenshotPrevious->setEnabled(false); + ui->screenshotNextTB->setEnabled(false); + ui->screenshotPreviousTB->setEnabled(false); + // Connect their signals + connect(ui->screenshotNext, &QPushButton::clicked, this, &VMManagerDetails::nextScreenshot); + connect(ui->screenshotNextTB, &QToolButton::clicked, this, &VMManagerDetails::nextScreenshot); + connect(ui->screenshotPreviousTB, &QToolButton::clicked, this, &VMManagerDetails::previousScreenshot); + connect(ui->screenshotPrevious, &QPushButton::clicked, this, &VMManagerDetails::previousScreenshot); + // These push buttons can be taken out if the tool buttons stay + ui->screenshotNext->setVisible(false); + ui->screenshotPrevious->setVisible(false); + QString toolButtonStyleSheet; + // Simple method to try and determine if light mode is enabled +#ifdef Q_OS_WINDOWS + const bool lightMode = windows_is_light_theme(); +#else + const bool lightMode = QApplication::palette().window().color().value() > QApplication::palette().windowText().color().value(); +#endif + if (lightMode) { + toolButtonStyleSheet = "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(midlight)} QToolButton:pressed {background: palette(mid)}"; + } else { +#ifndef Q_OS_WINDOWS + toolButtonStyleSheet = "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(dark)} QToolButton:pressed {background: palette(mid)}"; +#else + toolButtonStyleSheet = "QToolButton {padding: 5px}"; +#endif + } + ui->ssNavTBHolder->setStyleSheet(toolButtonStyleSheet); + + // Experimenting + startPauseButton = new QToolButton(); + startPauseButton->setIcon(QIcon(":/menuicons/qt/icons/run.ico")); + startPauseButton->setAutoRaise(true); + startPauseButton->setEnabled(false); + startPauseButton->setToolTip(tr("Start")); + ui->toolButtonHolder->setStyleSheet(toolButtonStyleSheet); + resetButton = new QToolButton(); + resetButton->setIcon(QIcon(":/menuicons/qt/icons/hard_reset.ico")); + resetButton->setEnabled(false); + resetButton->setToolTip(tr("Hard reset")); + stopButton = new QToolButton(); + stopButton->setIcon(QIcon(":/menuicons/qt/icons/acpi_shutdown.ico")); + stopButton->setEnabled(false); + stopButton->setToolTip(tr("Force shutdown")); + configureButton = new QToolButton(); + configureButton->setIcon(QIcon(":/menuicons/qt/icons/settings.ico")); + configureButton->setEnabled(false); + configureButton->setToolTip(tr("Settings...")); + cadButton = new QToolButton(); + cadButton->setIcon(QIcon(":menuicons/qt/icons/send_cad.ico")); + cadButton->setEnabled(false); + cadButton->setToolTip(tr("Ctrl+Alt+Del")); + + ui->toolButtonHolder->layout()->addWidget(configureButton); + ui->toolButtonHolder->layout()->addWidget(resetButton); + ui->toolButtonHolder->layout()->addWidget(stopButton); + ui->toolButtonHolder->layout()->addWidget(startPauseButton); + ui->toolButtonHolder->layout()->addWidget(cadButton); + + ui->notesTextEdit->setEnabled(false); + + sysconfig = new VMManagerSystem(); +} + +VMManagerDetails::~VMManagerDetails() { + delete ui; +} + +void +VMManagerDetails::updateData(VMManagerSystem *passed_sysconfig) { + + // Set the scrollarea background but also set the scroll bar to none. Otherwise it will also + // set the scrollbar background to the same. +#ifdef Q_OS_WINDOWS + extern bool windows_is_light_theme(); + if (windows_is_light_theme()) +#endif + { + ui->scrollArea->setStyleSheet("QWidget {background-color: palette(light)} QScrollBar{ background-color: none }"); + ui->systemLabel->setStyleSheet("background-color: palette(midlight);"); + } + // Margins are a little different on macos +#ifdef Q_OS_MACOS + ui->systemLabel->setMargin(15); +#else + ui->systemLabel->setMargin(10); +#endif + + // disconnect old signals before assigning the passed systemconfig object + disconnect(startPauseButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::startButtonPressed); + disconnect(startPauseButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::pauseButtonPressed); + disconnect(resetButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::restartButtonPressed); + disconnect(stopButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::shutdownForceButtonPressed); + disconnect(configureButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::launchSettings); + disconnect(cadButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::cadButtonPressed); + + sysconfig = passed_sysconfig; + connect(resetButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::restartButtonPressed); + connect(stopButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::shutdownForceButtonPressed); + connect(configureButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::launchSettings); + connect(cadButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::cadButtonPressed); + cadButton->setEnabled(true); + + bool running = sysconfig->getProcessStatus() == VMManagerSystem::ProcessStatus::Running || + sysconfig->getProcessStatus() == VMManagerSystem::ProcessStatus::RunningWaiting; + if(running) { + startPauseButton->setIcon(QIcon(":/menuicons/qt/icons/pause.ico")); + connect(startPauseButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::pauseButtonPressed); + } else { + startPauseButton->setIcon(QIcon(":/menuicons/qt/icons/run.ico")); + connect(startPauseButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::startButtonPressed); + } + startPauseButton->setEnabled(true); + configureButton->setEnabled(true); + + updateConfig(passed_sysconfig); + updateScreenshots(passed_sysconfig); + + ui->systemLabel->setText(passed_sysconfig->displayName); + ui->statusLabel->setText(sysconfig->process->processId() == 0 ? + tr("Not running") : + QString("%1: PID %2").arg(tr("Running"), QString::number(sysconfig->process->processId()))); + ui->notesTextEdit->setPlainText(passed_sysconfig->notes); + ui->notesTextEdit->setEnabled(true); + + disconnect(sysconfig->process, &QProcess::stateChanged, this, &VMManagerDetails::updateProcessStatus); + connect(sysconfig->process, &QProcess::stateChanged, this, &VMManagerDetails::updateProcessStatus); + + disconnect(sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerDetails::updateWindowStatus); + connect(sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerDetails::updateWindowStatus); + + disconnect(sysconfig, &VMManagerSystem::clientProcessStatusChanged, this, &VMManagerDetails::updateProcessStatus); + connect(sysconfig, &VMManagerSystem::clientProcessStatusChanged, this, &VMManagerDetails::updateProcessStatus); + + updateProcessStatus(); +} + +void +VMManagerDetails::updateConfig(VMManagerSystem *passed_sysconfig) { + // Each detail section here has its own VMManagerDetailSection. + // When a system is selected in the list view it is updated here, through this object: + // * First you clear it with VMManagerDetailSection::clear() + // * Then you add each line with VMManagerDetailSection::addSection() + + // System + systemSection->clear(); + systemSection->addSection("Machine", passed_sysconfig->getDisplayValue(Display::Name::Machine)); + systemSection->addSection("CPU", passed_sysconfig->getDisplayValue(Display::Name::CPU)); + systemSection->addSection("Memory", passed_sysconfig->getDisplayValue(Display::Name::Memory)); + + // Video + videoSection->clear(); + videoSection->addSection("Video", passed_sysconfig->getDisplayValue(Display::Name::Video)); + if(!passed_sysconfig->getDisplayValue(Display::Name::Voodoo).isEmpty()) { + videoSection->addSection("Voodoo", passed_sysconfig->getDisplayValue(Display::Name::Voodoo)); + } + + // Disks + storageSection->clear(); + storageSection->addSection("Disks", passed_sysconfig->getDisplayValue(Display::Name::Disks)); + storageSection->addSection("Floppy", passed_sysconfig->getDisplayValue(Display::Name::Floppy)); + storageSection->addSection("CD-ROM", passed_sysconfig->getDisplayValue(Display::Name::CD)); + storageSection->addSection("Removable disks", passed_sysconfig->getDisplayValue(Display::Name::RDisk)); + storageSection->addSection("MO", passed_sysconfig->getDisplayValue(Display::Name::MO)); + storageSection->addSection("SCSI", passed_sysconfig->getDisplayValue(Display::Name::SCSIController)); + storageSection->addSection("Controllers", passed_sysconfig->getDisplayValue(Display::Name::StorageController)); + + // Audio + audioSection->clear(); + audioSection->addSection("Audio", passed_sysconfig->getDisplayValue(Display::Name::Audio)); + audioSection->addSection("MIDI Out", passed_sysconfig->getDisplayValue(Display::Name::MidiOut)); + + // Network + networkSection->clear(); + networkSection->addSection("NIC", passed_sysconfig->getDisplayValue(Display::Name::NIC)); + + // Input + inputSection->clear(); + inputSection->addSection(tr("Keyboard"), passed_sysconfig->getDisplayValue(Display::Name::Keyboard)); + inputSection->addSection(tr("Mouse"), passed_sysconfig->getDisplayValue(Display::Name::Mouse)); + inputSection->addSection(tr("Joystick"), passed_sysconfig->getDisplayValue(Display::Name::Joystick)); + + // Ports + portsSection->clear(); + portsSection->addSection(tr("Serial ports"), passed_sysconfig->getDisplayValue(Display::Name::Serial)); + portsSection->addSection(tr("Parallel ports"), passed_sysconfig->getDisplayValue(Display::Name::Parallel)); + + // Other devices + otherSection->clear(); + otherSection->addSection(tr("ISA RTC"), passed_sysconfig->getDisplayValue(Display::Name::IsaRtc)); + otherSection->addSection(tr("ISA RAM"), passed_sysconfig->getDisplayValue(Display::Name::IsaMem)); + otherSection->addSection(tr("ISA ROM"), passed_sysconfig->getDisplayValue(Display::Name::IsaRom)); +} + +void +VMManagerDetails::updateScreenshots(VMManagerSystem *passed_sysconfig) { + // Disable screenshot navigation buttons by default + ui->screenshotNext->setEnabled(false); + ui->screenshotPrevious->setEnabled(false); + ui->screenshotNextTB->setEnabled(false); + ui->screenshotPreviousTB->setEnabled(false); + + // Different actions are taken depending on the existence and number of screenshots + screenshots = passed_sysconfig->getScreenshots(); + if (!screenshots.empty()) { + ui->screenshot->setFrameStyle(QFrame::NoFrame); + ui->screenshot->setEnabled(true); + if(screenshots.size() > 1) { + ui->screenshotNext->setEnabled(true); + ui->screenshotPrevious->setEnabled(true); + ui->screenshotNextTB->setEnabled(true); + ui->screenshotPreviousTB->setEnabled(true); + } +#ifdef Q_OS_WINDOWS + ui->screenshot->setStyleSheet(""); +#endif + if(QFileInfo::exists(screenshots.last().filePath())) { + screenshotIndex = screenshots.size() - 1; + const QPixmap pic(screenshots.at(screenshotIndex).filePath()); + ui->screenshot->setPixmap(pic.scaled(240, 160, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + } + } else { + ui->screenshotNext->setEnabled(false); + ui->screenshotPrevious->setEnabled(false); + ui->screenshotNextTB->setEnabled(false); + ui->screenshotPreviousTB->setEnabled(false); + ui->screenshot->setPixmap(QString()); + ui->screenshot->setFixedSize(240, 160); + ui->screenshot->setFrameStyle(QFrame::Box | QFrame::Sunken); + ui->screenshot->setText(tr("No screenshot")); + ui->screenshot->setEnabled(false); + ui->screenshot->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); +#ifdef Q_OS_WINDOWS + if (!windows_is_light_theme()) { + ui->screenshot->setStyleSheet("QLabel { border: 1px solid gray }"); + } else { + ui->screenshot->setStyleSheet(""); + } +#endif + } +} + +void +VMManagerDetails::updateProcessStatus() { + const bool running = sysconfig->process->state() == QProcess::ProcessState::Running; + QString status_text = running ? + QString("%1: PID %2").arg(tr("Running"), QString::number(sysconfig->process->processId())) : + tr("Not running"); + status_text.append(sysconfig->window_obscured ? QString(" (%1)").arg(tr("waiting")) : ""); + ui->statusLabel->setText(status_text); + resetButton->setEnabled(running); + stopButton->setEnabled(running); + cadButton->setEnabled(running); + if(running) { + if(sysconfig->getProcessStatus() == VMManagerSystem::ProcessStatus::Running) { + startPauseButton->setIcon(QIcon(":/menuicons/qt/icons/pause.ico")); + startPauseButton->setToolTip(tr("Pause")); + } else { + startPauseButton->setIcon(QIcon(":/menuicons/qt/icons/run.ico")); + startPauseButton->setToolTip(tr("Continue")); + } + + disconnect(startPauseButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::pauseButtonPressed); + disconnect(startPauseButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::startButtonPressed); + connect(startPauseButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::pauseButtonPressed); + } else { + startPauseButton->setIcon(QIcon(":/menuicons/qt/icons/run.ico")); + disconnect(startPauseButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::pauseButtonPressed); + disconnect(startPauseButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::startButtonPressed); + connect(startPauseButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::startButtonPressed); + startPauseButton->setToolTip(tr("Start")); + } + + if (sysconfig->window_obscured) { + resetButton->setDisabled(true); + stopButton->setDisabled(true); + cadButton->setDisabled(true); + startPauseButton->setDisabled(true); + configureButton->setDisabled(true); + } else { + configureButton->setDisabled(false); + startPauseButton->setDisabled(false); + } +} + +void +VMManagerDetails::updateWindowStatus() +{ + qInfo("Window status changed: %i", sysconfig->window_obscured); + updateProcessStatus(); +} + +QWidget * +VMManagerDetails::createHorizontalLine(const int leftSpacing, const int rightSpacing) +{ + const auto container = new QWidget; + const auto hLayout = new QHBoxLayout(container); + + hLayout->addSpacing(leftSpacing); + + const auto line = new QFrame(); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + + hLayout->addWidget(line); + hLayout->addSpacing(rightSpacing); + hLayout->setContentsMargins(0, 5, 0, 5); + + return container; +} + +void +VMManagerDetails::saveNotes() const +{ + sysconfig->setNotes(ui->notesTextEdit->toPlainText()); +} + +void +VMManagerDetails::nextScreenshot() +{ + screenshotIndex = (screenshotIndex + 1) % screenshots.size(); + const QPixmap pic(screenshots.at(screenshotIndex).filePath()); + ui->screenshot->setPixmap(pic.scaled(240, 160, Qt::KeepAspectRatio, Qt::SmoothTransformation)); +} + +void +VMManagerDetails::previousScreenshot() +{ + screenshotIndex = screenshotIndex == 0 ? screenshots.size() - 1 : screenshotIndex - 1; + const QPixmap pic(screenshots.at(screenshotIndex).filePath()); + ui->screenshot->setPixmap(pic.scaled(240, 160, Qt::KeepAspectRatio, Qt::SmoothTransformation)); +} + +bool +VMManagerDetails::eventFilter(QObject *watched, QEvent *event) +{ + if (watched->isWidgetType() && event->type() == QEvent::FocusOut) { + // Make sure it's the textedit + if (const auto *textEdit = qobject_cast(watched); textEdit) { + saveNotes(); + } + } + return QWidget::eventFilter(watched, event); +} + diff --git a/src/qt/qt_vmmanager_details.hpp b/src/qt/qt_vmmanager_details.hpp new file mode 100644 index 000000000..2fb1a9d57 --- /dev/null +++ b/src/qt/qt_vmmanager_details.hpp @@ -0,0 +1,93 @@ +/* +* 86Box A hypervisor and IBM PC system emulator that specializes in +* running old operating systems and software designed for IBM +* PC systems and compatibles from 1981 through fairly recent +* system designs based on the PCI bus. +* +* This file is part of the 86Box distribution. +* +* Header for 86Box VM manager system details module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#ifndef QT_VMMANAGER_DETAILS_H +#define QT_VMMANAGER_DETAILS_H + +#include +#include "qt_vmmanager_system.hpp" +// #include "qt_vmmanager_details_section.hpp" +#include "qt_vmmanager_detailsection.hpp" + + +QT_BEGIN_NAMESPACE +//namespace Ui { class VMManagerDetails; class CollapseButton;} +namespace Ui { class VMManagerDetails;} +QT_END_NAMESPACE + +class VMManagerDetails : public QWidget { + Q_OBJECT + +public: + explicit VMManagerDetails(QWidget *parent = nullptr); + + ~VMManagerDetails() override; + + void updateData(VMManagerSystem *passed_sysconfig); + + void updateProcessStatus(); + + void updateWindowStatus(); +// CollapseButton *systemCollapseButton; + +private: + Ui::VMManagerDetails *ui; + VMManagerSystem *sysconfig; + + VMManagerDetailSection *systemSection; + VMManagerDetailSection *videoSection; + VMManagerDetailSection *storageSection; + VMManagerDetailSection *audioSection; + VMManagerDetailSection *networkSection; + VMManagerDetailSection *inputSection; + VMManagerDetailSection *portsSection; + VMManagerDetailSection *otherSection; + + QFileInfoList screenshots; + int screenshotIndex = 0; + QSize screenshotLabelSize; + QSize screenshotThumbnailSize; + + QToolButton *startPauseButton; + QToolButton *resetButton; + QToolButton *stopButton; + QToolButton *configureButton; + QToolButton *cadButton; + + void updateConfig(VMManagerSystem *passed_sysconfig); + void updateScreenshots(VMManagerSystem *passed_sysconfig); + static QWidget* createHorizontalLine(int leftSpacing = 25, int rightSpacing = 25); + // QVBoxLayout *detailsLayout; +private slots: + void saveNotes() const; + void nextScreenshot(); + void previousScreenshot(); + +protected: + bool eventFilter(QObject *watched, QEvent *event) override; + +// CollapseButton *systemCollapseButton; +// QFrame *systemFrame; +// CollapseButton *displayCollapseButton; +// QFrame *displayFrame; +// CollapseButton *storageCollapseButton; +// QFrame *storageFrame; +}; + + + +#endif //QT_VMMANAGER_DETAILS_H diff --git a/src/qt/qt_vmmanager_details.ui b/src/qt/qt_vmmanager_details.ui new file mode 100644 index 000000000..9b4fbbe8b --- /dev/null +++ b/src/qt/qt_vmmanager_details.ui @@ -0,0 +1,293 @@ + + + VMManagerDetails + + + + 0 + 0 + 497 + 444 + + + + VMManagerDetails + + + + 0 + + + 0 + + + + + + 18 + + + + No Machines Found! + + + Qt::AlignCenter + + + + + + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + true + + + + + 0 + 0 + 139 + 388 + + + + + 0 + + + 12 + + + 12 + + + 12 + + + 12 + + + + + + + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 240 + 160 + + + + + 240 + 160 + + + + + + + Qt::AlignCenter + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + + + false + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + ... + + + + + + + ... + + + true + + + + + + + + + + + 0 + 0 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Type some notes here + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + Qt::AlignCenter + + + + + + + + + + + + + + diff --git a/src/qt/qt_vmmanager_detailsection.cpp b/src/qt/qt_vmmanager_detailsection.cpp new file mode 100644 index 000000000..23c940706 --- /dev/null +++ b/src/qt/qt_vmmanager_detailsection.cpp @@ -0,0 +1,309 @@ +/* +* 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. +* +* 86Box VM manager system details section module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#include "qt_vmmanager_detailsection.hpp" +#include "ui_qt_vmmanager_detailsection.h" + +#include + +const QString VMManagerDetailSection::sectionSeparator = ";"; +using namespace VMManager; + +VMManagerDetailSection:: +VMManagerDetailSection(const QString §ionName) + : mainLayout(new QVBoxLayout()) + , buttonLayout(new QHBoxLayout()) + , frame(new QFrame()) + , ui(new Ui::DetailSection) +{ + ui->setupUi(this); + + frameGridLayout = new QGridLayout(); + // Create the collapse button, set the name and add it to the layout + collapseButton = new CollapseButton(); + setSectionName(sectionName); + ui->collapseButtonHolder->setContentsMargins(getMargins(MarginSection::ToolButton)); + + // Simple method to try and determine if light mode is enabled on the host +#ifdef Q_OS_WINDOWS + extern bool windows_is_light_theme(); + const bool lightMode = windows_is_light_theme(); +#else + const bool lightMode = QApplication::palette().window().color().value() > QApplication::palette().windowText().color().value(); +#endif + // Alternate layout + if ( lightMode) { + ui->collapseButtonHolder->setStyleSheet("background-color: palette(midlight);"); + } else { +#ifdef Q_OS_WINDOWS + ui->outerFrame->setStyleSheet("background-color: #272727;"); + ui->collapseButtonHolder->setStyleSheet("background-color: #616161;"); +#else + ui->collapseButtonHolder->setStyleSheet("background-color: palette(mid);"); +#endif + } + const auto sectionLabel = new QLabel(sectionName); + sectionLabel->setStyleSheet(sectionLabel->styleSheet().append("font-weight: bold;")); + ui->collapseButtonHolder->setContentsMargins(QMargins(3, 2, 0, 2)); + ui->collapseButtonHolder->layout()->addWidget(sectionLabel); + + // ui->collapseButtonHolder->layout()->addWidget(collapseButton); + collapseButton->setContent(ui->detailFrame); + // Horizontal line added after the section name / button + // const auto hLine = new QFrame(); + // hLine->setFrameShape(QFrame::HLine); + // hLine->setFrameShadow(QFrame::Sunken); + // hLine->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); + // ui->collapseButtonHolder->layout()->addWidget(hLine); + const auto hSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); + ui->collapseButtonHolder->layout()->addItem(hSpacer); + // collapseButton->setContent(frame); + // ui->sectionName->setVisible(false); + setVisible(false); +} + +VMManagerDetailSection:: +VMManagerDetailSection(const QVariant &varSectionName) : ui(new Ui::DetailSection) +{ + const auto sectionName = varSectionName.toString(); + + // Initialize even though they will get wiped out + // (to keep clang-tidy happy) + frameGridLayout = new QGridLayout(); + const auto outerFrame = new QFrame(); + // for the CSS + outerFrame->setObjectName("outer_frame"); + outerFrame->setContentsMargins(QMargins(0, 0, 0, 0)); + const auto innerFrameLayout = new QVBoxLayout(); + + outerFrame->setLayout(innerFrameLayout); + auto *outerFrameLayout = new QVBoxLayout(); + outerFrameLayout->addWidget(outerFrame); + outerFrameLayout->setContentsMargins(QMargins(0, 0, 0, 0)); + + const auto buttonWidget = new QWidget(this); + + mainLayout = new QVBoxLayout(); + buttonLayout = new QHBoxLayout(); + buttonWidget->setLayout(buttonLayout); + + collapseButton = new CollapseButton(); + setSectionName(sectionName); + buttonLayout->setContentsMargins(getMargins(MarginSection::ToolButton)); + buttonLayout->addWidget(collapseButton); + + // buttonLayout->addStretch(); + auto *hLine = new QFrame(); + hLine->setFrameShape(QFrame::HLine); + hLine->setFrameShadow(QFrame::Sunken); + hLine->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); + buttonLayout->addWidget(hLine); + + mainLayout->addLayout(buttonLayout); + + frame = new QFrame(); + frame->setFrameShape(QFrame::Box); + frame->setFrameStyle(QFrame::NoFrame); + collapseButton->setContent(frame); + + mainLayout->addWidget(frame); + innerFrameLayout->addWidget(buttonWidget); + innerFrameLayout->addWidget(frame); + setLayout(outerFrameLayout); +} + +VMManagerDetailSection::~VMManagerDetailSection() += default; + +void +VMManagerDetailSection::setSectionName(const QString &name) +{ + sectionName = name; + collapseButton->setButtonText(" " + sectionName); + // Bold the section headers + collapseButton->setStyleSheet(collapseButton->styleSheet().append("font-weight: bold;")); +} + +void +VMManagerDetailSection::addSection(const QString &name, const QString &value, Display::Name displayField) +{ + const auto new_section = DetailSection { name, value}; + sections.push_back(new_section); + setSections(); +} + +void +VMManagerDetailSection::setupMainLayout() +{ + // clang-tidy says I don't need to check before deleting + delete mainLayout; + mainLayout = new QVBoxLayout; +} +void +VMManagerDetailSection::clearContentsSetupGrid() +{ + // Clear everything out + if(frameGridLayout) { + while(frameGridLayout->count()) { + QLayoutItem * cur_item = frameGridLayout->takeAt(0); + if(cur_item->widget()) + delete cur_item->widget(); + delete cur_item; + } + } + + delete frameGridLayout; + frameGridLayout = new QGridLayout(); + qint32 *left = nullptr, *top = nullptr, *right = nullptr, *bottom = nullptr; + frameGridLayout->getContentsMargins(left, top, right, bottom); + frameGridLayout->setContentsMargins(getMargins(MarginSection::DisplayGrid)); + ui->detailFrame->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + ui->detailFrame->setLayout(frameGridLayout); +} +void +VMManagerDetailSection::setSections() +{ + clearContentsSetupGrid(); + int row = 0; + + + for ( const auto& section : sections) { + // if the string contains the separator (defined elsewhere) then split and + // add each entry on a new line. Otherwise, just add the one. + QStringList sectionsToAdd; + if(section.value.contains(sectionSeparator)) { + sectionsToAdd = section.value.split(sectionSeparator); + } else { + sectionsToAdd.push_back(section.value); + } + bool keyAdded = false; + for(const auto&line : sectionsToAdd) { + if(line.isEmpty()) { + // Don't bother adding entries if the values are blank + continue; + } + const auto labelKey = new QLabel(); + labelKey->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + const auto labelValue = new QLabel(); + labelKey->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); + labelValue->setTextInteractionFlags(labelValue->textInteractionFlags() | Qt::TextSelectableByMouse); + labelKey->setTextInteractionFlags(labelValue->textInteractionFlags() | Qt::TextSelectableByMouse); + + // Reduce the text size for the label + // First, get the existing font + auto smaller_font = labelValue->font(); + // Get a smaller size + // Not sure if I like the smaller size, back to regular for now + // auto smaller_size = 0.85 * smaller_font.pointSize(); + const auto smaller_size = 1 * smaller_font.pointSize(); + // Set the font to the smaller size + smaller_font.setPointSizeF(smaller_size); + // Assign that new, smaller font to the label + labelKey->setFont(smaller_font); + labelValue->setFont(smaller_font); + + labelKey->setText(QCoreApplication::translate("", QString(section.name + ":").toUtf8().data())); + labelValue->setText(line); + if(!keyAdded) { + frameGridLayout->addWidget(labelKey, row, 0, Qt::AlignLeft); + keyAdded = true; + } + frameGridLayout->addWidget(labelValue, row, 1, Qt::AlignLeft); + const auto hSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); + frameGridLayout->addItem(hSpacer, row, 2); + row++; + } + } + collapseButton->setContent(ui->detailFrame); + if (sections.size()) + setVisible(true); +} +void +VMManagerDetailSection::clear() +{ + sections.clear(); + setVisible(false); +} + +// QT for Linux and Windows doesn't have the same default margins as QT on MacOS. +// For consistency in appearance we'll have to return the margins on a per-OS basis +QMargins +VMManagerDetailSection::getMargins(const MarginSection section) +{ + switch (section) { + case MarginSection::ToolButton: +#if defined(Q_OS_WINDOWS) or defined(Q_OS_LINUX) + return {10, 0, 5, 0}; +#else + return {0, 0, 5, 0}; +#endif + case MarginSection::DisplayGrid: +#if defined(Q_OS_WINDOWS) or defined(Q_OS_LINUX) + return {10, 0, 0, 10}; +#else + return {0, 0, 0, 10}; +#endif + default: + return {}; + } +} + +// CollapseButton Class + +CollapseButton::CollapseButton(QWidget *parent) : QToolButton(parent), content_(nullptr) { + setCheckable(true); + setStyleSheet("background:none; border:none;"); + setIconSize(QSize(8, 8)); + setFont(QApplication::font()); + setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + connect(this, &QToolButton::toggled, [=](const bool checked) { + setArrowType(checked ? Qt::ArrowType::DownArrow : Qt::ArrowType::RightArrow); + content_ != nullptr && checked ? showContent() : hideContent(); + }); + setChecked(true); +} + +void CollapseButton::setButtonText(const QString &text) { + setText(" " + text); +} + +void CollapseButton::setContent(QWidget *content) { + assert(content != nullptr); + content_ = content; + const auto animation_ = new QPropertyAnimation(content_, "maximumHeight"); // QObject with auto delete + animation_->setStartValue(0); + animation_->setEasingCurve(QEasingCurve::InOutQuad); + animation_->setDuration(300); + animation_->setEndValue(content->geometry().height() + 50); + // qDebug() << "section" << text() << "has a height of" << content->geometry().height(); + animator_.clear(); + animator_.addAnimation(animation_); + if (!isChecked()) { + content->setMaximumHeight(0); + } +} + +void CollapseButton::hideContent() { + animator_.setDirection(QAbstractAnimation::Backward); + animator_.start(); +} + +void CollapseButton::showContent() { + animator_.setDirection(QAbstractAnimation::Forward); + animator_.start(); +} + diff --git a/src/qt/qt_vmmanager_detailsection.hpp b/src/qt/qt_vmmanager_detailsection.hpp new file mode 100644 index 000000000..7619a476c --- /dev/null +++ b/src/qt/qt_vmmanager_detailsection.hpp @@ -0,0 +1,101 @@ +/* +* 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. +* +* 86Box VM manager system details section module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed + */ + +#ifndef QT_VMMANAGER_DETAILSECTION_H +#define QT_VMMANAGER_DETAILSECTION_H + +#include +#include +#include +#include +#include +#include +#include "qt_vmmanager_system.hpp" + +QT_BEGIN_NAMESPACE +namespace Ui { class DetailSection; } +QT_END_NAMESPACE + +class CollapseButton final : public QToolButton { + Q_OBJECT + +public: + explicit CollapseButton(QWidget *parent = nullptr); + + void setButtonText(const QString &text); + + void setContent(QWidget *content); + + void hideContent(); + + void showContent(); + +private: + QWidget *content_; + QString text_; + QParallelAnimationGroup animator_; +}; + +class VMManagerDetailSection final : public QWidget { + Q_OBJECT + +public: + explicit VMManagerDetailSection(const QString §ionName); + explicit VMManagerDetailSection(const QVariant &varSectionName); + // explicit VMManagerDetailSection(); + + ~VMManagerDetailSection() override; + + void addSection(const QString &name, const QString &value, VMManager::Display::Name displayField = VMManager::Display::Name::Unknown); + void clear(); + + CollapseButton *collapseButton; +// QGridLayout *buttonGridLayout; + QGridLayout *frameGridLayout; + QVBoxLayout *mainLayout; + QHBoxLayout *buttonLayout; + QFrame *frame; + + static const QString sectionSeparator; + + +private: + enum class MarginSection { + ToolButton, + DisplayGrid, + }; + + void setSectionName(const QString &name); + void setupMainLayout(); + void clearContentsSetupGrid(); + void setSections(); + + static QMargins getMargins(MarginSection section); + + QString sectionName; + + struct DetailSection { + QString name; + QString value; + }; + + QVector sections; + Ui::DetailSection *ui; + +}; + +#endif // QT_VMMANAGER_DETAILSECTION_H diff --git a/src/qt/qt_vmmanager_detailsection.ui b/src/qt/qt_vmmanager_detailsection.ui new file mode 100644 index 000000000..18e89ee65 --- /dev/null +++ b/src/qt/qt_vmmanager_detailsection.ui @@ -0,0 +1,91 @@ + + + DetailSection + + + + 0 + 0 + 348 + 151 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + + + + + + diff --git a/src/qt/qt_vmmanager_listviewdelegate.cpp b/src/qt/qt_vmmanager_listviewdelegate.cpp new file mode 100644 index 000000000..28820a044 --- /dev/null +++ b/src/qt/qt_vmmanager_listviewdelegate.cpp @@ -0,0 +1,249 @@ +/* +* 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. +* +* 86Box VM manager list view delegate module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + + +#include + +#include "qt_vmmanager_listviewdelegate.hpp" +#include "qt_vmmanager_model.hpp" + +#ifdef Q_OS_WINDOWS +extern bool windows_is_light_theme(); +#endif + + +// Thanks to scopchanov https://github.com/scopchanov/SO-MessageLog +// from https://stackoverflow.com/questions/53105343/is-it-possible-to-add-a-custom-widget-into-a-qlistview + + +VMManagerListViewDelegate::VMManagerListViewDelegate(QObject *parent) + : QStyledItemDelegate(parent), + m_ptr(new VMManagerListViewDelegateStyle) +{ +} + +VMManagerListViewDelegate::~VMManagerListViewDelegate() += default; + +void VMManagerListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const { + bool windows_light_mode = true; +#ifdef Q_OS_WINDOWS + windows_light_mode = windows_is_light_theme(); +#endif + QStyleOptionViewItem opt(option); + initStyleOption(&opt, index); + const QPalette &palette(opt.palette); + // opt.rect = opt.rect.adjusted(0, 0, 0, 20); + const QRect &rect(opt.rect); + const QRect &contentRect(rect.adjusted(m_ptr->margins.left(), + m_ptr->margins.top(), + -m_ptr->margins.right(), + -m_ptr->margins.bottom())); + + // The status icon represents the current state of the vm. Initially set to a default state. + QIcon status_icon = QApplication::style()->standardIcon(QStyle::SP_MediaStop); + auto process_variant = index.data(VMManagerModel::Roles::ProcessStatus); + auto process_status = process_variant.value(); + // The main icon, configurable. Falls back to default if it cannot be loaded. + auto customIcom = index.data(VMManagerModel::Roles::Icon).toString(); + opt.icon = QIcon(":/settings/qt/icons/86Box-gray.ico"); + if(!customIcom.isEmpty()) { + if (const auto customPixmap = QPixmap(customIcom); !customPixmap.isNull()) { + opt.icon = customPixmap; + } + } + // opt.icon = QIcon(":/settings/qt/icons/86Box-gray.ico"); + + // Set the status icon based on the process status + switch(process_status) { + case VMManagerSystem::ProcessStatus::Running: + status_icon = QIcon(":/menuicons/qt/icons/run.ico"); + break; + case VMManagerSystem::ProcessStatus::Stopped: + status_icon = QIcon(":/menuicons/qt/icons/acpi_shutdown.ico"); + break; + case VMManagerSystem::ProcessStatus::PausedWaiting: + case VMManagerSystem::ProcessStatus::RunningWaiting: + case VMManagerSystem::ProcessStatus::Paused: + status_icon = QIcon(":/menuicons/qt/icons/pause.ico"); + break; + default: + status_icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxQuestion); + } + + + // Used to determine if the horizontal separator should be drawn + const bool lastIndex = (index.model()->rowCount() - 1) == index.row(); + const bool hasIcon = !opt.icon.isNull(); + const int bottomEdge = rect.bottom(); + QFont f(opt.font); + + f.setPointSizeF(m_ptr->statusFontPointSize(opt.font)); + + painter->save(); + painter->setClipping(true); + painter->setClipRect(rect); + painter->setFont(opt.font); + + // Draw the background + if (opt.state & QStyle::State_Selected) { + // When selected, only draw the highlighted part until the horizontal separator + int offset = 2; + auto highlightRect = rect.adjusted(0, 0, 0, -offset); + painter->fillRect(highlightRect, windows_light_mode ? palette.highlight().color() : QColor("#616161")); + // Then fill the remainder with the normal color + auto regularRect = rect.adjusted(0, rect.height()-offset, 0, 0); + painter->fillRect(regularRect, windows_light_mode ? palette.light().color() : QColor("#272727")); + } else { + // Otherwise just draw the background color as usual + painter->fillRect(rect, windows_light_mode ? palette.light().color() : QColor("#272727")); + } + + // Draw bottom line. Last line gets a different color + painter->setPen(lastIndex ? palette.dark().color() + : palette.mid().color()); + painter->drawLine(lastIndex ? rect.left() : m_ptr->margins.left(), + bottomEdge, rect.right(), bottomEdge); + + // Draw system icon + if (hasIcon) { + painter->drawPixmap(contentRect.left(), contentRect.top(), + opt.icon.pixmap(m_ptr->iconSize)); + } + + // System name + QRect systemNameRect(m_ptr->systemNameBox(opt, index)); + + systemNameRect.moveTo(m_ptr->margins.left() + m_ptr->iconSize.width() + + m_ptr->spacingHorizontal, contentRect.top()); + // If desired, font can be changed here +// painter->setFont(f); + painter->setFont(opt.font); + painter->setPen(palette.text().color()); + painter->drawText(systemNameRect, Qt::TextSingleLine, opt.text); + + // Draw status icon + painter->drawPixmap(systemNameRect.left(), systemNameRect.bottom() + + m_ptr->spacingVertical, + status_icon.pixmap(m_ptr->smallIconSize)); + + // This rectangle is around the status icon + // auto point = QPoint(systemNameRect.left(), systemNameRect.bottom() + // + m_ptr->spacingVertical); + // auto point2 = QPoint(point.x() + m_ptr->smallIconSize.width(), point.y() + m_ptr->smallIconSize.height()); + // auto arect = QRect(point, point2); + // painter->drawRect(arect); + + // Draw status text + QRect statusRect(m_ptr->statusBox(opt, index)); + int extraaa = 2; + statusRect.moveTo(systemNameRect.left() + m_ptr->margins.left() + m_ptr->smallIconSize.width(), + systemNameRect.bottom() + m_ptr->spacingVertical + extraaa + (m_ptr->smallIconSize.height() - systemNameRect.height() )); + +// painter->setFont(opt.font); + painter->setFont(f); + painter->setPen(palette.windowText().color()); + painter->drawText(statusRect, Qt::TextSingleLine, + index.data(VMManagerModel::Roles::ProcessStatusString).toString()); + + painter->restore(); + +} + +QMargins VMManagerListViewDelegate::contentsMargins() const +{ + return m_ptr->margins; +} + +void VMManagerListViewDelegate::setContentsMargins(const int left, const int top, const int right, const int bottom) const +{ + m_ptr->margins = QMargins(left, top, right, bottom); +} + +int VMManagerListViewDelegate::horizontalSpacing() const +{ + return m_ptr->spacingHorizontal; +} + +void VMManagerListViewDelegate::setHorizontalSpacing(const int spacing) const +{ + m_ptr->spacingHorizontal = spacing; +} + +int VMManagerListViewDelegate::verticalSpacing() const +{ + return m_ptr->spacingVertical; +} + +void VMManagerListViewDelegate::setVerticalSpacing(const int spacing) const +{ + m_ptr->spacingVertical = spacing; +} + + +QSize VMManagerListViewDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QStyleOptionViewItem opt(option); + initStyleOption(&opt, index); + + const int textHeight = m_ptr->systemNameBox(opt, index).height() + + m_ptr->spacingVertical + m_ptr->statusBox(opt, index).height(); + const int iconHeight = m_ptr->iconSize.height(); + const int h = textHeight > iconHeight ? textHeight : iconHeight; + + // return the same width + // for height, add margins on top and bottom *plus* either the text or icon height, whichever is greater + // Note: text height is the combined value of the system name and the status just below the name + return {opt.rect.width(), m_ptr->margins.top() + h + + m_ptr->margins.bottom()}; +} + +VMManagerListViewDelegateStyle::VMManagerListViewDelegateStyle() : + iconSize(32, 32), + smallIconSize(16, 16), + // bottom gets a little more than the top because of the custom separator + margins(4, 10, 8, 12), + // Spacing between icon and text + spacingHorizontal(8), + spacingVertical(4) +{ + +} + +QRect VMManagerListViewDelegateStyle::statusBox(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QFont f(option.font); + + f.setPointSizeF(statusFontPointSize(option.font)); + + return QFontMetrics(f).boundingRect(index.data(VMManagerModel::Roles::ProcessStatusString).toString()) + .adjusted(0, 0, 1, 1); +} + +qreal VMManagerListViewDelegateStyle::statusFontPointSize(const QFont &f) const +{ + return 0.75*f.pointSize(); +// return 1*f.pointSize(); +} + +QRect VMManagerListViewDelegateStyle::systemNameBox(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return option.fontMetrics.boundingRect(option.text).adjusted(0, 0, 1, 1); +} diff --git a/src/qt/qt_vmmanager_listviewdelegate.hpp b/src/qt/qt_vmmanager_listviewdelegate.hpp new file mode 100644 index 000000000..84325086d --- /dev/null +++ b/src/qt/qt_vmmanager_listviewdelegate.hpp @@ -0,0 +1,67 @@ +/* +* 86Box A hypervisor and IBM PC system emulator that specializes in +* running old operating systems and software designed for IBM +* PC systems and compatibles from 1981 through fairly recent +* system designs based on the PCI bus. +* +* This file is part of the 86Box distribution. +* +* Header for 86Box VM manager list view delegate module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#ifndef QT_VMMANAGER_LISTVIEWDELEGATE_H +#define QT_VMMANAGER_LISTVIEWDELEGATE_H + +#include +#include +#include "qt_vmmanager_system.hpp" + +class VMManagerListViewDelegateStyle +{ + VMManagerListViewDelegateStyle(); + + [[nodiscard]] inline QRect systemNameBox(const QStyleOptionViewItem &option, + const QModelIndex &index) const; + [[nodiscard]] inline qreal statusFontPointSize(const QFont &f) const; + [[nodiscard]] inline QRect statusBox(const QStyleOptionViewItem &option, const QModelIndex &index) const; + + QSize iconSize; + QSize smallIconSize; + QMargins margins; + int spacingHorizontal; + int spacingVertical; + + friend class VMManagerListViewDelegate; +}; + +class VMManagerListViewDelegate final : public QStyledItemDelegate { + Q_OBJECT + +public: + explicit VMManagerListViewDelegate(QObject *parent = nullptr); + ~VMManagerListViewDelegate() override; + using QStyledItemDelegate::QStyledItemDelegate; + + [[nodiscard]] QMargins contentsMargins() const; + void setContentsMargins(int left, int top, int right, int bottom) const; + + [[nodiscard]] int horizontalSpacing() const; + void setHorizontalSpacing(int spacing) const; + + [[nodiscard]] int verticalSpacing() const; + void setVerticalSpacing(int spacing) const; + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + [[nodiscard]] QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const override; +private: + VMManagerListViewDelegateStyle *m_ptr; +}; +#endif // QT_VMMANAGER_LISTVIEWDELEGATE_H \ No newline at end of file diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp new file mode 100644 index 000000000..38a3d7340 --- /dev/null +++ b/src/qt/qt_vmmanager_main.cpp @@ -0,0 +1,562 @@ +/* +* 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. +* +* 86Box VM manager main module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qt_vmmanager_main.hpp" +#include "ui_qt_vmmanager_main.h" +#include "qt_vmmanager_model.hpp" +#include "qt_vmmanager_addmachine.hpp" + +VMManagerMain::VMManagerMain(QWidget *parent) : + QWidget(parent), ui(new Ui::VMManagerMain), selected_sysconfig(new VMManagerSystem) { + ui->setupUi(this); + + // Set up the main listView + ui->listView->setItemDelegate(new VMManagerListViewDelegate); + vm_model = new VMManagerModel; + proxy_model = new StringListProxyModel(this); + proxy_model->setSourceModel(vm_model); + ui->listView->setModel(proxy_model); + proxy_model->setSortCaseSensitivity(Qt::CaseInsensitive); + ui->listView->model()->sort(0, Qt::AscendingOrder); + + // Connect the model signal + connect(vm_model, &VMManagerModel::systemDataChanged, this, &VMManagerMain::modelDataChange); + + // Set up the context menu for the list view + ui->listView->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->listView, &QListView::customContextMenuRequested, [this, parent](const QPoint &pos) { + const auto indexAt = ui->listView->indexAt(pos); + if (indexAt.isValid()) { + QMenu contextMenu(tr("Context Menu"), ui->listView); + + QAction nameChangeAction(tr("Change &display name...")); + contextMenu.addAction(&nameChangeAction); + // Use a lambda to call a function so indexAt can be passed + connect(&nameChangeAction, &QAction::triggered, ui->listView, [this, indexAt] { + updateDisplayName(indexAt); + }); + nameChangeAction.setEnabled(!selected_sysconfig->window_obscured); + + QAction openSystemFolderAction(tr("&Open folder...")); + contextMenu.addAction(&openSystemFolderAction); + connect(&openSystemFolderAction, &QAction::triggered, [indexAt] { + if (const auto configDir = indexAt.data(VMManagerModel::Roles::ConfigDir).toString(); !configDir.isEmpty()) { + QDir dir(configDir); + if (!dir.exists()) + dir.mkpath("."); + + QDesktopServices::openUrl(QUrl(QString("file:///") + dir.canonicalPath())); + } + }); + + QAction openPrinterFolderAction(tr("Open &printer tray...")); + contextMenu.addAction(&openPrinterFolderAction); + connect(&openPrinterFolderAction, &QAction::triggered, [indexAt] { + if (const auto printerDir = indexAt.data(VMManagerModel::Roles::ConfigDir).toString() + QString("/printer/"); !printerDir.isEmpty()) { + QDir dir(printerDir); + if (!dir.exists()) + dir.mkpath("."); + + QDesktopServices::openUrl(QUrl(QString("file:///") + dir.canonicalPath())); + } + }); + + QAction setSystemIcon(tr("Set &icon...")); + contextMenu.addAction(&setSystemIcon); + connect(&setSystemIcon, &QAction::triggered, [this] { + IconSelectionDialog dialog(":/systemicons/"); + if(dialog.exec() == QDialog::Accepted) { + const QString iconName = dialog.getSelectedIconName(); + // A Blank iconName will cause setIcon to reset to the default + selected_sysconfig->setIcon(iconName); + } + }); + setSystemIcon.setEnabled(!selected_sysconfig->window_obscured); + + QAction killIcon(tr("&Kill")); + contextMenu.addAction(&killIcon); + connect(&killIcon, &QAction::triggered, [this, parent] { + QMessageBox msgbox(QMessageBox::Warning, tr("Warning"), tr("Killing a virtual machine can cause data loss. Only do this if the 86Box process gets stuck.\n\nDo you really wish to kill the virtual machine \"%1\"?").arg(selected_sysconfig->displayName), QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, parent); + msgbox.exec(); + if (msgbox.result() == QMessageBox::Yes) { + selected_sysconfig->process->kill(); + } + }); + killIcon.setEnabled(selected_sysconfig->process->state() == QProcess::Running); + + contextMenu.addSeparator(); + + QAction showRawConfigFile(tr("Show &config file")); + contextMenu.addAction(&showRawConfigFile); + connect(&showRawConfigFile, &QAction::triggered, [this, indexAt] { + if (const auto configFile = indexAt.data(VMManagerModel::Roles::ConfigFile).toString(); !configFile.isEmpty()) { + showTextFileContents(indexAt.data(Qt::DisplayRole).toString(), configFile); + } + }); + + contextMenu.exec(ui->listView->viewport()->mapToGlobal(pos)); + } + }); + + // Initial default details view + vm_details = new VMManagerDetails(); + ui->detailsArea->layout()->addWidget(vm_details); + const QItemSelectionModel *selection_model = ui->listView->selectionModel(); + + connect(selection_model, &QItemSelectionModel::currentChanged, this, &VMManagerMain::currentSelectionChanged); + // If there are items in the model, make sure to select the first item by default. + // When settings are loaded, the last selected item will be selected (if available) + if (proxy_model->rowCount(QModelIndex()) > 0) { + const QModelIndex first_index = proxy_model->index(0, 0); + ui->listView->setCurrentIndex(first_index); + } + + connect(ui->listView, &QListView::doubleClicked, this, &VMManagerMain::startButtonPressed); + + // Load and apply settings + loadSettings(); + ui->splitter->setSizes({ui->detailsArea->width(), (ui->listView->minimumWidth() * 2)}); + + // Set up search bar + connect(ui->searchBar, &QLineEdit::textChanged, this, &VMManagerMain::searchSystems); + // Create the completer + auto *completer = new QCompleter(this); + completer->setCaseSensitivity(Qt::CaseInsensitive); + completer->setFilterMode(Qt::MatchContains); + // Get the completer list + const auto allStrings = getSearchCompletionList(); + // Set up the completer + auto *completerModel = new QStringListModel(allStrings, completer); + completer->setModel(completerModel); + ui->searchBar->setCompleter(completer); + + // Set initial status bar after the event loop starts + QTimer::singleShot(0, this, [this] { + emit updateStatusRight(totalCountString()); + }); + +#if EMU_BUILD_NUM != 0 + // Start update check after a slight delay + QTimer::singleShot(1000, this, [this] { + if(updateCheck) { + backgroundUpdateCheckStart(); + } + }); +#endif +} + +VMManagerMain::~VMManagerMain() { + delete ui; + delete vm_model; +} + +void +VMManagerMain::currentSelectionChanged(const QModelIndex ¤t, + const QModelIndex &previous) +{ + if(!current.isValid()) { + return; + } + + disconnect(selected_sysconfig, &VMManagerSystem::configurationChanged, this, &VMManagerMain::onConfigUpdated); + const auto mapped_index = proxy_model->mapToSource(current); + selected_sysconfig = vm_model->getConfigObjectForIndex(mapped_index); + vm_details->updateData(selected_sysconfig); + connect(selected_sysconfig, &VMManagerSystem::configurationChanged, this, &VMManagerMain::onConfigUpdated); + + // Emit that the selection changed, include with the process state + emit selectionChanged(current, selected_sysconfig->process->state()); + +} + +void +VMManagerMain::settingsButtonPressed() { + if(!currentSelectionIsValid()) { + return; + } + selected_sysconfig->launchSettings(); +} + +void +VMManagerMain::startButtonPressed() const +{ + if(!currentSelectionIsValid()) { + return; + } + selected_sysconfig->startButtonPressed(); +} + +void +VMManagerMain::restartButtonPressed() const +{ + if(!currentSelectionIsValid()) { + return; + } + selected_sysconfig->restartButtonPressed(); + +} + +void +VMManagerMain::pauseButtonPressed() const +{ + if(!currentSelectionIsValid()) { + return; + } + selected_sysconfig->pauseButtonPressed(); +} + +void +VMManagerMain::shutdownRequestButtonPressed() const +{ + if (!currentSelectionIsValid()) { + return; + } + selected_sysconfig->shutdownRequestButtonPressed(); +} + +void +VMManagerMain::shutdownForceButtonPressed() const +{ + if (!currentSelectionIsValid()) { + return; + } + selected_sysconfig->shutdownForceButtonPressed(); +} + +// This function doesn't appear to be needed any longer +void +VMManagerMain::refresh() +{ + const auto current_index = ui->listView->currentIndex(); + emit selectionChanged(current_index, selected_sysconfig->process->state()); + + // if(!selected_sysconfig->config_file.path().isEmpty()) { + if(!selected_sysconfig->isValid()) { + // what was happening here? + } +} + +void +VMManagerMain::updateDisplayName(const QModelIndex &index) +{ + QDialog dialog; + dialog.setMinimumWidth(400); + dialog.setWindowTitle(tr("Set display name")); + const auto layout = new QVBoxLayout(&dialog); + const auto label = new QLabel(tr("Enter the new display name (blank to reset)")); + label->setAlignment(Qt::AlignHCenter); + label->setContentsMargins(QMargins(0, 0, 0, 5)); + layout->addWidget(label); + const auto lineEdit = new QLineEdit(index.data().toString(), &dialog); + layout->addWidget(lineEdit); + lineEdit->selectAll(); + + const auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog); + layout->addWidget(buttonBox); + + connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + + if (const bool accepted = dialog.exec() == QDialog::Accepted; accepted) { + const auto mapped_index = proxy_model->mapToSource(index); + vm_model->updateDisplayName(mapped_index, lineEdit->text()); + selected_sysconfig = vm_model->getConfigObjectForIndex(mapped_index); + vm_details->updateData(selected_sysconfig); + ui->listView->scrollTo(ui->listView->currentIndex(), QAbstractItemView::PositionAtCenter); + } +} + +void +VMManagerMain::loadSettings() +{ + const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); + const auto lastSelection = config->getStringValue("last_selection"); +#if EMU_BUILD_NUM != 0 + updateCheck = config->getStringValue("update_check").toInt(); +#endif + regexSearch = config->getStringValue("regex_search").toInt(); + + const auto matches = ui->listView->model()->match(vm_model->index(0, 0), VMManagerModel::Roles::ConfigName, QVariant::fromValue(lastSelection)); + if (!matches.empty()) { + ui->listView->setCurrentIndex(matches.first()); + ui->listView->scrollTo(ui->listView->currentIndex(), QAbstractItemView::PositionAtCenter); + } +} +bool +VMManagerMain::currentSelectionIsValid() const +{ + return ui->listView->currentIndex().isValid() && selected_sysconfig->isValid(); +} + +void +VMManagerMain::onConfigUpdated(const QString &uuid) +{ + if (selected_sysconfig->uuid == uuid) + vm_details->updateData(selected_sysconfig); +} +// Used from MainWindow during app exit to obtain and persist the current selection +QString +VMManagerMain::getCurrentSelection() const +{ + return ui->listView->currentIndex().data(VMManagerModel::Roles::ConfigName).toString(); +} + +void +VMManagerMain::searchSystems(const QString &text) const +{ + // Escape the search text string unless regular expression searching is enabled. + // When escaped, the search string functions as a plain text match. + const auto searchText = regexSearch ? text : QRegularExpression::escape(text); + const QRegularExpression regex(searchText, QRegularExpression::CaseInsensitiveOption); + if (!regex.isValid()) { + qDebug() << "Skipping, invalid regex"; + return; + } + proxy_model->setFilterRegularExpression(regex); + // Searching (filtering) can cause the list view to change. If there is still a valid selection, + // make sure to scroll to it + if (ui->listView->currentIndex().isValid()) { + ui->listView->scrollTo(ui->listView->currentIndex(), QAbstractItemView::PositionAtCenter); + } +} + +void +VMManagerMain::newMachineWizard() +{ + const auto wizard = new VMManagerAddMachine(this); + if (wizard->exec() == QDialog::Accepted) { + const auto newName = wizard->field("systemName").toString(); + const auto systemDir = wizard->field("systemLocation").toString(); + const auto existingConfiguration = wizard->field("existingConfiguration").toString(); + addNewSystem(newName, systemDir, existingConfiguration); + } +} + +void +VMManagerMain::addNewSystem(const QString &name, const QString &dir, const QString &configFile) +{ + const auto newSytemDirectory = QDir(QDir::cleanPath(dir + "/" + name)); + + // qt replaces `/` with native separators + const auto newSystemConfigFile = QFileInfo(newSytemDirectory.path() + "/" + "86box.cfg"); + if (newSystemConfigFile.exists() || newSytemDirectory.exists()) { + QMessageBox::critical(this, tr("Directory in use"), tr("The selected directory is already in use. Please select a different directory.")); + return; + } + // Create the directory + const QDir qmkdir; + if (const bool mkdirResult = qmkdir.mkdir(newSytemDirectory.path()); !mkdirResult) { + QMessageBox::critical(this, tr("Create directory failed"), tr("Unable to create the directory for the new system")); + return; + } + // If specified, write the contents of the configuration file before starting + if (!configFile.isEmpty()) { + const auto configPath = newSystemConfigFile.absoluteFilePath(); + const auto file = new QFile(configPath); + if (!file->open(QIODevice::WriteOnly)) { + qWarning() << "Unable to open file " << configPath; + QMessageBox::critical(this, tr("Configuration write failed"), tr("Unable to open the configuration file at %1 for writing").arg(configPath)); + return; + } + file->write(configFile.toUtf8()); + file->flush(); + file->close(); + } + + const auto new_system = new VMManagerSystem(newSystemConfigFile.absoluteFilePath()); + new_system->launchSettings(); + // Handle this in a closure so we can capture the temporary new_system object + connect(new_system->process, QOverload::of(&QProcess::finished), + [=](const int exitCode, const QProcess::ExitStatus exitStatus) { + if (exitCode != 0 || exitStatus != QProcess::NormalExit) { + qInfo().nospace().noquote() << "Abnormal program termination while creating new system: exit code " << exitCode << ", exit status " << exitStatus; + qInfo() << "Not adding system due to errors"; + QMessageBox::critical(this, tr("Error adding system"), + tr("Abnormal program termination while creating new system: exit code %1, exit status %2.\n\nThe system will not be added.").arg(QString::number(exitCode), exitStatus)); + delete new_system; + return; + } + // Create a new QFileInfo because the info from the old one may be cached + if (const auto fi = QFileInfo(new_system->config_file.absoluteFilePath()); !fi.exists()) { + // No config file which means the cancel button was pressed in the settings dialog + // Attempt to clean up the directory that was created + const QDir qrmdir; + if (const bool result = qrmdir.rmdir(newSytemDirectory.path()); !result) { + qWarning() << "Error cleaning up the old directory for canceled operation. Continuing anyway."; + } + delete new_system; + return; + } + const auto current_index = ui->listView->currentIndex(); + vm_model->reload(this); + const auto created_object = vm_model->getIndexForConfigFile(new_system->config_file); + if (created_object.row() < 0) { + // For some reason the index of the new object couldn't be determined. Fall back to the old index. + ui->listView->setCurrentIndex(current_index); + delete new_system; + return; + } + // Get the index of the newly-created system and select it + const QModelIndex mapped_index = proxy_model->mapFromSource(created_object); + ui->listView->setCurrentIndex(mapped_index); + delete new_system; + }); +} + +QStringList +VMManagerMain::getSearchCompletionList() const +{ + QSet uniqueStrings; + for (int row = 0; row < vm_model->rowCount(QModelIndex()); ++row) { + QModelIndex index = vm_model->index(row, 0); + auto fullList = vm_model->data(index, VMManagerModel::Roles::SearchList).toStringList(); + QSet uniqueSet(fullList.begin(), fullList.end()); + uniqueStrings.unite(uniqueSet); + } + // Convert the set back to a QStringList + QStringList allStrings = uniqueStrings.values(); + return allStrings; +} + +QString +VMManagerMain::totalCountString() const +{ + const auto count = vm_model->rowCount(QModelIndex()); + return QString("%1 %2").arg(QString::number(count), tr("total")); +} + +void +VMManagerMain::modelDataChange() +{ + // Model data has changed. This includes process status. + // Update the counts / totals accordingly + auto modelStats = vm_model->getProcessStats(); + QStringList stats; + for (auto it = modelStats.constBegin(); it != modelStats.constEnd(); ++it) { + const auto &key = it.key(); + stats.append(QString("%1 %2").arg(QString::number(modelStats[key]), key)); + } + auto states = stats.join(", "); + if (!modelStats.isEmpty()) { + states.append(", "); + } + + emit updateStatusRight(states + totalCountString()); +} + +void +VMManagerMain::onPreferencesUpdated() +{ + // Only reload values that we care about + const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); + const auto oldRegexSearch = regexSearch; + regexSearch = config->getStringValue("regex_search").toInt(); + if (oldRegexSearch != regexSearch) { + ui->searchBar->clear(); + } +} + +int +VMManagerMain::getActiveMachineCount() +{ + return vm_model->getActiveMachineCount(); +} + +#if EMU_BUILD_NUM != 0 +void +VMManagerMain::backgroundUpdateCheckStart() const +{ + auto updateChannel = UpdateCheck::UpdateChannel::CI; +#ifdef RELEASE_BUILD + updateChannel = UpdateCheck::UpdateChannel::Stable; +#endif + const auto updateCheck = new UpdateCheck(updateChannel); + connect(updateCheck, &UpdateCheck::updateCheckComplete, this, &VMManagerMain::backgroundUpdateCheckComplete); + connect(updateCheck, &UpdateCheck::updateCheckError, this, &VMManagerMain::backgroundUpdateCheckError); + updateCheck->checkForUpdates(); +} + +void +VMManagerMain::backgroundUpdateCheckComplete(const UpdateCheck::UpdateResult &result) +{ + qDebug() << "Check complete: update available?" << result.updateAvailable; + auto type = result.channel == UpdateCheck::UpdateChannel::CI ? tr("Build") : tr("Version"); + const auto updateMessage = QString("%1: %2 %3").arg( tr("An update to 86Box is available"), type, result.latestVersion); + emit updateStatusLeft(updateMessage); +} + +void +VMManagerMain::backgroundUpdateCheckError(const QString &errorMsg) +{ + qDebug() << "Update check failed with the following error:" << errorMsg; + // TODO: Update the status bar +} +#endif + +void +VMManagerMain::showTextFileContents(const QString &title, const QString &path) +{ + // Make sure we can open the file + const auto fi = QFileInfo(path); + if(!fi.exists()) { + qWarning("Requested file does not exist: %s", path.toUtf8().constData()); + return; + } + // Read the file + QFile displayFile(path); + if (!displayFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning("Couldn't open the file: error %d", displayFile.error()); + return; + } + const QString configFileContents = displayFile.readAll(); + displayFile.close(); + + const auto textDisplayDialog = new QDialog(this); + textDisplayDialog->setMinimumSize(QSize(540, 360)); + textDisplayDialog->setWindowTitle(QString("%1 - %2").arg(title, fi.fileName())); + + const auto textEdit = new QPlainTextEdit(); + const auto monospaceFont = new QFont(); +#ifdef Q_OS_WINDOWS + monospaceFont->setFamily("Consolas"); +#elif defined(Q_OS_MACOS) + monospaceFont->setFamily("Menlo"); +#else + monospaceFont->setFamily("Monospace"); +#endif + monospaceFont->setStyleHint(QFont::Monospace); + monospaceFont->setFixedPitch(true); + textEdit->setFont(*monospaceFont); + textEdit->setReadOnly(true); + textEdit->setPlainText(configFileContents); + const auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok); + connect(buttonBox, &QDialogButtonBox::accepted, textDisplayDialog, &QDialog::accept); + const auto layout = new QVBoxLayout(); + textDisplayDialog->setLayout(layout); + textDisplayDialog->layout()->addWidget(textEdit); + textDisplayDialog->layout()->addWidget(buttonBox); + textDisplayDialog->exec(); +} diff --git a/src/qt/qt_vmmanager_main.hpp b/src/qt/qt_vmmanager_main.hpp new file mode 100644 index 000000000..fc21d577f --- /dev/null +++ b/src/qt/qt_vmmanager_main.hpp @@ -0,0 +1,181 @@ +/* +* 86Box A hypervisor and IBM PC system emulator that specializes in +* running old operating systems and software designed for IBM +* PC systems and compatibles from 1981 through fairly recent +* system designs based on the PCI bus. +* +* This file is part of the 86Box distribution. +* +* Header for 86Box VM manager main module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#ifndef QT_VMMANAGER_MAIN_H +#define QT_VMMANAGER_MAIN_H + +#include +#include "qt_vmmanager_model.hpp" +#include "qt_vmmanager_details.hpp" +#include "qt_vmmanager_listviewdelegate.hpp" + +#include + +extern "C" { +#include <86box/86box.h> // for vmm_path +#include <86box/version.h> +} + +#if EMU_BUILD_NUM != 0 +# include "qt_updatecheck.hpp" +#endif + +QT_BEGIN_NAMESPACE +namespace Ui { class VMManagerMain; } +QT_END_NAMESPACE + +class VMManagerMain final : public QWidget { + Q_OBJECT + +public: + explicit VMManagerMain(QWidget *parent = nullptr); + ~VMManagerMain() override; + // Used to save the current selection + [[nodiscard]] QString getCurrentSelection() const; + + enum class ToolbarButton { + Start, + Pause, + StartPause, + Shutdown, + Reset, + CtrlAltDel, + Settings, + }; +signals: + void selectionChanged(const QModelIndex ¤tSelection, QProcess::ProcessState processState); + void updateStatusLeft(const QString &text); + void updateStatusRight(const QString &text); + +public slots: + void startButtonPressed() const; + void settingsButtonPressed(); + void restartButtonPressed() const; + void pauseButtonPressed() const; + void shutdownRequestButtonPressed() const; + void shutdownForceButtonPressed() const; + void searchSystems(const QString &text) const; + void newMachineWizard(); + void addNewSystem(const QString &name, const QString &dir, const QString &configFile = {}); +#if __GNUC__ >= 11 + [[nodiscard]] QStringList getSearchCompletionList() const; +#else + QStringList getSearchCompletionList() const; +#endif + void modelDataChange(); + void onPreferencesUpdated(); + void onConfigUpdated(const QString &uuid); + int getActiveMachineCount(); + +private: + Ui::VMManagerMain *ui; + + VMManagerModel *vm_model; + VMManagerDetails *vm_details; + VMManagerSystem *selected_sysconfig; + // VMManagerConfig *config; + QSortFilterProxyModel *proxy_model; +#if EMU_BUILD_NUM != 0 + bool updateCheck = false; +#endif + bool regexSearch = false; + + // void updateSelection(const QItemSelection &selected, + // const QItemSelection &deselected); + void currentSelectionChanged(const QModelIndex ¤t, + const QModelIndex &previous); + void refresh(); + void updateDisplayName(const QModelIndex &index); + void loadSettings(); + [[nodiscard]] bool currentSelectionIsValid() const; + [[nodiscard]] QString totalCountString() const; +#if EMU_BUILD_NUM != 0 + void backgroundUpdateCheckStart() const; +#endif + void showTextFileContents(const QString &title, const QString &path); +private slots: +#if EMU_BUILD_NUM != 0 + void backgroundUpdateCheckComplete(const UpdateCheck::UpdateResult &result); + void backgroundUpdateCheckError(const QString &errorMsg); +#endif +}; + +#include +#include +#include +#include + +class IconSelectionDialog final : public QDialog { + Q_OBJECT + +public: + explicit IconSelectionDialog(QString assetPath, QWidget *parent = nullptr) : QDialog(parent), listWidget(new QListWidget) { + // Set the list widget to icon mode + listWidget->setViewMode(QListWidget::IconMode); + setFixedSize(QSize(540, 360)); + listWidget->setGridSize(QSize(96, 96)); + listWidget->setIconSize(QSize(64, 64)); + // Read in all the assets from the given path + const QDir iconsDir(assetPath); + if (!assetPath.endsWith("/")) { + assetPath.append("/"); + } + setWindowTitle(tr("Select an icon")); + + // Loop on all files and add them as items (icons) in QListWidget + for(const QString& iconName : iconsDir.entryList()) { + const auto item = new QListWidgetItem(QIcon(assetPath + iconName), iconName); + // Set the UserRole to the resource bundle path + item->setData(Qt::UserRole, assetPath + iconName); + listWidget->addItem(item); + } + + // Dialog buttons + const auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Reset); + // Use the reset button for resetting the icon to the default + const QPushButton* resetButton = buttonBox->button(QDialogButtonBox::Reset); + + // Connect the buttons signals + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + connect(listWidget, &QListWidget::doubleClicked, this, &QDialog::accept); + connect(resetButton, &QPushButton::clicked, [this] { + // For reset, set the index to invalid so the caller will receive a blank string + listWidget->setCurrentIndex(QModelIndex()); + // Then accept + QDialog::accept(); + }); + + const auto layout = new QVBoxLayout(this); + layout->addWidget(listWidget); + layout->addWidget(buttonBox); + } + + public slots: + [[nodiscard]] QString getSelectedIconName() const { + if (listWidget->currentIndex().isValid()) { + return listWidget->currentItem()->data(Qt::UserRole).toString(); + } + // Index is invalid because the reset button was pressed + return {}; + } + +private: + QListWidget* listWidget; +}; + +#endif //QT_VMMANAGER_MAIN_H diff --git a/src/qt/qt_vmmanager_main.ui b/src/qt/qt_vmmanager_main.ui new file mode 100644 index 000000000..582645b9f --- /dev/null +++ b/src/qt/qt_vmmanager_main.ui @@ -0,0 +1,116 @@ + + + VMManagerMain + + + + 0 + 0 + 820 + 472 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + false + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 125 + 0 + + + + + + + + Qt::ClickFocus + + + Search + + + true + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + diff --git a/src/qt/qt_vmmanager_mainwindow.cpp b/src/qt/qt_vmmanager_mainwindow.cpp new file mode 100644 index 000000000..f6abc4674 --- /dev/null +++ b/src/qt/qt_vmmanager_mainwindow.cpp @@ -0,0 +1,231 @@ +/* +* 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. +* +* 86Box VM manager main window +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#include "qt_vmmanager_mainwindow.hpp" +#include "qt_vmmanager_main.hpp" +#include "qt_vmmanager_preferences.hpp" +#include "ui_qt_vmmanager_mainwindow.h" +#if EMU_BUILD_NUM != 0 +# include "qt_updatecheckdialog.hpp" +#endif +#include "qt_about.hpp" + +#include +#include +#include +#include +#include + +VMManagerMainWindow:: +VMManagerMainWindow(QWidget *parent) + : ui(new Ui::VMManagerMainWindow) + , vmm(new VMManagerMain(this)) + , statusLeft(new QLabel) + , statusRight(new QLabel) +{ + ui->setupUi(this); + + // Connect signals from the VMManagerMain widget + connect(vmm, &VMManagerMain::selectionChanged, this, &VMManagerMainWindow::vmmSelectionChanged); + + setWindowTitle(tr("%1 VM Manager").arg(EMU_NAME)); + setCentralWidget(vmm); + + // Set up the buttons + connect(ui->actionNew_Machine, &QAction::triggered, vmm, &VMManagerMain::newMachineWizard); + connect(ui->actionStartPause, &QAction::triggered, vmm, &VMManagerMain::startButtonPressed); + connect(ui->actionSettings, &QAction::triggered, vmm, &VMManagerMain::settingsButtonPressed); + connect(ui->actionHard_Reset, &QAction::triggered, vmm, &VMManagerMain::restartButtonPressed); + connect(ui->actionForce_Shutdown, &QAction::triggered, vmm, &VMManagerMain::shutdownForceButtonPressed); + + // Set up menu actions + // (Disable this if the EMU_BUILD_NUM == 0) + #if EMU_BUILD_NUM == 0 + ui->actionCheck_for_updates->setVisible(false); + #else + connect(ui->actionCheck_for_updates, &QAction::triggered, this, &VMManagerMainWindow::checkForUpdatesTriggered); + #endif + + // TODO: Remove all of this (all the way to END REMOVE) once certain the search will no longer be in the toolbar. + // BEGIN REMOVE + // Everything is still setup here for it but it is all hidden. None of it will be + // needed if the search stays in VMManagerMain + ui->actionStartPause->setEnabled(true); + ui->actionStartPause->setIcon(QIcon(":/menuicons/qt/icons/run.ico")); + ui->actionStartPause->setText(tr("Start")); + ui->actionStartPause->setToolTip(tr("Start")); + ui->actionHard_Reset->setEnabled(false); + ui->actionForce_Shutdown->setEnabled(false); + ui->actionCtrl_Alt_Del->setEnabled(false); + + const auto searchBar = new QLineEdit(); + searchBar->setMinimumWidth(150); + searchBar->setPlaceholderText(" " + tr("Search")); + searchBar->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + searchBar->setClearButtonEnabled(true); + // Spacer to make the search go all the way to the right + const auto spacer = new QWidget(); + spacer->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred); + ui->toolBar->addWidget(spacer); + ui->toolBar->addWidget(searchBar); + // Connect signal for search + connect(searchBar, &QLineEdit::textChanged, vmm, &VMManagerMain::searchSystems); + // Preferences + connect(ui->actionPreferences, &QAction::triggered, this, &VMManagerMainWindow::preferencesTriggered); + + // Create a completer for the search bar + auto *completer = new QCompleter(this); + completer->setCaseSensitivity(Qt::CaseInsensitive); + completer->setFilterMode(Qt::MatchContains); + // Get the completer list + const auto allStrings = vmm->getSearchCompletionList(); + // Set up the completer + auto *completerModel = new QStringListModel(allStrings, completer); + completer->setModel(completerModel); + searchBar->setCompleter(completer); +#ifdef Q_OS_WINDOWS + ui->toolBar->setBackgroundRole(QPalette::Light); +#endif + ui->toolBar->setVisible(false); + // END REMOVE + + // Status bar widgets + statusLeft->setAlignment(Qt::AlignLeft); + statusRight->setAlignment(Qt::AlignRight); + ui->statusbar->addPermanentWidget(statusLeft, 1); + ui->statusbar->addPermanentWidget(statusRight, 1); + connect(vmm, &VMManagerMain::updateStatusLeft, this, &VMManagerMainWindow::setStatusLeft); + connect(vmm, &VMManagerMain::updateStatusRight, this, &VMManagerMainWindow::setStatusRight); + + // Inform the main view when preferences are updated + connect(this, &VMManagerMainWindow::preferencesUpdated, vmm, &VMManagerMain::onPreferencesUpdated); + +} + +VMManagerMainWindow::~ +VMManagerMainWindow() + = default; + +void +VMManagerMainWindow::vmmSelectionChanged(const QModelIndex ¤tSelection, const QProcess::ProcessState processState) const +{ + if (processState == QProcess::Running) { + ui->actionStartPause->setEnabled(true); + ui->actionStartPause->setIcon(QIcon(":/menuicons/qt/icons/pause.ico")); + ui->actionStartPause->setText(tr("Pause")); + ui->actionStartPause->setToolTip(tr("Pause")); + disconnect(ui->actionStartPause, &QAction::triggered, vmm, &VMManagerMain::startButtonPressed); + connect(ui->actionStartPause, &QAction::triggered, vmm, &VMManagerMain::pauseButtonPressed); + ui->actionHard_Reset->setEnabled(true); + ui->actionForce_Shutdown->setEnabled(true); + ui->actionCtrl_Alt_Del->setEnabled(true); + } else { + ui->actionStartPause->setEnabled(true); + ui->actionStartPause->setIcon(QIcon(":/menuicons/qt/icons/run.ico")); + ui->actionStartPause->setText(tr("Start")); + ui->actionStartPause->setToolTip(tr("Start")); + disconnect(ui->actionStartPause, &QAction::triggered, vmm, &VMManagerMain::pauseButtonPressed); + connect(ui->actionStartPause, &QAction::triggered, vmm, &VMManagerMain::startButtonPressed); + ui->actionHard_Reset->setEnabled(false); + ui->actionForce_Shutdown->setEnabled(false); + ui->actionCtrl_Alt_Del->setEnabled(false); + } +} +void +VMManagerMainWindow::preferencesTriggered() +{ + const auto prefs = new VMManagerPreferences(); + if (prefs->exec() == QDialog::Accepted) { + emit preferencesUpdated(); + } +} + +void +VMManagerMainWindow::saveSettings() const +{ + const auto currentSelection = vmm->getCurrentSelection(); + const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); + config->setStringValue("last_selection", currentSelection); + // Sometimes required to ensure the settings save before the app exits + config->sync(); +} + +void +VMManagerMainWindow::closeEvent(QCloseEvent *event) +{ + int running = vmm->getActiveMachineCount(); + if (running > 0) { + QMessageBox warningbox(QMessageBox::Icon::Warning, tr("%1 VM Manager").arg(EMU_NAME), tr("%1 machine(s) are currently active. Are you sure you want to exit the VM manager anyway?").arg(running), QMessageBox::Yes | QMessageBox::No, this); + warningbox.exec(); + if (warningbox.result() == QMessageBox::No) { + event->ignore(); + return; + } + } + saveSettings(); + QMainWindow::closeEvent(event); +} + +void +VMManagerMainWindow::setStatusLeft(const QString &text) const +{ + statusLeft->setText(text); +} + +void +VMManagerMainWindow::setStatusRight(const QString &text) const +{ + statusRight->setText(text); +} + +#if EMU_BUILD_NUM != 0 +void +VMManagerMainWindow::checkForUpdatesTriggered() +{ + auto updateChannel = UpdateCheck::UpdateChannel::CI; +# ifdef RELEASE_BUILD + updateChannel = UpdateCheck::UpdateChannel::Stable; +# endif + const auto updateCheck = new UpdateCheckDialog(updateChannel, this); + updateCheck->exec(); +} +#endif + +void +VMManagerMainWindow::on_actionExit_triggered() +{ + this->close(); +} + +void +VMManagerMainWindow::on_actionAbout_Qt_triggered() +{ + QApplication::aboutQt(); +} + +void +VMManagerMainWindow::on_actionAbout_86Box_triggered() +{ + const auto msgBox = new About(this); + msgBox->exec(); +} + +void +VMManagerMainWindow::on_actionDocumentation_triggered() +{ + QDesktopServices::openUrl(QUrl(EMU_DOCS_URL)); +} diff --git a/src/qt/qt_vmmanager_mainwindow.hpp b/src/qt/qt_vmmanager_mainwindow.hpp new file mode 100644 index 000000000..ca7b0043d --- /dev/null +++ b/src/qt/qt_vmmanager_mainwindow.hpp @@ -0,0 +1,66 @@ +/* +* 86Box A hypervisor and IBM PC system emulator that specializes in +* running old operating systems and software designed for IBM +* PC systems and compatibles from 1981 through fairly recent +* system designs based on the PCI bus. +* +* This file is part of the 86Box distribution. +* +* Header for 86Box VM manager main window +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#ifndef VMM_MAINWINDOW_H +#define VMM_MAINWINDOW_H + +#include "qt_vmmanager_main.hpp" + +#include +#include +#include + +namespace Ui { +class VMManagerMainWindow; +} + +class VMManagerMainWindow final : public QMainWindow +{ + Q_OBJECT +public: + explicit VMManagerMainWindow(QWidget *parent = nullptr); + ~VMManagerMainWindow() override; +signals: + void preferencesUpdated(); + +private: + Ui::VMManagerMainWindow *ui; + VMManagerMain *vmm; + void saveSettings() const; + QLabel *statusLeft; + QLabel *statusRight; +public slots: + void setStatusLeft(const QString &text) const; + void setStatusRight(const QString &text) const; + +private slots: + void vmmSelectionChanged(const QModelIndex ¤tSelection, QProcess::ProcessState processState) const; + void preferencesTriggered(); +#if EMU_BUILD_NUM != 0 + void checkForUpdatesTriggered(); +#endif + + void on_actionExit_triggered(); + void on_actionDocumentation_triggered(); + void on_actionAbout_86Box_triggered(); + void on_actionAbout_Qt_triggered(); + +protected: + void closeEvent(QCloseEvent *event) override; +}; + +#endif // VMM_MAINWINDOW_H diff --git a/src/qt/qt_vmmanager_mainwindow.ui b/src/qt/qt_vmmanager_mainwindow.ui new file mode 100644 index 000000000..fa32241a4 --- /dev/null +++ b/src/qt/qt_vmmanager_mainwindow.ui @@ -0,0 +1,257 @@ + + + VMManagerMainWindow + + + + 0 + 0 + 900 + 600 + + + + MainWindow + + + + + + 0 + 0 + 900 + 21 + + + + + &Tools + + + + + + + &File + + + + + + + + &Help + + + + + + + + + + + + + true + + + toolBar + + + false + + + Qt::TopToolBarArea + + + + 16 + 16 + + + + Qt::ToolButtonIconOnly + + + TopToolBarArea + + + false + + + + + + + + + + + + true + + + + :/menuicons/qt/icons/run.ico:/menuicons/qt/icons/run.ico + + + &Start + + + false + + + + + + :/menuicons/qt/icons/hard_reset.ico:/menuicons/qt/icons/hard_reset.ico + + + &Hard Reset... + + + false + + + + + true + + + + :/menuicons/qt/icons/acpi_shutdown.ico:/menuicons/qt/icons/acpi_shutdown.ico + + + &Force shutdown + + + Force shutdown + + + true + + + false + + + + + false + + + + :/menuicons/qt/icons/send_cad.ico:/menuicons/qt/icons/send_cad.ico + + + &Ctrl+Alt+Del + + + Ctrl+Alt+Del + + + false + + + false + + + false + + + + + + :/menuicons/qt/icons/settings.ico:/menuicons/qt/icons/settings.ico + + + &Settings... + + + QAction::NoRole + + + false + + + + + + :/settings/qt/icons/86Box-yellow.ico:/settings/qt/icons/86Box-yellow.ico + + + &New machine... + + + New machine... + + + + + &Preferences... + + + Preferences... + + + QAction::PreferencesRole + + + + + true + + + + :/menuicons/qt/icons/run.ico:/menuicons/qt/icons/run.ico + + + &Start + + + false + + + + + &Check for updates... + + + + + E&xit + + + QAction::QuitRole + + + + + &Documentation... + + + + + &About 86Box... + + + QAction::AboutRole + + + + + About &Qt + + + false + + + QAction::AboutQtRole + + + + + + + + diff --git a/src/qt/qt_vmmanager_model.cpp b/src/qt/qt_vmmanager_model.cpp new file mode 100644 index 000000000..76fcbffd6 --- /dev/null +++ b/src/qt/qt_vmmanager_model.cpp @@ -0,0 +1,180 @@ +/* +* 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. +* +* 86Box VM manager model module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed + */ + +#include +#include "qt_vmmanager_model.hpp" + +VMManagerModel::VMManagerModel() { + auto machines_vec = VMManagerSystem::scanForConfigs(); + for ( const auto& each_config : machines_vec) { + machines.append(each_config); + connect(each_config, &VMManagerSystem::itemDataChanged, this, &VMManagerModel::modelDataChanged); + } +} + +VMManagerModel::~VMManagerModel() { + for ( auto machine : machines) { + delete machine; + } +} + +int +VMManagerModel::rowCount(const QModelIndex &parent) const { + return machines.size(); +} + +QVariant +VMManagerModel::data(const QModelIndex &index, int role) const { + if (!index.isValid()) + return {}; + + if (index.row() >= machines.size()) + return {}; + + switch (role) { + case Qt::DisplayRole: + return machines.at(index.row())->displayName; + case ConfigName: + return machines.at(index.row())->config_name; + case ConfigDir: + return machines.at(index.row())->config_dir; + case ConfigFile: + return machines.at(index.row())->config_file.canonicalFilePath(); + case UUID: + return machines.at(index.row())->uuid; + case Notes: + return machines.at(index.row())->notes; + case SearchList: + return machines.at(index.row())->searchTerms; + case LastUsed: + return machines.at(index.row())->timestamp(); + case Icon: + return machines.at(index.row())->icon; + case Qt::ToolTipRole: + return machines.at(index.row())->shortened_dir; + case Qt::UserRole: + return machines.at(index.row())->getAll("General"); + case ProcessStatusString: + return machines.at(index.row())->getProcessStatusString(); + case ProcessStatus: + return QVariant::fromValue(machines.at(index.row())->getProcessStatus()); + default: + return {}; + } +} + +QVariant +VMManagerModel::headerData(int section, Qt::Orientation orientation, int role) const { + + if (role != Qt::DisplayRole) + return {}; + + if (orientation == Qt::Horizontal) + return QStringLiteral("Column %1").arg(section); + else + return QStringLiteral("Row %1").arg(section); +} + +VMManagerSystem * +VMManagerModel::getConfigObjectForIndex(const QModelIndex &index) const +{ + return machines.at(index.row()); +} +void +VMManagerModel::reload(QWidget* parent) +{ + // Scan for configs + auto machines_vec = VMManagerSystem::scanForConfigs(parent); + for (const auto &scanned_config : machines_vec) { + int found = 0; + for (const auto &existing_config : machines) { + if (*scanned_config == *existing_config) { + found = 1; + } + } + if (!found) { + addConfigToModel(scanned_config); + } + } + // TODO: Remove missing configs +} + +void +VMManagerModel::refreshConfigs() { + for ( const auto& each_config : machines) + each_config->reloadConfig(); +} + +QModelIndex +VMManagerModel::getIndexForConfigFile(const QFileInfo& config_file) +{ + int object_index = 0; + for (const auto& config_object: machines) { + if (config_object->config_file == config_file) { + return this->index(object_index); + } + object_index++; + } + return {}; +} + +void +VMManagerModel::addConfigToModel(VMManagerSystem *system_config) +{ + beginInsertRows(QModelIndex(), this->rowCount(QModelIndex()), this->rowCount(QModelIndex())); + machines.append(system_config); + connect(system_config, &VMManagerSystem::itemDataChanged, this, &VMManagerModel::modelDataChanged); + endInsertRows(); +} +void +VMManagerModel::modelDataChanged() +{ + // Inform the model + emit dataChanged(this->index(0), this->index(machines.size()-1)); + // Inform any interested observers + emit systemDataChanged(); +} + +void +VMManagerModel::updateDisplayName(const QModelIndex &index, const QString &newDisplayName) +{ + machines.at(index.row())->setDisplayName(newDisplayName); + modelDataChanged(); +} +QHash +VMManagerModel::getProcessStats() +{ + QHash stats; + for (const auto& system: machines) { + if (system->getProcessStatus() != VMManagerSystem::ProcessStatus::Stopped) { + auto statusString = system->getProcessStatusString(); + stats[statusString] += 1; + } + } + return stats; +} + +int +VMManagerModel::getActiveMachineCount() +{ + int running = 0; + for (const auto& system: machines) { + if (system->getProcessStatus() != VMManagerSystem::ProcessStatus::Stopped) + running++; + } + return running; +} \ No newline at end of file diff --git a/src/qt/qt_vmmanager_model.hpp b/src/qt/qt_vmmanager_model.hpp new file mode 100644 index 000000000..9fed1ca8c --- /dev/null +++ b/src/qt/qt_vmmanager_model.hpp @@ -0,0 +1,93 @@ +/* +* 86Box A hypervisor and IBM PC system emulator that specializes in +* running old operating systems and software designed for IBM +* PC systems and compatibles from 1981 through fairly recent +* system designs based on the PCI bus. +* +* This file is part of the 86Box distribution. +* +* Header for 86Box VM manager model module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed + */ + +#ifndef QT_VMMANAGER_MODEL_H +#define QT_VMMANAGER_MODEL_H + + +#include "qt_vmmanager_system.hpp" + +#include + +class VMManagerModel final : public QAbstractListModel { + + Q_OBJECT + +public: + // VMManagerModel(const QStringList &strings, QObject *parent = nullptr) + // : QAbstractListModel(parent), machines(strings) {} + VMManagerModel(); + ~VMManagerModel() override; + enum Roles { + ProcessStatusString = Qt::UserRole + 1, + ProcessStatus, + DisplayName, + ConfigName, + ConfigDir, + ConfigFile, + LastUsed, + UUID, + Notes, + SearchList, + Icon + }; + + [[nodiscard]] int rowCount(const QModelIndex &parent) const override; + [[nodiscard]] QVariant data(const QModelIndex &index, int role) const override; + [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, + int role) const override; + void addConfigToModel(VMManagerSystem *system_config); + + [[nodiscard]] VMManagerSystem * getConfigObjectForIndex(const QModelIndex &index) const; + QModelIndex getIndexForConfigFile(const QFileInfo& config_file); + void reload(QWidget* parent = nullptr); + void updateDisplayName(const QModelIndex &index, const QString &newDisplayName); + QHash getProcessStats(); + int getActiveMachineCount(); + void refreshConfigs(); +signals: + void systemDataChanged(); + +private: + QVector machines; + void modelDataChanged(); + +}; + +// Note: Custom QSortFilterProxyModel is included here instead of its own file as +// its only use is in this model + +class StringListProxyModel final : public QSortFilterProxyModel { +public: + explicit StringListProxyModel(QObject *parent = nullptr) : QSortFilterProxyModel(parent) {} + +protected: + [[nodiscard]] bool filterAcceptsRow(const int sourceRow, const QModelIndex &sourceParent) const override { + const QModelIndex index = sourceModel()->index(sourceRow, filterKeyColumn(), sourceParent); + + QStringList stringList = sourceModel()->data(index, VMManagerModel::Roles::SearchList).toStringList(); + + const QRegularExpression regex = filterRegularExpression(); + + const auto result = std::any_of(stringList.begin(), stringList.end(), [®ex](const QString &string) { + return regex.match(string).hasMatch(); + }); + return result; + } +}; + +#endif //QT_VMMANAGER_MODEL_H diff --git a/src/qt/qt_vmmanager_preferences.cpp b/src/qt/qt_vmmanager_preferences.cpp new file mode 100644 index 000000000..57f67c9b8 --- /dev/null +++ b/src/qt/qt_vmmanager_preferences.cpp @@ -0,0 +1,88 @@ +/* +* 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. +* +* 86Box VM manager preferences module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#include +#include + +#include "qt_vmmanager_preferences.hpp" +#include "qt_vmmanager_config.hpp" +#include "ui_qt_vmmanager_preferences.h" + +extern "C" { +#include <86box/86box.h> +} + +VMManagerPreferences:: +VMManagerPreferences(QWidget *parent) : ui(new Ui::VMManagerPreferences) +{ + ui->setupUi(this); + ui->dirSelectButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_DirIcon)); + connect(ui->dirSelectButton, &QPushButton::clicked, this, &VMManagerPreferences::chooseDirectoryLocation); + + const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); + const auto configSystemDir = config->getStringValue("system_directory"); + if(!configSystemDir.isEmpty()) { + // Prefer this one + ui->systemDirectory->setText(configSystemDir); + } else if(!QString(vmm_path).isEmpty()) { + // If specified on command line + ui->systemDirectory->setText(QDir(vmm_path).path()); + } + + // TODO: Defaults +#if EMU_BUILD_NUM != 0 + const auto configUpdateCheck = config->getStringValue("update_check").toInt(); + ui->updateCheckBox->setChecked(configUpdateCheck); +#else + ui->updateCheckBox->setVisible(false); +#endif + const auto useRegexSearch = config->getStringValue("regex_search").toInt(); + ui->regexSearchCheckBox->setChecked(useRegexSearch); + + +} + +VMManagerPreferences::~ +VMManagerPreferences() + = default; + +// Bad copy pasta from machine add +void +VMManagerPreferences::chooseDirectoryLocation() +{ + // TODO: FIXME: This is pulling in the CLI directory! Needs to be set properly elsewhere + const auto directory = QFileDialog::getExistingDirectory(this, "Choose directory", QDir(vmm_path).path()); + ui->systemDirectory->setText(QDir::toNativeSeparators(directory)); +} + +void +VMManagerPreferences::accept() +{ + const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); + config->setStringValue("system_directory", ui->systemDirectory->text()); +#if EMU_BUILD_NUM != 0 + config->setStringValue("update_check", ui->updateCheckBox->isChecked() ? "1" : "0"); +#endif + config->setStringValue("regex_search", ui->regexSearchCheckBox->isChecked() ? "1" : "0"); + QDialog::accept(); +} + +void +VMManagerPreferences::reject() +{ + QDialog::reject(); +} diff --git a/src/qt/qt_vmmanager_preferences.hpp b/src/qt/qt_vmmanager_preferences.hpp new file mode 100644 index 000000000..aedba862a --- /dev/null +++ b/src/qt/qt_vmmanager_preferences.hpp @@ -0,0 +1,46 @@ +/* +* 86Box A hypervisor and IBM PC system emulator that specializes in +* running old operating systems and software designed for IBM +* PC systems and compatibles from 1981 through fairly recent +* system designs based on the PCI bus. +* +* This file is part of the 86Box distribution. +* +* Header for 86Box VM manager preferences module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#ifndef VMMANAGER_PREFERENCES_H +#define VMMANAGER_PREFERENCES_H + +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class VMManagerPreferences; } +QT_END_NAMESPACE + + +class VMManagerPreferences final : public QDialog +{ + Q_OBJECT +public: + explicit VMManagerPreferences(QWidget *parent = nullptr); + ~VMManagerPreferences() override; + +private: + Ui::VMManagerPreferences *ui; + QString settingsFile; +private slots: + void chooseDirectoryLocation(); +protected: + void accept() override; + void reject() override; + +}; + +#endif // VMMANAGER_PREFERENCES_H diff --git a/src/qt/qt_vmmanager_preferences.ui b/src/qt/qt_vmmanager_preferences.ui new file mode 100644 index 000000000..1743a0bfb --- /dev/null +++ b/src/qt/qt_vmmanager_preferences.ui @@ -0,0 +1,130 @@ + + + VMManagerPreferences + + + + 0 + 0 + 400 + 300 + + + + Preferences + + + + + + System Directory: + + + + + + + + 0 + + + 0 + + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + Check for updates on startup + + + + + + + Use regular expressions in search box + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + VMManagerPreferences + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + VMManagerPreferences + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/qt/qt_vmmanager_protocol.cpp b/src/qt/qt_vmmanager_protocol.cpp new file mode 100644 index 000000000..bc1805411 --- /dev/null +++ b/src/qt/qt_vmmanager_protocol.cpp @@ -0,0 +1,135 @@ +/* +* 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. +* +* 86Box VM manager protocol module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed + */ + +#include "qt_vmmanager_protocol.hpp" +#include +#include +VMManagerProtocol::VMManagerProtocol(VMManagerProtocol::Sender sender) +{ + message_class = sender; +} + +VMManagerProtocol::~VMManagerProtocol() += default; + +QJsonObject +VMManagerProtocol::protocolManagerMessage(VMManagerProtocol::ManagerMessage message_type) +{ + auto json_message = constructDefaultObject(VMManagerProtocol::Sender::Manager); + json_message["message"] = managerMessageTypeToString(message_type); + return json_message; +} + +QJsonObject +VMManagerProtocol::protocolClientMessage(VMManagerProtocol::ClientMessage message_type) +{ + auto json_message = constructDefaultObject(VMManagerProtocol::Sender::Client); + json_message["message"] = clientMessageTypeToString(message_type); + return json_message; +} + +QString +VMManagerProtocol::managerMessageTypeToString(VMManagerProtocol::ManagerMessage message) +{ + QMetaEnum qme = QMetaEnum::fromType(); + return qme.valueToKey(static_cast(message)); +} + +QString +VMManagerProtocol::clientMessageTypeToString(VMManagerProtocol::ClientMessage message) +{ + QMetaEnum qme = QMetaEnum::fromType(); + return qme.valueToKey(static_cast(message)); +} + +QJsonObject +VMManagerProtocol::constructDefaultObject(VMManagerProtocol::Sender type) +{ + QJsonObject json_message; + QString sender_type = ( type == VMManagerProtocol::Sender::Client ) ? "Client" : "VMManager"; + json_message["type"] = QString(sender_type); + json_message["version"] = QStringLiteral(EMU_VERSION); + return json_message; +} +bool +VMManagerProtocol::hasRequiredFields(const QJsonObject& json_document) +{ + for (const auto& field : ProtocolRequiredFields) { + if (!json_document.contains(field)) { + qDebug("Received json missing field \"%s\"", qPrintable(field)); + return false; + } + } + return true; +} +VMManagerProtocol::ClientMessage +VMManagerProtocol::getClientMessageType(const QJsonObject &json_document) +{ + // FIXME: This key ("message") is hardcoded here. Make a hash which maps these + // required values. + QString message_type = json_document.value("message").toString(); + // Can't use switch with strings, manual compare + if (message_type == "Status") { + return VMManagerProtocol::ClientMessage::Status; + } else if (message_type == "WindowBlocked") { + return VMManagerProtocol::ClientMessage::WindowBlocked; + } else if (message_type == "WindowUnblocked") { + return VMManagerProtocol::ClientMessage::WindowUnblocked; + } else if (message_type == "RunningStateChanged") { + return VMManagerProtocol::ClientMessage::RunningStateChanged; + } else if (message_type == "ConfigurationChanged") { + return VMManagerProtocol::ClientMessage::ConfigurationChanged; + } else if (message_type == "WinIdMessage") { + return VMManagerProtocol::ClientMessage::WinIdMessage; + } + return VMManagerProtocol::ClientMessage::UnknownMessage; +} +VMManagerProtocol::ManagerMessage +VMManagerProtocol::getManagerMessageType(const QJsonObject &json_document) +{ + // FIXME: This key ("message") is hardcoded here. Make a hash which maps these + // required values. + QString message_type = json_document.value("message").toString(); + // Can't use switch with strings, manual compare + if (message_type == "RequestStatus") { + return VMManagerProtocol::ManagerMessage::RequestStatus; + } else if (message_type == "Pause") { + return VMManagerProtocol::ManagerMessage::Pause; + } if (message_type == "CtrlAltDel") { + return VMManagerProtocol::ManagerMessage::CtrlAltDel; + } if (message_type == "ShowSettings") { + return VMManagerProtocol::ManagerMessage::ShowSettings; + } if (message_type == "ResetVM") { + return VMManagerProtocol::ManagerMessage::ResetVM; + } if (message_type == "RequestShutdown") { + return VMManagerProtocol::ManagerMessage::RequestShutdown; + } if (message_type == "ForceShutdown") { + return VMManagerProtocol::ManagerMessage::ForceShutdown; + } + return VMManagerProtocol::ManagerMessage::UnknownMessage; +} +QJsonObject +VMManagerProtocol::getParams(const QJsonObject &json_document) +{ + // FIXME: This key ("params") is hardcoded here. Make a hash which maps these + // required values. + auto params_object = json_document.value("params"); + if (params_object.type() != QJsonValue::Object) { + return {}; + } + return params_object.toObject(); +} diff --git a/src/qt/qt_vmmanager_protocol.hpp b/src/qt/qt_vmmanager_protocol.hpp new file mode 100644 index 000000000..90f7e4eeb --- /dev/null +++ b/src/qt/qt_vmmanager_protocol.hpp @@ -0,0 +1,96 @@ +/* +* 86Box A hypervisor and IBM PC system emulator that specializes in +* running old operating systems and software designed for IBM +* PC systems and compatibles from 1981 through fairly recent +* system designs based on the PCI bus. +* +* This file is part of the 86Box distribution. +* +* Header for 86Box VM manager protocol module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed + */ + +#ifndef QT_VMMANAGER_PROTOCOL_H +#define QT_VMMANAGER_PROTOCOL_H + +#include +extern "C" { +#include <86box/version.h> +} + +static QVector ProtocolRequiredFields = { "type", "message" }; + +class VMManagerProtocol : QObject { + Q_OBJECT + +public: + enum class Sender { + Manager, + Client, + }; + Q_ENUM(Sender); + + enum class ManagerMessage { + RequestStatus, + Pause, + CtrlAltDel, + ShowSettings, + ResetVM, + RequestShutdown, + ForceShutdown, + UnknownMessage, + }; + + // This macro allows us to do a reverse lookup of the enum with `QMetaEnum` + Q_ENUM(ManagerMessage); + + enum class ClientMessage { + Status, + WindowBlocked, + WindowUnblocked, + RunningStateChanged, + ConfigurationChanged, + WinIdMessage, + UnknownMessage, + }; + Q_ENUM(ClientMessage); + + enum class WindowStatus { + WindowUnblocked = 0, + WindowBlocked, + }; + + enum class RunningState { + Running = 0, + Paused, + RunningWaiting, + PausedWaiting, + Unknown, + }; + Q_ENUM(RunningState); + + explicit VMManagerProtocol(Sender sender); + ~VMManagerProtocol(); + + QJsonObject protocolManagerMessage(ManagerMessage message_type); + QJsonObject protocolClientMessage(ClientMessage message_type); + static QString managerMessageTypeToString(ManagerMessage message); + static QString clientMessageTypeToString(ClientMessage message); + + static bool hasRequiredFields(const QJsonObject &json_document); + static QJsonObject getParams(const QJsonObject &json_document); + static QJsonObject getStatus(const QJsonObject &json_document); + static ClientMessage getClientMessageType(const QJsonObject &json_document); + static ManagerMessage getManagerMessageType(const QJsonObject &json_document); + +private: + Sender message_class; + static QJsonObject constructDefaultObject(VMManagerProtocol::Sender type); +}; + +#endif // QT_VMMANAGER_PROTOCOL_H diff --git a/src/qt/qt_vmmanager_serversocket.cpp b/src/qt/qt_vmmanager_serversocket.cpp new file mode 100644 index 000000000..1364ff794 --- /dev/null +++ b/src/qt/qt_vmmanager_serversocket.cpp @@ -0,0 +1,221 @@ +/* +* 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. +* +* 86Box VM manager server socket module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed + */ + +#include "qt_vmmanager_serversocket.hpp" +#include +#include +#include +#include +#include +#include + +VMManagerServerSocket::VMManagerServerSocket(const QFileInfo &config_path, const ServerType type) +{ + server_type = type; + config_file = config_path; + serverIsRunning = false; + socket = nullptr; + server = new QLocalServer; + setupVars(); +} + +VMManagerServerSocket::~VMManagerServerSocket() +{ + delete server; +} + +bool +VMManagerServerSocket::startServer() { + + // Remove socket file (if it exists) in order to start a new one + qInfo("Socket path is %s", qPrintable(socket_path.filePath())); + if (socket_path.exists() and !socket_path.isDir()) { + auto socket_file = new QFile(socket_path.filePath()); + if (!socket_file->remove()) { + qInfo("Failed to remove the old socket file (Error %i): %s", socket_file->error(), qPrintable(socket_file->errorString())); + return false; + } + } + + if (server->listen(socket_path.fileName())) { + serverIsRunning = true; + connect(server, &QLocalServer::newConnection, this, &VMManagerServerSocket::serverConnectionReceived); + return true; + } else { + qInfo("Failed to start server: %s", qPrintable(server->errorString())); + serverIsRunning = false; + return false; + } +} + +void +VMManagerServerSocket::serverConnectionReceived() { + qDebug("Connection received on %s", qPrintable(socket_path.fileName())); + socket = server->nextPendingConnection(); + if(!socket) { + qInfo("Invalid socket when trying to receive the connection"); + return; + } + connect(socket, &QLocalSocket::readyRead, this, &VMManagerServerSocket::serverReceivedMessage); + connect(socket, &QLocalSocket::disconnected, this, &VMManagerServerSocket::serverDisconnected); +} + +void +VMManagerServerSocket::serverReceivedMessage() { + + // Handle legacy socket connections first. These connections only receive + // information on window status + if(server_type == VMManagerServerSocket::ServerType::Legacy) { + QByteArray tempString = socket->read(1); + int window_obscured = tempString.toInt(); + emit windowStatusChanged(window_obscured); + return; + } + + // Normal connections here + QDataStream stream(socket); + stream.setVersion(QDataStream::Qt_5_7); + QByteArray jsonData; + for (;;) { + // Start a transaction + stream.startTransaction(); + // Try to read the data + stream >> jsonData; + if (stream.commitTransaction()) { + QJsonParseError parse_error{}; + // Validate the received data to make sure it's valid json + const QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parse_error); + if (parse_error.error == QJsonParseError::NoError) { + // The data received was valid json + if (jsonDoc.isObject()) { + // The data is a valid json object + emit dataReceived(); + jsonReceived(jsonDoc.object()); + } + } + // The data was not valid json. + // Loop and try to read more data + } else { + // read failed, socket is reverted to its previous state (before the transaction) + // exit the loop and wait for more data to become available + break; + } + } +} + +void +VMManagerServerSocket::serverSendMessage(VMManagerProtocol::ManagerMessage protocol_message, const QStringList& arguments) const { + if(!socket) { + qInfo("Cannot send message: Invalid socket"); + return; + } + + // Regular connection + QDataStream stream(socket); + stream.setVersion(QDataStream::Qt_5_7); + auto packet = new VMManagerProtocol(VMManagerProtocol::Sender::Manager); + auto jsonMessage = packet->protocolManagerMessage(protocol_message); + stream << QJsonDocument(jsonMessage).toJson(QJsonDocument::Compact); +} + +void +VMManagerServerSocket::serverDisconnected() +{ + qInfo("Connection disconnected"); +} +void +VMManagerServerSocket::jsonReceived(const QJsonObject &json) +{ + // The serialization portion has already validated the message as json. + // Now ensure it has the required fields. + if (!VMManagerProtocol::hasRequiredFields(json)) { + // TODO: Error handling of some sort, emit signals + qDebug("Invalid message received from client: required fields missing. Object:"); + qDebug() << json; + return; + } +// qDebug().noquote() << Q_FUNC_INFO << json; + QJsonObject params_object; + + auto message_type = VMManagerProtocol::getClientMessageType(json); + switch (message_type) { + case VMManagerProtocol::ClientMessage::WinIdMessage: + qDebug("WinId message received from client"); + params_object = VMManagerProtocol::getParams(json); + if (!params_object.isEmpty()) { + // valid object + if(params_object.value("params").type() == QJsonValue::Double) { + emit winIdReceived(params_object.value("params").toVariant().toULongLong()); + } + } + break; + case VMManagerProtocol::ClientMessage::Status: + qDebug("Status message received from client"); + break; + case VMManagerProtocol::ClientMessage::WindowBlocked: + qDebug("Window blocked message received from client"); + emit windowStatusChanged(static_cast(VMManagerProtocol::WindowStatus::WindowBlocked)); + break; + case VMManagerProtocol::ClientMessage::WindowUnblocked: + qDebug("Window unblocked received from client"); + emit windowStatusChanged(static_cast(VMManagerProtocol::WindowStatus::WindowUnblocked)); + break; + case VMManagerProtocol::ClientMessage::RunningStateChanged: + qDebug("Running state change received from client"); + params_object = VMManagerProtocol::getParams(json); + if (!params_object.isEmpty()) { + // valid object + if(params_object.value("status").type() == QJsonValue::Double) { + // has status key, value is an int (qt assigns it as Double) + emit runningStatusChanged(static_cast(params_object.value("status").toInt())); + } + } + break; + case VMManagerProtocol::ClientMessage::ConfigurationChanged: + qDebug("Configuration change received from client"); + emit configurationChanged(); + break; + default: + qDebug("Unknown client message type received:"); + qDebug() << json; + return; + } +} + +void +VMManagerServerSocket::setupVars() +{ + QString unique_name = QCryptographicHash::hash(config_file.path().toUtf8().constData(), QCryptographicHash::Algorithm::Sha256).toHex().right(6); + socket_path.setFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + QApplication::applicationName() + ".socket." + unique_name); +} + +QString +VMManagerServerSocket::getSocketPath() const +{ + if (server) { + return server->fullServerName(); + } + return {}; +} + +QString +VMManagerServerSocket::serverTypeToString(VMManagerServerSocket::ServerType server_type_lookup) +{ + QMetaEnum qme = QMetaEnum::fromType(); + return qme.valueToKey(static_cast(server_type_lookup)); + +} diff --git a/src/qt/qt_vmmanager_serversocket.hpp b/src/qt/qt_vmmanager_serversocket.hpp new file mode 100644 index 000000000..30ad02b2c --- /dev/null +++ b/src/qt/qt_vmmanager_serversocket.hpp @@ -0,0 +1,84 @@ +/* +* 86Box A hypervisor and IBM PC system emulator that specializes in +* running old operating systems and software designed for IBM +* PC systems and compatibles from 1981 through fairly recent +* system designs based on the PCI bus. +* +* This file is part of the 86Box distribution. +* +* Header for 86Box VM manager server socket module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed + */ + +#ifndef QT_VMMANAGER_SERVERSOCKET_H +#define QT_VMMANAGER_SERVERSOCKET_H + +#include +#include +#include +#include +#include +#include "qt_vmmanager_protocol.hpp" + +// This macro helps give us the required `qHash()` function in order to use the +// enum as a hash key +#define QHASH_FOR_CLASS_ENUM(T) \ +inline uint qHash(const T &t, uint seed) { \ + return ::qHash(static_cast::type>(t), seed); \ +} + +class VMManagerServerSocket : public QWidget { + + Q_OBJECT + +public: + + enum class ServerType { + Standard, + Legacy, + }; + // This macro allows us to do a reverse lookup of the enum with `QMetaEnum` + Q_ENUM(ServerType) + + QHASH_FOR_CLASS_ENUM(ServerType) + + explicit VMManagerServerSocket(const QFileInfo &config_path, ServerType type = ServerType::Standard); + ~VMManagerServerSocket() override; + + QFileInfo socket_path; + QFileInfo config_file; + + QLocalServer *server; + QLocalSocket *socket; + ServerType server_type; + bool serverIsRunning; + + // Server functions + bool startServer(); + void serverConnectionReceived(); + void serverReceivedMessage(); + void serverSendMessage(VMManagerProtocol::ManagerMessage protocol_message, const QStringList& arguments = QStringList()) const; + static void serverDisconnected(); + void jsonReceived(const QJsonObject &json); + QString getSocketPath() const; + + static QString serverTypeToString(ServerType server_type_lookup); + + void setupVars(); + +signals: + void dataReceived(); + void windowStatusChanged(int status); + void runningStatusChanged(VMManagerProtocol::RunningState state); + void configurationChanged(); + void winIdReceived(WId id); + + +}; + +#endif // QT_VMMANAGER_SERVERSOCKET_H diff --git a/src/qt/qt_vmmanager_system.cpp b/src/qt/qt_vmmanager_system.cpp new file mode 100644 index 000000000..fadc5aa61 --- /dev/null +++ b/src/qt/qt_vmmanager_system.cpp @@ -0,0 +1,1241 @@ +/* +* 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. +* +* 86Box VM manager system module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qt_util.hpp" +#include "qt_vmmanager_system.hpp" +// #include "qt_vmmanager_details_section.hpp" +#include "qt_vmmanager_detailsection.hpp" + +#ifdef Q_OS_WINDOWS +#include +#endif + + +extern "C" { +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/video.h> +// #include <86box/vid_xga_device.h> +#include <86box/machine.h> +#include <86box/plat.h> +#include <86box/sound.h> +#include +#include <86box/thread.h> // required for network.h +#include <86box/timer.h> // required for network.h and fdd.h +#include <86box/cdrom.h> +#include <86box/cdrom_interface.h> +#include <86box/scsi.h> +#include <86box/scsi_device.h> // required for rdisk.h and mo.h +#include <86box/rdisk.h> +#include <86box/mo.h> +#include <86box/fdd.h> +#include <86box/fdc_ext.h> +#include <86box/hdc.h> +#include <86box/gameport.h> +#include <86box/isartc.h> +#include <86box/isamem.h> +#include <86box/isarom.h> +#include <86box/lpt.h> +#include <86box/midi.h> +#include <86box/network.h> +#include <86box/keyboard.h> +#include <86box/mouse.h> +} + +using namespace VMManager; + +VMManagerSystem::VMManagerSystem(const QString &sysconfig_file) { + + // The 86Box configuration file + config_file = QFileInfo(sysconfig_file); + // The default name of the system. This is the name of the directory + // that contains the 86box configuration file + config_name = config_file.dir().dirName(); + // The full path of the directory that contains the 86box configuration file + config_dir = shortened_dir = config_file.dir().absolutePath(); + process_status = ProcessStatus::Stopped; + // In the configuration file the UUID is used as a unique value + uuid = util::generateUuid(sysconfig_file); + // That unique value is used to map the information to each individual system. + config_settings = new VMManagerConfig(VMManagerConfig::ConfigType::System, uuid); + + // On non-windows platforms, shortened_dir will replace the home directory path with ~ + // and be used as the tool tip in the list view +#if not defined(Q_OS_WINDOWS) + if (config_dir.startsWith(QDir::homePath())) { + shortened_dir.replace(QDir::homePath(), "~"); + } +#endif + loadSettings(); + setupPaths(); + // Paths must be setup before vars! + setupVars(); + + serverIsRunning = false; + window_obscured = false; + + find86BoxBinary(); + platform = QApplication::platformName(); + process = new QProcess(); + connect(process, &QProcess::stateChanged, this, &VMManagerSystem::processStatusChanged); + + // Server type for this instance (Standard should always be used instead of Legacy) + socket_server_type = VMManagerServerSocket::ServerType::Standard; + socket_server = new VMManagerServerSocket(config_file, socket_server_type); + + // NOTE: When unique names or UUIDs are written to the individual VM config file, use that + // here instead of the auto-generated unique_name + // Save settings once everything is initialized + saveSettings(); +} + +VMManagerSystem::~VMManagerSystem() { + delete socket_server; +} + +QVector +VMManagerSystem::scanForConfigs(QWidget* parent, const QString &searchPath) +{ + QProgressDialog progDialog(parent); + unsigned int found = 0; + progDialog.setCancelButton(nullptr); + progDialog.setWindowTitle(tr("Searching for VMs...")); + progDialog.setMinimumDuration(0); + progDialog.setValue(0); + progDialog.setMinimum(0); + progDialog.setMaximum(0); + progDialog.setWindowFlags(progDialog.windowFlags() & ~Qt::WindowCloseButtonHint); + progDialog.setFixedSize(progDialog.sizeHint()); + QElapsedTimer scanTimer; + scanTimer.start(); + QVector system_configs; + + const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); + auto systemDirConfig = config->getStringValue("system_directory"); + + const auto config_file_name = QString("86box.cfg"); + const QStringList filters = {config_file_name}; + QStringList matches; + // TODO: Preferences. Once I get the CLI args worked out. + // For now it just takes vmm_path from the CLI + QString search_directory; + // if(searchPath.isEmpty()) { + // // If the location isn't specified in function call, use the one loaded + // // from the config file + // search_directory = systemDirConfig; + // } else { + // search_directory = searchPath; + // } + + search_directory = searchPath.isEmpty()? vmm_path : searchPath; + + if(!QDir(search_directory).exists()) { + //qWarning() << "Path" << search_directory << "does not exist. Cannot continue"; + QDir(search_directory).mkpath("."); + //return {}; + } + + QDirIterator dir_iterator(search_directory, filters, QDir::Files, QDirIterator::Subdirectories); + + qInfo("Searching %s for %s", qPrintable(search_directory), qPrintable(config_file_name)); + + QElapsedTimer timer; + timer.start(); + while (dir_iterator.hasNext()) { + found++; + progDialog.setLabelText(tr("Found %1").arg(QString::number(found))); + QApplication::processEvents(); + QString filename = dir_iterator.next(); + matches.append(filename); + } + + const auto scanElapsed = timer.elapsed(); + qDebug().noquote().nospace() << "Found " << matches.size() << " configs in " << search_directory <<". Scan took " << scanElapsed << " ms"; + + timer.restart(); + // foreach (QFileInfo hit, matches) { + // system_configs.append(new VMManagerSystem(hit)); + // } + progDialog.setMaximum(found); + progDialog.setValue(0); + unsigned int appended = 0; + for (const auto &filename : matches) { + system_configs.append(new VMManagerSystem(filename)); + appended++; + progDialog.setLabelText(system_configs.last()->displayName); + progDialog.setValue(appended); + QApplication::processEvents(); + } + if (matches.size()) { + auto elapsed = timer.elapsed(); + qDebug() << "Load loop took" << elapsed << "ms for" << matches.size() << "loads"; + qDebug() << "Overall scan time was" << scanTimer.elapsed() << "ms, average" << elapsed / matches.size() << "ms / load"; + } + return system_configs; +} + +QString +VMManagerSystem::generateTemporaryFilename() +{ + QTemporaryFile tempFile; + // File will be closed once the QTemporaryFile object goes out of scope + tempFile.setAutoRemove(true); + tempFile.open(); + return tempFile.fileName(); +} + +QFileInfoList +VMManagerSystem::getScreenshots() { + + // Don't bother unless the directory exists + if(!screenshot_directory.exists()) { + return {}; + } + + auto screen_scan_dir = QDir(screenshot_directory.path(), "Monitor_1*", QDir::SortFlag::LocaleAware | QDir::SortFlag::IgnoreCase, QDir::Files); + auto screenshot_files = screen_scan_dir.entryInfoList(); + return screenshot_files; +} + +void +VMManagerSystem::loadSettings() +{ + // First, load the information from the 86box.cfg + QSettings settings(config_file.filePath(), QSettings::IniFormat); + if (settings.status() != QSettings::NoError) { + qWarning() << "Error loading" << config_file.path() << " status:" << settings.status(); + } + // qInfo() << "Loaded "<< config_file.filePath() << "status:" << settings.status(); + + // Clear out the config hash in case the config is reloaded + for (const auto &outer_key : config_hash.keys()) { + config_hash[outer_key].clear(); + } + + // General + for (const auto &key_name : settings.childKeys()) { + config_hash["General"][key_name] = settings.value(key_name).toString(); + } + + for (auto &group_name : settings.childGroups()) { + settings.beginGroup(group_name); + for (const auto &key_name : settings.allKeys()) { + QString setting_value; + // QSettings will interpret lines with commas as QStringList. + // Check for it and join them back to a string. + if (settings.value(key_name).type() == QVariant::StringList) { + setting_value = settings.value(key_name).toStringList().join(", "); + } else { + setting_value = settings.value(key_name).toString(); + } + config_hash[group_name][key_name] = setting_value; + } + settings.endGroup(); + } + + // Next, load the information from the vmm config for this system + // Display name + auto loadedDisplayName = config_settings->getStringValue("display_name"); + if (!loadedDisplayName.isEmpty()) { + displayName = loadedDisplayName; + } else { + displayName = config_name; + } + // Notes + auto loadedNotes = config_settings->getStringValue("notes"); + if (!loadedNotes.isEmpty()) { + notes = loadedNotes; + } + // Timestamp + auto loadedTimestamp = config_settings->getStringValue("timestamp"); + if (!loadedTimestamp.isEmpty()) { + // Make sure it is valid + if (auto newTimestamp = QDateTime::fromString(loadedTimestamp, Qt::ISODate); newTimestamp.isValid()) { + lastUsedTimestamp = newTimestamp; + } + } + // Icon + auto loadedIcon = config_settings->getStringValue("icon"); + if (!loadedIcon.isEmpty()) { + icon = loadedIcon; + } +} +void +VMManagerSystem::saveSettings() +{ + if(!isValid()) { + return; + } + config_settings->setStringValue("system_name", config_name); + config_settings->setStringValue("config_file", config_file.canonicalFilePath()); + config_settings->setStringValue("config_dir", config_file.canonicalPath()); + if (displayName != config_name) { + config_settings->setStringValue("display_name", displayName); + } else { + config_settings->remove("display_name"); + } + + config_settings->setStringValue("notes", notes); + if(lastUsedTimestamp.isValid()) { + config_settings->setStringValue("timestamp", lastUsedTimestamp.toString(Qt::ISODate)); + } + config_settings->setStringValue("icon", icon); + generateSearchTerms(); +} +void +VMManagerSystem::generateSearchTerms() +{ + searchTerms.clear(); + for (const auto &config_key : config_hash.keys()) { + // searchTerms.append(config_hash[config_key].values()); + // brute force temporarily don't add paths + for(const auto &value: config_hash[config_key].values()) { + if(!value.startsWith("/")) { + searchTerms.append(value); + } + } + } + searchTerms.append(display_table.values()); + searchTerms.append(displayName); + searchTerms.append(config_name); + QRegularExpression whitespaceRegex("\\s+"); + searchTerms.append(notes.split(whitespaceRegex)); +} +void +VMManagerSystem::updateTimestamp() +{ + lastUsedTimestamp = QDateTime::currentDateTimeUtc(); + saveSettings(); +} + +QString +VMManagerSystem::getAll(const QString& category) const { + auto value = config_hash[category].keys().join(", "); + return value; +} + +QHash> +VMManagerSystem::getConfigHash() const +{ + return config_hash; +} + +void +VMManagerSystem::setDisplayName(const QString &newDisplayName) +{ + // If blank, reset to the default + if (newDisplayName.isEmpty()) { + displayName = config_name; + } else { + displayName = newDisplayName; + } + saveSettings(); +} +void +VMManagerSystem::setNotes(const QString &newNotes) +{ + notes = newNotes; + saveSettings(); +} +bool +VMManagerSystem::isValid() const +{ + return config_file.exists() && config_file.isFile() && config_file.size() != 0; +} + +bool +VMManagerSystem::isProcessRunning() const +{ + return process->processId() != 0; +} + +qint64 +VMManagerSystem::processId() const +{ + return process->processId(); +} + +QHash +VMManagerSystem::getCategory(const QString &category) const { + return config_hash[category]; +} + +void +VMManagerSystem::find86BoxBinary() { + // We'll use our own self to launch the VMs + main_binary = QFileInfo(QCoreApplication::applicationFilePath()); +} + +bool +VMManagerSystem::has86BoxBinary() { + return main_binary.exists(); +} + +void +VMManagerSystem::launchMainProcess() { + + if(!has86BoxBinary()) { + qWarning("No binary found! returning"); + return; + } + + // start the server first to get the socket name + if (!serverIsRunning) { + if(!startServer()) { + // FIXME: Better error handling + qInfo("Failed to start VM Manager server"); + return; + } + } + // If the system is already running, bring it to front + if (process->processId() != 0) { +#ifdef Q_OS_WINDOWS + if (this->id) { + SetForegroundWindow((HWND)this->id); + } +#endif + return; + } + setProcessEnvVars(); + QString program = main_binary.filePath(); + QStringList args; + args << "--vmpath" << config_dir; + args << "--vmname" << displayName; + process->setProgram(program); + process->setArguments(args); + qDebug() << Q_FUNC_INFO << " Full Command:" << process->program() << " " << process->arguments(); + process->start(); + updateTimestamp(); + + connect(process, QOverload::of(&QProcess::finished), + [=](const int exitCode, const QProcess::ExitStatus exitStatus){ + if (exitCode != 0 || exitStatus != QProcess::NormalExit) { + qInfo().nospace().noquote() << "Abnormal program termination while launching main process: exit code " << exitCode << ", exit status " << exitStatus; + return; + } + }); +} + +void +VMManagerSystem::startButtonPressed() { + launchMainProcess(); +} + +void +VMManagerSystem::launchSettings() { + if(!has86BoxBinary()) { + qWarning("No binary found! returning"); + return; + } + + // start the server first to get the socket name + if (!serverIsRunning) { + if(!startServer()) { + // FIXME: Better error handling + qInfo("Failed to start VM Manager server"); + return; + } + } + + // If the system is already running, instruct it to show settings + if (process->processId() != 0) { +#ifdef Q_OS_WINDOWS + if (this->id) { + SetForegroundWindow((HWND)this->id); + } +#endif + socket_server->serverSendMessage(VMManagerProtocol::ManagerMessage::ShowSettings); + return; + } + + // Otherwise, launch the system with the settings parameter + setProcessEnvVars(); + window_obscured = true; + QString program = main_binary.filePath(); + QStringList open_command_args; + QStringList args; + args << "--vmpath" << config_dir << "--settings"; + process->setProgram(program); + process->setArguments(args); + qDebug() << Q_FUNC_INFO << " Full Command:" << process->program() << " " << process->arguments(); + process->start(); + + connect(process, QOverload::of(&QProcess::finished), + [=](const int exitCode, const QProcess::ExitStatus exitStatus){ + if (exitCode != 0 || exitStatus != QProcess::NormalExit) { + qInfo().nospace().noquote() << "Abnormal program termination while launching settings: exit code " << exitCode << ", exit status " << exitStatus; + return; + } + + configurationChangeReceived(); + }); +} + +void +VMManagerSystem::setupPaths() { + // application_temp_directory.setPath(QStandardPaths::writableLocation(QStandardPaths::TempLocation)); + // standard_temp_directory.setPath(QStandardPaths::writableLocation(QStandardPaths::TempLocation)); + // QString temp_subdir = QApplication::applicationName(); + // if (!application_temp_directory.exists(temp_subdir)) { + // // FIXME: error checking + // application_temp_directory.mkdir(temp_subdir); + // } + // // QT always replaces `/` with native separators, so it is safe to use here for all platforms + // application_temp_directory.setPath(application_temp_directory.path() + "/" + temp_subdir); + // app_data_directory.setPath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + // // TODO: come back here and update with the new plat_get_global_* + // if (!app_data_directory.exists()) { + // // FIXME: Error checking + // app_data_directory.mkpath(app_data_directory.path()); + // } + screenshot_directory.setPath(config_dir + "/" + "screenshots"); +} + +void +VMManagerSystem::setupVars() { + unique_name = QCryptographicHash::hash(config_file.path().toUtf8().constData(), QCryptographicHash::Algorithm::Sha256).toHex().right(9); + // unique_name = "aaaaaa"; + // Set up the display vars + // This will likely get moved out to its own class + // This will likely get moved out to its own class + auto machine_config = getCategory("Machine"); + auto video_config = getCategory("Video"); + auto disk_config = getCategory("Hard disks"); + auto audio_config = getCategory("Sound"); + auto network_config = getCategory("Network"); + auto input_config = getCategory("Input devices"); + auto floppy_cdrom_config = getCategory("Floppy and CD-ROM drives"); + auto rdisk_mo_config = getCategory("Other removable devices"); + auto storage_config = getCategory("Storage controllers"); + auto ports_config = getCategory("Ports (COM & LPT)"); + auto other_config = getCategory("Other peripherals"); + // auto general_config = getCategory("General"); + // auto config_uuid = QString("Not set"); + // if(!general_config["uuid"].isEmpty()) { + // config_uuid = general_config["uuid"]; + // qDebug() << "btw config dir:" << config_dir; + // } + // qDebug() << "Generated UUID:" << uuid; + // qDebug() << "Config file UUID:" << config_uuid; + auto machine_name = QString(); + int i = 0; + int ram_granularity = 0; + // Machine + for (int ci = 0; ci < machine_count(); ++ci) { + if (machine_available(ci)) { + if (machines[ci].internal_name == machine_config["machine"]) { + machine_name = machines[ci].name; + ram_granularity = machines[ci].ram.step; + } + } + } + display_table[Display::Name::Machine] = machine_name; + + // CPU: Combine name with speed and FPU + QString cpu_name = "Unknown"; + while (cpu_families[i].package != 0) { + if (cpu_families[i].internal_name == machine_config["cpu_family"]) { + int j = 0; + cpu_name = QString("%1 %2").arg(cpu_families[i].manufacturer, cpu_families[i].name); + while (cpu_families[i].cpus[j].cpu_type != 0) { + if (cpu_families[i].cpus[j].rspeed == machine_config["cpu_speed"].toUInt()) { + auto cpu_speed = QString(cpu_families[i].cpus[j].name).split("/").at(0).split(" (").at(0); + cpu_name.append(cpu_speed.prepend(" / ")); + cpu_name.append(QCoreApplication::translate("", "MHz").prepend(' ')); + if (machine_config.contains("fpu_type") && (machine_config["fpu_type"] != QString("none")) && (machine_config["fpu_type"] != QString("internal"))) { + int k = 0; + while (cpu_families[i].cpus[j].fpus[k].internal_name != nullptr) { + if (QString(cpu_families[i].cpus[j].fpus[k].internal_name) == machine_config["fpu_type"]) { + cpu_name.append(QString(cpu_families[i].cpus[j].fpus[k].name).prepend(", ")); + cpu_name.append(QCoreApplication::translate("", "FPU").prepend(' ')); + break; + } + k++; + } + } + break; + } + j++; + } + break; + } + i++; + } +// int speed_display = machine_config["cpu_speed"].toInt() / 1000000; +// cpu_name.append(QString::number(speed_display).prepend(" / ")); +// cpu_name.append(QCoreApplication::translate("", "MHz").prepend(' ')); + display_table[Display::Name::CPU] = cpu_name; + + // Memory + int divisor = (ram_granularity < 1024) ? 1 : 1024; + QString display_unit = (divisor == 1) ? "KB" : "MB"; + auto mem_display = QString::number(machine_config["mem_size"].toInt() / divisor); + mem_display.append(QCoreApplication::translate("", display_unit.toUtf8().constData()).prepend(' ')); + display_table[Display::Name::Memory] = mem_display; + + // Video card + int video_int = video_get_video_from_internal_name(video_config["gfxcard"].toUtf8().data()); + const device_t* video_dev = video_card_getdevice(video_int); + display_table[Display::Name::Video] = DeviceConfig::DeviceName(video_dev, video_get_internal_name(video_int), 1); + + // Secondary video + if (video_config.contains("gfxcard_2")) { + int video2_int = video_get_video_from_internal_name(video_config["gfxcard_2"].toUtf8().data()); + const device_t* video2_dev = video_card_getdevice(video2_int); + display_table[Display::Name::Video].append(DeviceConfig::DeviceName(video2_dev, video_get_internal_name(video2_int), 1).prepend(VMManagerDetailSection::sectionSeparator)); + } + + // Add-on video that's not Voodoo + if (video_config.contains("8514a") && (video_config["8514a"].toInt() != 0)) + display_table[Display::Name::Video].append(tr("IBM 8514/A Graphics").prepend(VMManagerDetailSection::sectionSeparator)); + if (video_config.contains("xga") && (video_config["xga"].toInt() != 0)) + display_table[Display::Name::Video].append(tr("XGA Graphics").prepend(VMManagerDetailSection::sectionSeparator)); + if (video_config.contains("da2") && (video_config["da2"].toInt() != 0)) + display_table[Display::Name::Video].append(tr("IBM PS/55 Display Adapter Graphics").prepend(VMManagerDetailSection::sectionSeparator)); + + // Voodoo + if (video_config.contains("voodoo") && (video_config["voodoo"].toInt() != 0)) { + auto voodoo_config = getCategory(DeviceConfig::DeviceName(&voodoo_device, "voodoo", 0)); + int voodoo_type = voodoo_config["type"].toInt(); + QString voodoo_name; + switch (voodoo_type) { + case 0: + default: + voodoo_name = tr("3Dfx Voodoo Graphics"); + break; + case 1: + voodoo_name = tr("Obsidian SB50 + Amethyst (2 TMUs)"); + break; + case 2: + voodoo_name = tr("3Dfx Voodoo 2"); + break; + } + display_table[Display::Name::Voodoo] = voodoo_name; + } + + // Drives + // First the number of disks + QMap disks; + for(const auto& key: disk_config.keys()) { + // Assuming the format hdd_NN_* + QStringList pieces = key.split('_'); + QString disk = QString("%1_%2").arg(pieces.at(0), pieces.at(1)); + if(!disk.isEmpty()) { + disks[disk] = 1; + } + } + // Next, the types + QHash bus_types; + for (const auto& key: disks.keys()) { + auto disk_parameter_key = QString("%1_parameters").arg(key); + QStringList pieces = disk_config[disk_parameter_key].split(","); + QString bus_type = pieces.value(pieces.length() - 1).trimmed(); + bus_types[bus_type] = 1; + } + QString disks_display = tr("%n disk(s)", "", disks.count()); + if (disks.count()) { + disks_display.append(" / ").append(bus_types.keys().join(", ").toUpper()); + } +// display_table[Display::Name::Disks] = disks_display; + + // Drives + QString new_disk_display; + for (const auto& key: disks.keys()) { + auto disk_parameter_key = QString("%1_parameters").arg(key); + // Converting a string to an int back to a string to remove the zero (e.g. 01 to 1) + auto disk_number = QString::number(key.split("_").last().toInt()); + QStringList pieces = disk_config[disk_parameter_key].split(","); + QString sectors = pieces.value(0).trimmed(); + QString heads = pieces.value(1).trimmed(); + QString cylinders = pieces.value(2).trimmed(); + QString bus_type = pieces.value(pieces.length() - 1).trimmed(); + // Add separator for each subsequent value, skipping the first + if(!new_disk_display.isEmpty()) { + new_disk_display.append(QString("%1").arg(VMManagerDetailSection::sectionSeparator)); + } + int diskSizeRaw = (cylinders.toInt() * heads.toInt() * sectors.toInt()) >> 11; + QString diskSizeFinal; + QString unit = tr("MiB"); + if(diskSizeRaw > 1000) { + unit = tr("GiB"); + diskSizeFinal = QString::number(diskSizeRaw * 1.0 / 1000, 'f', 1); + } else { + diskSizeFinal = QString::number(diskSizeRaw); + } + // Only prefix each disk when there are multiple disks + QString diskNumberDisplay = disks.count() > 1 ? tr("Disk %1: ").arg(disk_number) : ""; + new_disk_display.append(QString("%1%2 %3 (%4)").arg(diskNumberDisplay, diskSizeFinal, unit, bus_type.toUpper())); + } + if(new_disk_display.isEmpty()) { + new_disk_display = tr("No disks"); + } + display_table[Display::Name::Disks] = new_disk_display; + + // Floppy & CD-ROM + QStringList floppyDevices; + QStringList cdromDevices; + // Special case: first two 5.25" 360k FDDs which don't get saved to the .cfg + for (int i = 0; i < 2; i++) { + if (!floppy_cdrom_config.contains(QString("fdd_0%1_type").arg(i + 1))) + floppyDevices.append(QString(fdd_getname(fdd_get_from_internal_name((char *) "525_2dd")))); + } + + static auto floppy_match = QRegularExpression("fdd_\\d\\d_type", QRegularExpression::CaseInsensitiveOption); + static auto cdrom_match = QRegularExpression("cdrom_\\d\\d_type", QRegularExpression::CaseInsensitiveOption); + for(const auto& key: floppy_cdrom_config.keys()) { + if(key.contains(floppy_match)) { + // auto device_number = key.split("_").at(1); + auto floppy_internal_name = QString(floppy_cdrom_config[key]); + // Not interested in the nones + if(floppy_internal_name == "none") { + continue; + } + auto floppy_type = fdd_get_from_internal_name(floppy_internal_name.toUtf8().data()); + if(auto fddName = QString(fdd_getname(floppy_type)); !fddName.isEmpty()) { + floppyDevices.append(fddName); + } + } + if(key.contains(cdrom_match)) { + auto device_number = key.split("_").at(1); + auto cdrom_internal_name = QString(floppy_cdrom_config[key]); + auto cdrom_type = cdrom_get_from_internal_name(cdrom_internal_name.toUtf8().data()); + + auto cdrom_speed_key = QString("cdrom_%1_speed").arg(device_number); + auto cdrom_parameters_key = QString("cdrom_%1_parameters").arg(device_number); + auto cdrom_speed = QString(floppy_cdrom_config[cdrom_speed_key]); + auto cdrom_parameters = QString(floppy_cdrom_config[cdrom_parameters_key]); + auto cdrom_bus = cdrom_parameters.split(",").at(1).trimmed().toUpper(); + + if(cdrom_type != -1) { + if(!cdrom_speed.isEmpty()) { + cdrom_speed = QString("%1x ").arg(cdrom_speed); + } + if(!cdrom_bus.isEmpty()) { + cdrom_bus = QString(" (%1)").arg(cdrom_bus); + } + cdromDevices.append(QString("%1%2 %3 %4%5").arg(cdrom_speed, cdrom_drive_types[cdrom_type].vendor, cdrom_drive_types[cdrom_type].model, cdrom_drive_types[cdrom_type].revision, cdrom_bus)); + } + } + } + + display_table[Display::Name::Floppy] = floppyDevices.join(VMManagerDetailSection::sectionSeparator); + display_table[Display::Name::CD] = cdromDevices.join(VMManagerDetailSection::sectionSeparator); + + // Removable disks & MO + QStringList rdiskDevices; + QStringList moDevices; + static auto rdisk_match = QRegularExpression("rdisk_\\d\\d_parameters", QRegularExpression::CaseInsensitiveOption); + static auto zip_match = QRegularExpression("zip_\\d\\d_parameters", QRegularExpression::CaseInsensitiveOption); // Legacy ZIP drive entries + static auto mo_match = QRegularExpression("mo_\\d\\d_parameters", QRegularExpression::CaseInsensitiveOption); + for(const auto& key: rdisk_mo_config.keys()) { + if(key.contains(rdisk_match) || key.contains(zip_match)) { + auto device_number = key.split("_").at(1); + auto rdisk_parameters = QString(rdisk_mo_config[key]); + auto rdisk_type = rdisk_parameters.split(",").at(0).toInt(); + if (key.contains(zip_match)) + rdisk_type++; + auto rdisk_bus = rdisk_parameters.split(",").at(1).trimmed().toUpper(); + + if((rdisk_type >= 0) && (rdisk_type < KNOWN_RDISK_DRIVE_TYPES)) { + if(!rdisk_bus.isEmpty()) + rdisk_bus = QString(" (%1)").arg(rdisk_bus); + rdiskDevices.append(QString("%1 %2%3").arg(rdisk_drive_types[rdisk_type].vendor, rdisk_drive_types[rdisk_type].model, rdisk_bus)); + } + } + if(key.contains(mo_match)) { + auto device_number = key.split("_").at(1); + auto mo_parameters = QString(rdisk_mo_config[key]); + auto mo_type = mo_parameters.split(",").at(0).toInt(); + auto mo_bus = mo_parameters.split(",").at(1).trimmed().toUpper(); + + if((mo_type >= 0) && (mo_type < KNOWN_MO_DRIVE_TYPES)) { + if(!mo_bus.isEmpty()) + mo_bus = QString(" (%1)").arg(mo_bus); + moDevices.append(QString("%1 %2%3").arg(mo_drive_types[mo_type].vendor, mo_drive_types[mo_type].model, mo_bus)); + } + } + } + + display_table[Display::Name::RDisk] = rdiskDevices.join(VMManagerDetailSection::sectionSeparator); + display_table[Display::Name::MO] = moDevices.join(VMManagerDetailSection::sectionSeparator); + + + // SCSI controllers + QStringList scsiControllers; + static auto scsi_match = QRegularExpression("scsicard_\\d", QRegularExpression::CaseInsensitiveOption); + for(const auto& key: storage_config.keys()) { + if(key.contains(scsi_match)) { + auto device_number = key.split("_").at(1); + auto scsi_internal_name = QString(storage_config[key]); + auto scsi_id = scsi_card_get_from_internal_name(scsi_internal_name.toUtf8().data()); + auto scsi_device = scsi_card_getdevice(scsi_id); + auto scsi_name = DeviceConfig::DeviceName(scsi_device, scsi_card_get_internal_name(scsi_id), 1); + if(!scsi_name.isEmpty()) { + scsiControllers.append(scsi_name); + } + } + } + display_table[Display::Name::SCSIController] = scsiControllers.join(VMManagerDetailSection::sectionSeparator); + + // Hard and floppy disk controllers + QStringList storageControllers; + static auto fdc_match = QRegularExpression("fdc(_\\d)?", QRegularExpression::CaseInsensitiveOption); // futureproofing + static auto hdc_match = QRegularExpression("hdc(_\\d)?", QRegularExpression::CaseInsensitiveOption); + for(const auto& key: storage_config.keys()) { + if(key.contains(fdc_match)) { + QString device_number; + if (!key.contains('_')) + device_number = "1"; + else // futureproofing + device_number = key.split("_").at(1); + auto fdc_internal_name = QString(storage_config[key]); + if (!fdc_internal_name.isEmpty() && (fdc_internal_name != "none") && (fdc_internal_name != "internal")) { + auto fdc_id = fdc_card_get_from_internal_name(fdc_internal_name.toUtf8().data()); + auto fdc_device = fdc_card_getdevice(fdc_id); + auto fdc_name = DeviceConfig::DeviceName(fdc_device, fdc_card_get_internal_name(fdc_id), 1); + if(!fdc_name.isEmpty()) { + storageControllers.append(fdc_name); + } + } + } + if(key.contains(hdc_match)) { + QString device_number; + if (!key.contains('_')) // legacy hdc entry + device_number = "1"; + else + device_number = key.split("_").at(1); + auto hdc_internal_name = QString(storage_config[key]); + if (!hdc_internal_name.isEmpty() && (hdc_internal_name != "none") && (hdc_internal_name != "internal")) { + auto hdc_id = hdc_get_from_internal_name(hdc_internal_name.toUtf8().data()); + auto hdc_device = hdc_get_device(hdc_id); + auto hdc_name = DeviceConfig::DeviceName(hdc_device, hdc_get_internal_name(hdc_id), 1); + if(!hdc_name.isEmpty()) { + storageControllers.append(hdc_name); + } + } + } + } + + // CD-ROM controller + if (storage_config.contains("cdrom_interface")) { + auto cdrom_intf_internal_name = storage_config["cdrom_interface"]; + if (!cdrom_intf_internal_name.isEmpty() && (cdrom_intf_internal_name != "none") && (cdrom_intf_internal_name != "internal")) { + auto cdrom_intf_dev = cdrom_interface_get_from_internal_name(cdrom_intf_internal_name.toUtf8().data()); + auto cdrom_intf_dev_name = DeviceConfig::DeviceName(cdrom_interface_get_device(cdrom_intf_dev), cdrom_interface_get_internal_name(cdrom_intf_dev), 1); + storageControllers.append(cdrom_intf_dev_name); + } + } + + // Legacy tertiary/quaternary IDE + QString ide_ter_internal_name = "ide_ter"; + QString ide_qua_internal_name = "ide_qua"; + if (storage_config.contains(ide_ter_internal_name) && (storage_config[ide_ter_internal_name].toInt() != 0)) + storageControllers.append(DeviceConfig::DeviceName(hdc_get_device(hdc_get_from_internal_name(ide_ter_internal_name.toUtf8().data())), ide_ter_internal_name.toUtf8().constData(), 1)); + if (storage_config.contains(ide_qua_internal_name) && (storage_config[ide_qua_internal_name].toInt() != 0)) + storageControllers.append(DeviceConfig::DeviceName(hdc_get_device(hdc_get_from_internal_name(ide_qua_internal_name.toUtf8().data())), ide_qua_internal_name.toUtf8().constData(), 1)); + + display_table[Display::Name::StorageController] = storageControllers.join(VMManagerDetailSection::sectionSeparator); + + // Audio + QStringList sndCards; + static auto sndcard_match = QRegularExpression("sndcard\\d?", QRegularExpression::CaseInsensitiveOption); + for(const auto& key: audio_config.keys()) { + if(key.contains(sndcard_match)) { + auto device_number = key.right(1); + if(device_number == "d") // card #1 has no number + device_number = "1"; + auto audio_internal_name = QString(audio_config[key]); + auto audio_id = sound_card_get_from_internal_name(audio_internal_name.toUtf8().data()); + auto audio_device = sound_card_getdevice(audio_id); + auto audio_name = DeviceConfig::DeviceName(audio_device, sound_card_get_internal_name(audio_id), 1); + if(!audio_name.isEmpty()) { + sndCards.append(audio_name); + } + } + } + if(audio_config.contains("mpu401_standalone")) { + sndCards.append(tr("Standalone MPU-401")); + } + if(sndCards.isEmpty()) { + sndCards.append(tr("None")); + } + display_table[Display::Name::Audio] = sndCards.join(VMManagerDetailSection::sectionSeparator); + + // MIDI + QString midiOutDev; + if (audio_config.contains("midi_device")) { + auto midi_out_device = QString(audio_config["midi_device"]); + auto midi_device_int = midi_out_device_get_from_internal_name(midi_out_device.toUtf8().data()); + auto midi_out = midi_out_device_getdevice(midi_device_int); + if(auto midiDevName = QString(midi_out->name); !midiDevName.isEmpty()) { + midiOutDev = midiDevName; + } + } + display_table[Display::Name::MidiOut] = midiOutDev; + + // midi_device = mt32 (output) + // mpu401_standalone = 1 + // midi_in_device (input) + + // Network + QStringList nicList; + static auto nic_match = QRegularExpression("net_\\d\\d_card", QRegularExpression::CaseInsensitiveOption); + for(const auto& key: network_config.keys()) { + if(key.contains(nic_match)) { + auto device_number = key.split("_").at(1); + auto nic_internal_name = QString(network_config[key]); + auto nic_id = network_card_get_from_internal_name(nic_internal_name.toUtf8().data()); + auto nic = network_card_getdevice(nic_id); + auto nic_name = DeviceConfig::DeviceName(nic, network_card_get_internal_name(nic_id), 1); + auto net_type_key = QString("net_%1_net_type").arg(device_number); + auto net_type = network_config[net_type_key]; + if (!net_type.isEmpty()) { + if (net_type == "slirp") + net_type = "SLiRP"; + else if (net_type == "pcap") + net_type = "PCap"; + else if (net_type == "nmswitch") + net_type = tr("Local Switch"); + else if (net_type == "nrswitch") + net_type = tr("Remote Switch"); + else + net_type = net_type.toUpper(); + nicList.append(nic_name + " (" + net_type + ")"); + } else { + nicList.append(nic_name); + } + + } + } + if(nicList.isEmpty()) { + nicList.append(tr("None")); + } + display_table[Display::Name::NIC] = nicList.join(VMManagerDetailSection::sectionSeparator); + + // Input (Keyboard) + if (input_config.contains("keyboard_type")) { + auto keyboard_internal_name = input_config["keyboard_type"]; + auto keyboard_dev = keyboard_get_from_internal_name(keyboard_internal_name.toUtf8().data()); + auto keyboard_dev_name = DeviceConfig::DeviceName(keyboard_get_device(keyboard_dev), keyboard_get_internal_name(keyboard_dev), 0); + display_table[Display::Name::Keyboard] = keyboard_dev_name; + } + + // Input (Mouse) + auto mouse_internal_name = input_config["mouse_type"]; + auto mouse_dev = mouse_get_from_internal_name(mouse_internal_name.toUtf8().data()); + auto mouse_dev_name = DeviceConfig::DeviceName(mouse_get_device(mouse_dev), mouse_get_internal_name(mouse_dev), 0); + display_table[Display::Name::Mouse] = mouse_dev_name; + + // Input (joystick) + QString joystickDevice; + if(input_config.contains("joystick_type")) { + auto joystick_internal = QString(input_config["joystick_type"]); + auto joystick_dev = joystick_get_from_internal_name(joystick_internal.toUtf8().data()); + if (auto joystickName = tr(joystick_get_name(joystick_dev)); !joystickName.isEmpty()) { + joystickDevice = joystickName; + } + } + display_table[Display::Name::Joystick] = joystickDevice; + + // # Ports + // Serial + // By default serial 1 and 2 are enabled unless otherwise specified + static auto serial_match = QRegularExpression("serial\\d_enabled", QRegularExpression::CaseInsensitiveOption); + QList serial_enabled = {true, true, false, false, false, false, false, false}; + // Parallel + // By default lpt 1 is enabled unless otherwise specified + static auto lpt_match = QRegularExpression("lpt\\d_enabled", QRegularExpression::CaseInsensitiveOption); + QList lpt_enabled = {true, false, false, false}; + for (const auto &key: ports_config.keys()) { + if (key.contains(serial_match)) { + if (auto serial_dev = key.split("_").at(0); !serial_dev.isEmpty()) { + auto serial_num = serial_dev.at(serial_dev.size() - 1); + // qDebug() << "serial is set" << key << ":" << ports_config[key]; + if(serial_num.isDigit() && serial_num.digitValue() >= 1 && serial_num.digitValue() <= 4) { + // Already verified that it is a digit with isDigit() + serial_enabled[serial_num.digitValue() - 1] = ports_config[key].toInt() == 1; + } + } + } + if (key.contains(lpt_match)) { + if (auto lpt_dev = key.split("_").at(0); !lpt_dev.isEmpty()) { + auto lpt_num = lpt_dev.at(lpt_dev.size() - 1); + // qDebug() << "lpt is set" << key << ":" << ports_config[key]; + if (lpt_num.isDigit() && lpt_num.digitValue() >= 1 && lpt_num.digitValue() <= 4) { + lpt_enabled[lpt_num.digitValue() - 1] = ports_config[key].toInt() == 1; + } + } + } + } + // qDebug() << "ports final" << serial_enabled << lpt_enabled; + QStringList serialFinal; + QStringList lptFinal; + int portIndex = 0; + while (true) { + if (serial_enabled[portIndex]) + serialFinal.append(QString("COM%1").arg(portIndex + 1)); + ++portIndex; + if (portIndex == SERIAL_MAX) + break; + } + portIndex = 0; + bool hasLptDevices = false; + while (true) { + if (lpt_enabled[portIndex]) { + auto lpt_device_key = QString("lpt%1_device").arg(portIndex + 1); + QString lpt_device_name = ""; + if (ports_config.contains(lpt_device_key)) { + auto lpt_internal_name = QString(ports_config[lpt_device_key]); + auto lpt_id = lpt_device_get_from_internal_name(lpt_internal_name.toUtf8().data()); + lpt_device_name = " (" + tr(lpt_device_get_name(lpt_id)) + ")"; + hasLptDevices = true; + } + lptFinal.append(QString("LPT%1%2").arg(portIndex + 1).arg(lpt_device_name)); + } + ++portIndex; + if (portIndex == PARALLEL_MAX) + break; + } + display_table[Display::Name::Serial] = (serialFinal.empty() ? tr("None") : serialFinal.join(", ")); + display_table[Display::Name::Parallel] = (lptFinal.empty() ? tr("None") : lptFinal.join((hasLptDevices ? VMManagerDetailSection::sectionSeparator : ", "))); + + // ISA RTC + if (other_config.contains("isartc_type")) { + auto isartc_internal_name = other_config["isartc_type"]; + auto isartc_dev = isartc_get_from_internal_name(isartc_internal_name.toUtf8().data()); + auto isartc_dev_name = DeviceConfig::DeviceName(isartc_get_device(isartc_dev), isartc_get_internal_name(isartc_dev), 0); + display_table[Display::Name::IsaRtc] = isartc_dev_name; + } + + // ISA RAM + QStringList IsaMemCards; + static auto isamem_match = QRegularExpression("isamem\\d_type", QRegularExpression::CaseInsensitiveOption); + for(const auto& key: other_config.keys()) { + if(key.contains(isamem_match)) { + auto device_number = QString("%1").arg(key.split("_").at(0).right(1).toInt() + 1); + auto isamem_internal_name = QString(other_config[key]); + auto isamem_id = isamem_get_from_internal_name(isamem_internal_name.toUtf8().data()); + auto isamem_device = isamem_get_device(isamem_id); + auto isamem_name = DeviceConfig::DeviceName(isamem_device, isamem_get_internal_name(isamem_id), 0); + if(!isamem_name.isEmpty()) { + IsaMemCards.append(isamem_name); + } + } + } + display_table[Display::Name::IsaMem] = IsaMemCards.join(VMManagerDetailSection::sectionSeparator); + + // ISA ROM + QStringList IsaRomCards; + static auto isarom_match = QRegularExpression("isarom\\d_type", QRegularExpression::CaseInsensitiveOption); + for(const auto& key: other_config.keys()) { + if(key.contains(isarom_match)) { + auto device_number = QString("%1").arg(key.split("_").at(0).right(1).toInt() + 1); + auto isarom_internal_name = QString(other_config[key]); + auto isarom_id = isarom_get_from_internal_name(isarom_internal_name.toUtf8().data()); + auto isarom_device = isarom_get_device(isarom_id); + auto isarom_name = DeviceConfig::DeviceName(isarom_device, isarom_get_internal_name(isarom_id), 0); + if(!isarom_name.isEmpty()) { + IsaRomCards.append(isarom_name); + } + } + } + display_table[Display::Name::IsaRom] = IsaRomCards.join(VMManagerDetailSection::sectionSeparator); +} + +bool +VMManagerSystem::startServer() { + if (socket_server->startServer()) { + serverIsRunning = true; + connect(socket_server, &VMManagerServerSocket::dataReceived, this, &VMManagerSystem::dataReceived); + connect(socket_server, &VMManagerServerSocket::windowStatusChanged, this, &VMManagerSystem::windowStatusChangeReceived); + connect(socket_server, &VMManagerServerSocket::runningStatusChanged, this, &VMManagerSystem::runningStatusChangeReceived); + connect(socket_server, &VMManagerServerSocket::configurationChanged, this, &VMManagerSystem::configurationChangeReceived); + connect(socket_server, &VMManagerServerSocket::winIdReceived, this, [this] (WId id) { this->id = id; }); + return true; + } else { + return false; + } +} + +void +VMManagerSystem::setProcessEnvVars() { + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + QString env_var_name = (socket_server_type == VMManagerServerSocket::ServerType::Standard) ? "VMM_86BOX_SOCKET" : "86BOX_MANAGER_SOCKET"; + env.insert(env_var_name, socket_server->getSocketPath()); + process->setProcessEnvironment(env); +} + +void +VMManagerSystem::restartButtonPressed() { + socket_server->serverSendMessage(VMManagerProtocol::ManagerMessage::ResetVM); + +} + +void +VMManagerSystem::pauseButtonPressed() { + socket_server->serverSendMessage(VMManagerProtocol::ManagerMessage::Pause); +} +void +VMManagerSystem::dataReceived() +{ + qInfo() << Q_FUNC_INFO << "Note: Respond to data received events here."; +} +void +VMManagerSystem::windowStatusChangeReceived(int status) +{ + window_obscured = status; + emit windowStatusChanged(); + processStatusChanged(); +} +QString +VMManagerSystem::getDisplayValue(Display::Name key) +{ + return (display_table.contains(key)) ? display_table[key] : ""; +} + +void +VMManagerSystem::shutdownRequestButtonPressed() +{ + socket_server->serverSendMessage(VMManagerProtocol::ManagerMessage::RequestShutdown); +} + +void +VMManagerSystem::shutdownForceButtonPressed() +{ + socket_server->serverSendMessage(VMManagerProtocol::ManagerMessage::ForceShutdown); +} + +void +VMManagerSystem::cadButtonPressed() +{ + socket_server->serverSendMessage(VMManagerProtocol::ManagerMessage::CtrlAltDel); +} + +void +VMManagerSystem::processStatusChanged() +{ + // set to running if the process is running and the state is stopped + if (process->state() == QProcess::ProcessState::Running) { + if (process_status == VMManagerSystem::ProcessStatus::Stopped) { + process_status = VMManagerSystem::ProcessStatus::Running; + } + } else if (process->state() == QProcess::ProcessState::NotRunning) { + process_status = VMManagerSystem::ProcessStatus::Stopped; + window_obscured = false; + } + emit itemDataChanged(); + emit clientProcessStatusChanged(); +} +void +VMManagerSystem::statusRefresh() +{ + processStatusChanged(); +} +QString +VMManagerSystem::processStatusToString(VMManagerSystem::ProcessStatus status) +{ +// QMetaEnum qme = QMetaEnum::fromType(); +// return qme.valueToKey(static_cast(status)); + switch (status) { + case VMManagerSystem::ProcessStatus::Stopped: + return tr("Powered Off"); + case VMManagerSystem::ProcessStatus::Running: + return tr("Running"); + case VMManagerSystem::ProcessStatus::Paused: + return tr("Paused"); + case VMManagerSystem::ProcessStatus::PausedWaiting: + case VMManagerSystem::ProcessStatus::RunningWaiting: + return tr("Paused (Waiting)"); + default: + return tr("Unknown Status"); + } +} + +QString +VMManagerSystem::getProcessStatusString() const +{ + return processStatusToString(process_status); +} + +VMManagerSystem::ProcessStatus +VMManagerSystem::getProcessStatus() const +{ + return process_status; +} +// Maps VMManagerProtocol::RunningState to VMManagerSystem::ProcessStatus +void +VMManagerSystem::runningStatusChangeReceived(VMManagerProtocol::RunningState state) +{ + if(state == VMManagerProtocol::RunningState::Running) { + process_status = VMManagerSystem::ProcessStatus::Running; + window_obscured = false; + windowStatusChanged(); + } else if(state == VMManagerProtocol::RunningState::Paused) { + process_status = VMManagerSystem::ProcessStatus::Paused; + window_obscured = false; + windowStatusChanged(); + } else if(state == VMManagerProtocol::RunningState::RunningWaiting) { + process_status = VMManagerSystem::ProcessStatus::RunningWaiting; + window_obscured = true; + windowStatusChanged(); + } else if(state == VMManagerProtocol::RunningState::PausedWaiting) { + process_status = VMManagerSystem::ProcessStatus::PausedWaiting; + window_obscured = true; + windowStatusChanged(); + } else { + process_status = VMManagerSystem::ProcessStatus::Unknown; + } + processStatusChanged(); +} +void +VMManagerSystem::configurationChangeReceived() +{ + reloadConfig(); + emit configurationChanged(this->uuid); +} +void +VMManagerSystem::reloadConfig() +{ + loadSettings(); + setupVars(); +} + +QDateTime +VMManagerSystem::timestamp() +{ + return lastUsedTimestamp; +} +void +VMManagerSystem::setIcon(const QString &newIcon) +{ + icon = newIcon; + saveSettings(); + emit itemDataChanged(); +} diff --git a/src/qt/qt_vmmanager_system.hpp b/src/qt/qt_vmmanager_system.hpp new file mode 100644 index 000000000..27b9fda57 --- /dev/null +++ b/src/qt/qt_vmmanager_system.hpp @@ -0,0 +1,205 @@ +/* +* 86Box A hypervisor and IBM PC system emulator that specializes in +* running old operating systems and software designed for IBM +* PC systems and compatibles from 1981 through fairly recent +* system designs based on the PCI bus. +* +* This file is part of the 86Box distribution. +* +* Header for 86Box VM manager system module +* +* +* +* Authors: cold-brewed +* +* Copyright 2024 cold-brewed +*/ + +#ifndef QT_VMMANAGER_SYSTEM_H +#define QT_VMMANAGER_SYSTEM_H + +#include +#include +#include +#include +#include +#include "qt_vmmanager_serversocket.hpp" +#include "qt_vmmanager_config.hpp" +#include "qt_deviceconfig.hpp" + +// This macro helps give us the required `qHash()` function in order to use the +// enum as a hash key +#define QHASH_FOR_CLASS_ENUM(T) \ +inline uint qHash(const T &t, uint seed) { \ + return ::qHash(static_cast::type>(t), seed); \ +} + +namespace VMManager { +Q_NAMESPACE +namespace Display { +Q_NAMESPACE +enum class Name { + Machine, + CPU, + Memory, + Video, + Disks, + Floppy, + CD, + RDisk, + MO, + SCSIController, + StorageController, + MidiOut, + Joystick, + Serial, + Parallel, + Audio, + Voodoo, + NIC, + Keyboard, + Mouse, + IsaRtc, + IsaMem, + IsaRom, + Unknown +}; +Q_ENUM_NS(Name) +QHASH_FOR_CLASS_ENUM(Name) +} +} + +class VMManagerSystem : public QWidget { + Q_OBJECT + + typedef QHash display_table_t; + typedef QHash > config_hash_t; + +public: + + enum class ProcessStatus { + Stopped, + Running, + Paused, + PausedWaiting, + RunningWaiting, + Unknown, + }; + Q_ENUM(ProcessStatus); + + explicit VMManagerSystem(const QString &sysconfig_file); + // Default constructor will generate a temporary filename as the config file + // but it will not be valid (isValid() will return false) + VMManagerSystem() : VMManagerSystem(generateTemporaryFilename()) {} + + ~VMManagerSystem() override; + + static QVector scanForConfigs(QWidget* parent = nullptr, const QString &searchPath = {}); + static QString generateTemporaryFilename(); + + QFileInfo config_file; + QString config_name; + QString config_dir; + QString shortened_dir; + QString uuid; + QString displayName; + QString notes; + QString icon; + QStringList searchTerms; + + config_hash_t config_hash; + + [[nodiscard]] QString getAll(const QString& category) const; + [[nodiscard]] QHash getCategory(const QString& category) const; + [[nodiscard]] QHash > getConfigHash() const; + + void setDisplayName(const QString& newDisplayName); + void setNotes(const QString& newNotes); + + [[nodiscard]] bool isValid() const; + [[nodiscard]] bool isProcessRunning() const; + [[nodiscard]] qint64 processId() const; +public slots: + void launchMainProcess(); + void launchSettings(); + void startButtonPressed(); + void restartButtonPressed(); + void pauseButtonPressed(); + void shutdownRequestButtonPressed(); + void shutdownForceButtonPressed(); + void cadButtonPressed(); + void reloadConfig(); +public: + QDateTime timestamp(); + void setIcon(const QString &newIcon); + + QProcess *process = new QProcess(); + + bool window_obscured; + + QString getDisplayValue(VMManager::Display::Name key); + QFileInfoList getScreenshots(); + + inline bool operator==(const VMManagerSystem &rhs) const + { + return config_file.filePath() == rhs.config_file.filePath(); + } + + static QString + processStatusToString(VMManagerSystem::ProcessStatus status) ; + ProcessStatus process_status; + [[nodiscard]] QString getProcessStatusString() const; + [[nodiscard]] ProcessStatus getProcessStatus() const; + +signals: + void windowStatusChanged(); + void itemDataChanged(); + void clientProcessStatusChanged(); + void configurationChanged(const QString &uuid); + +private: + void loadSettings(); + void saveSettings(); + void generateSearchTerms(); + void updateTimestamp(); + + display_table_t display_table; + + QFileInfo main_binary; + QString platform; + + // QDir application_temp_directory; + // QDir standard_temp_directory; + // QDir app_data_directory; + QDir screenshot_directory; + + QString unique_name; + QDateTime lastUsedTimestamp; + + VMManagerServerSocket *socket_server; + VMManagerServerSocket::ServerType socket_server_type; + + // Configuration file settings + VMManagerConfig *config_settings; + + WId id; + + bool serverIsRunning; + bool startServer(); + + bool has86BoxBinary(); + void find86BoxBinary(); + void setupPaths(); + void setupVars(); + void setProcessEnvVars(); + + void dataReceived(); + void windowStatusChangeReceived(int status); + void runningStatusChangeReceived(VMManagerProtocol::RunningState state); + void configurationChangeReceived(); + void processStatusChanged(); + void statusRefresh(); +}; + + +#endif //QT_VMMANAGER_SYSTEM_H diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 306da575f..eca77d15d 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -6,15 +6,22 @@ * * This file is part of the 86Box distribution. * - * Windows raw input native filter for QT + * Windows raw input native filter for Qt * * * * Authors: Teemu Korhonen * Miran Grca, + * Sam Latinga + * Cacodemon345 * * Copyright 2021 Teemu Korhonen * Copyright 2016-2018 Miran Grca. + * Copyright 1997-2025 Sam Latinga + * Copyright 2024-2025 Cacodemon345. + * + * See this header for SDL3 code license: + * https://github.com/libsdl-org/SDL/blob/8e5fe0ea61dc87b29ca9a6119324221df0113bcf/src/video/windows/SDL_windowsrawinput.c#L1 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -31,6 +38,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +/* Mouse RawInput code taken from SDL3. */ + #include "qt_winrawinputfilter.hpp" #include @@ -64,6 +73,8 @@ extern void win_keyboard_handle(uint32_t scancode, int up, int e0, int e1); #include "qt_rendererstack.hpp" #include "ui_qt_mainwindow.h" +static bool NewDarkMode = FALSE; + bool windows_is_light_theme() { // based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application @@ -92,30 +103,158 @@ bool windows_is_light_theme() { return i == 1; } +struct +{ + HANDLE done_event = 0, ready_event = 0; + std::atomic_bool done{false}; + + size_t rawinput_offset = 0, rawinput_size = 0; + uint8_t* rawinput = nullptr; + + HANDLE thread = 0; +} win_rawinput_data; + +static void +win_poll_mouse(void) +{ + // Yes, this is a thing in C++. + auto* data = &win_rawinput_data; + uint32_t size, i, count, total = 0; + RAWINPUT *input; + //static int64_t ms_time = plat_get_ticks(); + + if (data->rawinput_offset == 0) { + BOOL isWow64; + + data->rawinput_offset = sizeof(RAWINPUTHEADER); + if (IsWow64Process(GetCurrentProcess(), &isWow64) && isWow64) { + // We're going to get 64-bit data, so use the 64-bit RAWINPUTHEADER size + data->rawinput_offset += 8; + } + } + + input = (RAWINPUT *)data->rawinput; + for (;;) { + size = data->rawinput_size - (UINT)((BYTE *)input - data->rawinput); + count = GetRawInputBuffer(input, &size, sizeof(RAWINPUTHEADER)); + if (count == 0 || count == (UINT)-1) { + if (!data->rawinput || (count == (UINT)-1 && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { + const UINT RAWINPUT_BUFFER_SIZE_INCREMENT = 96; // 2 64-bit raw mouse packets + BYTE *rawinput = (BYTE *)realloc(data->rawinput, data->rawinput_size + RAWINPUT_BUFFER_SIZE_INCREMENT); + if (!rawinput) { + break; + } + input = (RAWINPUT *)(rawinput + ((BYTE *)input - data->rawinput)); + data->rawinput = rawinput; + data->rawinput_size += RAWINPUT_BUFFER_SIZE_INCREMENT; + } else { + break; + } + } else { + total += count; + + // Advance input to the end of the buffer + while (count--) { + input = NEXTRAWINPUTBLOCK(input); + } + } + } + + if (total > 0) { + for (i = 0, input = (RAWINPUT *)data->rawinput; i < total; ++i, input = NEXTRAWINPUTBLOCK(input)) { + if (input->header.dwType == RIM_TYPEMOUSE) { + RAWMOUSE *rawmouse = (RAWMOUSE *)((BYTE *)input + data->rawinput_offset); + if (mouse_capture) + WindowsRawInputFilter::mouse_handle(rawmouse); + } + } + } + + //qDebug() << "Mouse delay: " << (plat_get_ticks() - ms_time); + //ms_time = plat_get_ticks(); +} + +static DWORD +win_rawinput_thread(void* param) +{ + RAWINPUTDEVICE rid = { + .usUsagePage = 0x01, + .usUsage = 0x02, + .dwFlags = 0, + .hwndTarget = nullptr + }; + auto window = CreateWindowEx(0, TEXT("Message"), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); + if (!window) { + return 0; + } + + rid.hwndTarget = window; + if (!RegisterRawInputDevices(&rid, 1, sizeof(rid))) { + DestroyWindow(window); + return 0; + } + + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); + + SetEvent(win_rawinput_data.ready_event); + + while (!win_rawinput_data.done) { + DWORD result = MsgWaitForMultipleObjects(1, &win_rawinput_data.done_event, FALSE, INFINITE, QS_RAWINPUT); + + if (result != (WAIT_OBJECT_0 + 1)) { + break; + } + + // Clear the queue status so MsgWaitForMultipleObjects() will wait again + (void)GetQueueStatus(QS_RAWINPUT); + + win_poll_mouse(); + } + + rid.dwFlags |= RIDEV_REMOVE; + rid.hwndTarget = NULL; + + RegisterRawInputDevices(&rid, 1, sizeof(rid)); + DestroyWindow(window); + return 0; +} + extern "C" void win_joystick_handle(PRAWINPUT); std::unique_ptr WindowsRawInputFilter::Register(MainWindow *window) { - RAWINPUTDEVICE rid[2] = { + RAWINPUTDEVICE rid[1] = { { .usUsagePage = 0x01, .usUsage = 0x06, .dwFlags = RIDEV_NOHOTKEYS, .hwndTarget = nullptr - }, - { - .usUsagePage = 0x01, - .usUsage = 0x02, - .dwFlags = 0, - .hwndTarget = nullptr } }; - if (hook_enabled && (RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])) == FALSE)) - return std::unique_ptr(nullptr); - else if (!hook_enabled && (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE)) - return std::unique_ptr(nullptr); + if (!hook_enabled) { + RegisterRawInputDevices(rid, 1, sizeof(rid[0])); + } + win_rawinput_data.done_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + win_rawinput_data.ready_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + + if (!win_rawinput_data.done_event || !win_rawinput_data.ready_event) { + warning("Failed to create RawInput events."); + + goto conclude; + } + + win_rawinput_data.thread = CreateThread(nullptr, 0, win_rawinput_thread, nullptr, 0, nullptr); + if (win_rawinput_data.thread) { + HANDLE handles[2] = { win_rawinput_data.ready_event, win_rawinput_data.thread }; + + WaitForMultipleObjects(2, handles, FALSE, INFINITE); + } else { + warning("Failed to create RawInput thread."); + } + +conclude: std::unique_ptr inputfilter(new WindowsRawInputFilter(window)); return inputfilter; @@ -133,25 +272,23 @@ WindowsRawInputFilter::WindowsRawInputFilter(MainWindow *window) WindowsRawInputFilter::~WindowsRawInputFilter() { - RAWINPUTDEVICE rid[2] = { + win_rawinput_data.done = true; + if (win_rawinput_data.done_event) + SetEvent(win_rawinput_data.done_event); + if (win_rawinput_data.thread) + WaitForSingleObject(win_rawinput_data.thread, INFINITE); + RAWINPUTDEVICE rid = { .usUsagePage = 0x01, .usUsage = 0x06, .dwFlags = RIDEV_REMOVE, .hwndTarget = NULL - }, - { - .usUsagePage = 0x01, - .usUsage = 0x02, - .dwFlags = RIDEV_REMOVE, - .hwndTarget = NULL - } - }; + }; - if (hook_enabled) - RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])); - else - RegisterRawInputDevices(rid, 2, sizeof(rid[0])); + if (!hook_enabled) + RegisterRawInputDevices(&rid, 1, sizeof(rid)); + + free(win_rawinput_data.rawinput); } static void @@ -220,6 +357,14 @@ WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *mess if ((((void *) msg->lParam) != nullptr) && (wcscmp(L"ImmersiveColorSet", (wchar_t*)msg->lParam) == 0)) { + bool OldDarkMode = NewDarkMode; +#if 0 + if (do_auto_pause && !dopause) { + auto_paused = 1; + plat_pause(1); + } +#endif + if (!windows_is_light_theme()) { QFile f(":qdarkstyle/dark/darkstyle.qss"); @@ -228,45 +373,39 @@ WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *mess else { f.open(QFile::ReadOnly | QFile::Text); QTextStream ts(&f); - qApp->setStyleSheet(ts.readAll()); + qApp->setStyleSheet(ts.readAll()); } - QTimer::singleShot(1000, [this] () { - BOOL DarkMode = TRUE; - auto vid_stack = (RendererStack::Renderer) vid_api; - DwmSetWindowAttribute((HWND) window->winId(), - DWMWA_USE_IMMERSIVE_DARK_MODE, - (LPCVOID) &DarkMode, - sizeof(DarkMode)); - window->ui->stackedWidget->switchRenderer(vid_stack); - for (int i = 1; i < MONITORS_NUM; i++) { - if ((window->renderers[i] != nullptr) && - !window->renderers[i]->isHidden()) - window->renderers[i]->switchRenderer(vid_stack); - } - }); + NewDarkMode = TRUE; } else { qApp->setStyleSheet(""); - QTimer::singleShot(1000, [this] () { - BOOL DarkMode = FALSE; - DwmSetWindowAttribute((HWND) window->winId(), - DWMWA_USE_IMMERSIVE_DARK_MODE, - (LPCVOID) &DarkMode, - sizeof(DarkMode)); - }); + NewDarkMode = FALSE; } - QTimer::singleShot(1000, [this] () { + if (NewDarkMode != OldDarkMode) QTimer::singleShot(1000, [this] () { + BOOL DarkMode = NewDarkMode; + DwmSetWindowAttribute((HWND) window->winId(), + DWMWA_USE_IMMERSIVE_DARK_MODE, + (LPCVOID) &DarkMode, + sizeof(DarkMode)); + window->resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y); + for (int i = 1; i < MONITORS_NUM; i++) { auto mon = &(monitors[i]); if ((window->renderers[i] != nullptr) && !window->renderers[i]->isHidden()) window->resizeContentsMonitor(mon->mon_scrnsz_x, - mon->mon_scrnsz_y, - i); + mon->mon_scrnsz_y, i); } + +#if 0 + if (auto_paused) { + plat_pause(0); + auto_paused = 0; + } +#endif }); } break; @@ -301,10 +440,6 @@ WindowsRawInputFilter::handle_input(HRAWINPUT input) case RIM_TYPEKEYBOARD: keyboard_handle(raw); break; - case RIM_TYPEMOUSE: - if (mouse_capture) - mouse_handle(raw); - break; case RIM_TYPEHID: win_joystick_handle(raw); break; @@ -324,9 +459,9 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) } void -WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) +WindowsRawInputFilter::mouse_handle(RAWMOUSE* raw) { - RAWMOUSE state = raw->data.mouse; + RAWMOUSE state = *raw; static int x, delta_x; static int y, delta_y; static int b, delta_z; @@ -391,7 +526,7 @@ WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) mouse_scale(delta_x, delta_y); - HWND wnd = (HWND)window->winId(); + /* HWND wnd = (HWND)window->winId(); RECT rect; @@ -400,5 +535,5 @@ WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) int left = rect.left + (rect.right - rect.left) / 2; int top = rect.top + (rect.bottom - rect.top) / 2; - SetCursorPos(left, top); + SetCursorPos(left, top); */ } diff --git a/src/qt/qt_winrawinputfilter.hpp b/src/qt/qt_winrawinputfilter.hpp index 411f7841c..9d8d6ba0e 100644 --- a/src/qt/qt_winrawinputfilter.hpp +++ b/src/qt/qt_winrawinputfilter.hpp @@ -38,6 +38,7 @@ #include #include +#include #include @@ -59,6 +60,8 @@ public: ~WindowsRawInputFilter(); + static void mouse_handle(RAWMOUSE* raw); + private: MainWindow *window; int buttons = 0; @@ -71,7 +74,6 @@ private: void handle_input(HRAWINPUT input); void keyboard_handle(PRAWINPUT raw); - void mouse_handle(PRAWINPUT raw); }; #endif diff --git a/src/qt/sdl_joystick.c b/src/qt/sdl_joystick.c index 83a2a67b1..75234bca3 100644 --- a/src/qt/sdl_joystick.c +++ b/src/qt/sdl_joystick.c @@ -33,10 +33,10 @@ #include <86box/gameport.h> #include <86box/plat_unused.h> -int joysticks_present = 0; -joystick_t joystick_state[GAMEPORT_MAX][MAX_JOYSTICKS]; -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS]; +int joysticks_present = 0; +joystick_state_t joystick_state[GAMEPORT_MAX][MAX_JOYSTICKS]; +plat_joystick_state_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS]; #ifndef M_PI # define M_PI 3.14159265358979323846 @@ -45,8 +45,10 @@ static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS]; void joystick_init(void) { +#ifdef _WIN32 /* This is needed for SDL's Windows raw input backend to work properly without SDL video. */ SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1"); +#endif if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) { return; diff --git a/src/qt/win_cdrom_ioctl.c b/src/qt/win_cdrom_ioctl.c index ff72e58fe..cd558c2ec 100644 --- a/src/qt/win_cdrom_ioctl.c +++ b/src/qt/win_cdrom_ioctl.c @@ -315,6 +315,7 @@ ioctl_get_track_info(const void *local, const uint32_t track, const raw_track_info_t *rti = (const raw_track_info_t *) ioctl->cur_rti; int ret = 1; int trk = -1; + int next = -1; if ((track >= 1) && (track < 99)) for (int i = 0; i < ioctl->blocks_num; i++) @@ -323,13 +324,35 @@ ioctl_get_track_info(const void *local, const uint32_t track, break; } + if ((track >= 1) && (track < 98)) + for (int i = 0; i < ioctl->blocks_num; i++) + if ((rti[i].point == (track + 1)) && (rti[i].session == rti[trk].session)) { + next = i; + break; + } + + if ((track >= 1) && (track < 99) && (trk != -1) && (next == -1)) + for (int i = 0; i < ioctl->blocks_num; i++) + if ((rti[i].point == 0xa2) && (rti[i].session == rti[trk].session)) { + next = i; + break; + } + if ((track == 0xaa) || (trk == -1)) { ioctl_log(ioctl->log, "ioctl_get_track_info(%02i)\n", track); ret = 0; } else { - ti->m = rti[trk].pm; - ti->s = rti[trk].ps; - ti->f = rti[trk].pf; + if (end) { + if (next != -1) { + ti->m = rti[next].pm; + ti->s = rti[next].ps; + ti->f = rti[next].pf; + } + } else { + ti->m = rti[trk].pm; + ti->s = rti[trk].ps; + ti->f = rti[trk].pf; + } ti->number = rti[trk].point; ti->attr = rti[trk].adr_ctl; diff --git a/src/qt/win_joystick_rawinput.c b/src/qt/win_joystick_rawinput.c index 5173d4f05..c775b4bb3 100644 --- a/src/qt/win_joystick_rawinput.c +++ b/src/qt/win_joystick_rawinput.c @@ -96,15 +96,15 @@ typedef struct { } pov[MAX_JOY_POVS]; } raw_joystick_t; -int joysticks_present = 0; -joystick_t joystick_state[GAMEPORT_MAX][MAX_JOYSTICKS]; -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +int joysticks_present = 0; +joystick_state_t joystick_state[GAMEPORT_MAX][MAX_JOYSTICKS]; +plat_joystick_state_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS]; /* We only use the first 32 buttons reported, from Usage ID 1-128 */ void -joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) +joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_state_t *joy, USAGE usage) { if (joy->nr_buttons >= MAX_JOY_BUTTONS) return; @@ -117,7 +117,7 @@ joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) } void -joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) +joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_state_t *joy, PHIDP_VALUE_CAPS prop) { if (joy->nr_axes >= MAX_JOY_AXES) return; @@ -202,7 +202,7 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS } void -joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) +joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_state_t *joy, PHIDP_VALUE_CAPS prop) { if (joy->nr_povs >= MAX_JOY_POVS) return; @@ -217,11 +217,12 @@ joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS } void -joystick_get_capabilities(raw_joystick_t *rawjoy, plat_joystick_t *joy) +joystick_get_capabilities(raw_joystick_t *rawjoy, plat_joystick_state_t *joy) { UINT size = 0; PHIDP_BUTTON_CAPS btn_caps = NULL; PHIDP_VALUE_CAPS val_caps = NULL; + HIDP_CAPS caps; /* Get preparsed data (HID data format) */ GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, NULL, &size); @@ -229,7 +230,6 @@ joystick_get_capabilities(raw_joystick_t *rawjoy, plat_joystick_t *joy) if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, rawjoy->data, &size) <= 0) fatal("joystick_get_capabilities: Failed to get preparsed data.\n"); - HIDP_CAPS caps; HidP_GetCaps(rawjoy->data, &caps); /* Buttons */ @@ -276,7 +276,7 @@ end: } void -joystick_get_device_name(raw_joystick_t *rawjoy, plat_joystick_t *joy, PRID_DEVICE_INFO info) +joystick_get_device_name(raw_joystick_t *rawjoy, plat_joystick_state_t *joy, PRID_DEVICE_INFO info) { UINT size = 0; WCHAR *device_name = NULL; @@ -340,9 +340,9 @@ joystick_init(void) if (info->hid.usUsage != HID_USAGE_GENERIC_JOYSTICK && info->hid.usUsage != HID_USAGE_GENERIC_GAMEPAD) goto end_loop; - plat_joystick_t *joy = &plat_joystick_state[joysticks_present]; - raw_joystick_t *rawjoy = &raw_joystick_state[joysticks_present]; - rawjoy->hdevice = deviceList[i].hDevice; + plat_joystick_state_t *joy = &plat_joystick_state[joysticks_present]; + raw_joystick_t *rawjoy = &raw_joystick_state[joysticks_present]; + rawjoy->hdevice = deviceList[i].hDevice; joystick_get_capabilities(rawjoy, joy); joystick_get_device_name(rawjoy, joy, info); @@ -356,6 +356,7 @@ end_loop: free(info); } + free(deviceList); joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present); /* Initialize the RawInput (joystick and gamepad) module. */ diff --git a/src/qt/win_netsocket.c b/src/qt/win_netsocket.c index 55a84d414..d7d467c07 100644 --- a/src/qt/win_netsocket.c +++ b/src/qt/win_netsocket.c @@ -82,10 +82,12 @@ SOCKET plat_netsocket_accept(SOCKET socket) { SOCKET clientsocket = accept(socket, NULL, NULL); + u_long yes = 1; if (clientsocket == INVALID_SOCKET) return -1; + ioctlsocket(clientsocket, FIONBIO, &yes); return clientsocket; } diff --git a/src/qt/win_serial_passthrough.c b/src/qt/win_serial_passthrough.c index c1802ce73..4ea6a1875 100644 --- a/src/qt/win_serial_passthrough.c +++ b/src/qt/win_serial_passthrough.c @@ -13,7 +13,7 @@ * Jasmine Iwanek * * Copyright 2021 Andreas J. Reichel - * Copyright 2021-2023 Jasmine Iwanek + * Copyright 2021-2025 Jasmine Iwanek */ #define _XOPEN_SOURCE 500 @@ -46,9 +46,9 @@ plat_serpt_close(void *priv) fclose(dev->master_fd); #endif FlushFileBuffers((HANDLE) dev->master_fd); - if (dev->mode == SERPT_MODE_VCON) + if (dev->mode == SERPT_MODE_NPIPE_SRV) DisconnectNamedPipe((HANDLE) dev->master_fd); - if (dev->mode == SERPT_MODE_HOSTSER) { + else if (dev->mode == SERPT_MODE_HOSTSER) { SetCommState((HANDLE) dev->master_fd, (DCB *) dev->backend_priv); free(dev->backend_priv); } @@ -133,7 +133,8 @@ plat_serpt_write(void *priv, uint8_t data) serial_passthrough_t *dev = (serial_passthrough_t *) priv; switch (dev->mode) { - case SERPT_MODE_VCON: + case SERPT_MODE_NPIPE_SRV: + case SERPT_MODE_NPIPE_CLNT: case SERPT_MODE_HOSTSER: plat_serpt_write_vcon(dev, data); break; @@ -157,7 +158,8 @@ plat_serpt_read(void *priv, uint8_t *data) int res = 0; switch (dev->mode) { - case SERPT_MODE_VCON: + case SERPT_MODE_NPIPE_SRV: + case SERPT_MODE_NPIPE_CLNT: case SERPT_MODE_HOSTSER: res = plat_serpt_read_vcon(dev, data); break; @@ -187,6 +189,42 @@ open_pseudo_terminal(serial_passthrough_t *dev) return 1; } +static int +connect_named_pipe_client(serial_passthrough_t *dev) +{ + char ascii_pipe_name[1024] = { 0 }; + size_t len = strlen(dev->named_pipe); + if ((len + 1) >= sizeof(ascii_pipe_name)) + memcpy(ascii_pipe_name, dev->named_pipe, sizeof(ascii_pipe_name)); + else + memcpy(ascii_pipe_name, dev->named_pipe, len + 1); + + HANDLE hPipe = CreateFileA( + ascii_pipe_name, // pipe name + GENERIC_READ | GENERIC_WRITE, + 0, // no sharing + NULL, // default security attributes + OPEN_EXISTING, // open existing pipe + 0, // default attributes + NULL); // no template file + + if (hPipe == INVALID_HANDLE_VALUE) { + DWORD error = GetLastError(); + wchar_t errorMsg[1024] = { 0 }; + wchar_t finalMsg[1024] = { 0 }; + FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errorMsg, 1024, NULL); + swprintf(finalMsg, 1024, L"Named Pipe (client, named_pipe=\"%hs\", port=COM%d): %ls\n", ascii_pipe_name, dev->port + 1, errorMsg); + ui_msgbox(MBX_ERROR | MBX_FATAL, finalMsg); + return 0; + } + + DWORD mode = PIPE_READMODE_BYTE | PIPE_NOWAIT; + SetNamedPipeHandleState(hPipe, &mode, NULL, NULL); + dev->master_fd = (intptr_t) hPipe; + pclog("Named Pipe client connected to %s\n", ascii_pipe_name); + return 1; +} + static int open_host_serial_port(serial_passthrough_t *dev) { @@ -222,15 +260,18 @@ plat_serpt_open_device(void *priv) serial_passthrough_t *dev = (serial_passthrough_t *) priv; switch (dev->mode) { - case SERPT_MODE_VCON: - if (open_pseudo_terminal(dev)) { + case SERPT_MODE_NPIPE_SRV: + if (open_pseudo_terminal(dev)) + return 0; + break; + case SERPT_MODE_NPIPE_CLNT: + if (connect_named_pipe_client(dev)) return 0; - } break; case SERPT_MODE_HOSTSER: - if (open_host_serial_port(dev)) { + if (open_host_serial_port(dev)) return 0; - } + break; default: break; } diff --git a/src/qt/wl_mouse.cpp b/src/qt/wl_mouse.cpp index 5d6d95a0a..6f90bac18 100644 --- a/src/qt/wl_mouse.cpp +++ b/src/qt/wl_mouse.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -30,10 +31,12 @@ extern "C" { #include <86box/plat.h> } -static zwp_relative_pointer_manager_v1 *rel_manager = nullptr; -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 zwp_relative_pointer_manager_v1 *rel_manager = nullptr; +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 zwp_keyboard_shortcuts_inhibit_manager_v1 *kbd_manager = nullptr; +static zwp_keyboard_shortcuts_inhibitor_v1 *kbd_inhibitor = nullptr; static bool wl_init_ok = false; @@ -57,16 +60,25 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id, if (!strcmp(interface, "zwp_pointer_constraints_v1")) { conf_pointer_interface = (zwp_pointer_constraints_v1 *) wl_registry_bind(registry, id, &zwp_pointer_constraints_v1_interface, version); } + if (!strcmp(interface, "zwp_keyboard_shortcuts_inhibit_manager_v1")) { + kbd_manager = (zwp_keyboard_shortcuts_inhibit_manager_v1 *) wl_registry_bind(registry, id, &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, version); + } } static void display_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name) { plat_mouse_capture(0); + if (kbd_inhibitor) { + zwp_keyboard_shortcuts_inhibitor_v1_destroy(kbd_inhibitor); + kbd_inhibitor = nullptr; + } + zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(kbd_manager); zwp_relative_pointer_manager_v1_destroy(rel_manager); zwp_pointer_constraints_v1_destroy(conf_pointer_interface); rel_manager = nullptr; conf_pointer_interface = nullptr; + kbd_manager = nullptr; } static const struct wl_registry_listener registry_listener = { @@ -90,9 +102,20 @@ wl_init() } } +void +wl_keyboard_grab(QWindow *window) +{ + if (!kbd_inhibitor && kbd_manager) { + kbd_inhibitor = zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(kbd_manager, (wl_surface *) QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window), (wl_seat *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_seat")); + } +} + void wl_mouse_capture(QWindow *window) { + if (!kbd_inhibitor) { + kbd_inhibitor = zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(kbd_manager, (wl_surface *) QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window), (wl_seat *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_seat")); + } if (rel_manager) { rel_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(rel_manager, (wl_pointer *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer")); zwp_relative_pointer_v1_add_listener(rel_pointer, &rel_listener, nullptr); diff --git a/src/qt_resources.qrc b/src/qt_resources.qrc index bc553ac61..01bbc866a 100644 --- a/src/qt_resources.qrc +++ b/src/qt_resources.qrc @@ -1,6 +1,8 @@ qt/icons/cartridge.ico + qt/icons/cartridge_image.ico + qt/icons/cassette_image.ico qt/icons/cassette.ico qt/icons/cdrom.ico qt/icons/cdrom_disabled.ico @@ -10,30 +12,53 @@ qt/icons/cdrom_folder.ico qt/icons/cdrom_host.ico qt/icons/display.ico + qt/icons/fast_forward.ico qt/icons/floppy_35.ico + qt/icons/floppy_35_image.ico qt/icons/floppy_525.ico + qt/icons/floppy_525_image.ico qt/icons/floppy_and_cdrom_drives.ico qt/icons/floppy_disabled.ico qt/icons/hard_disk.ico qt/icons/input_devices.ico qt/icons/machine.ico qt/icons/mo.ico + qt/icons/mo_image.ico qt/icons/mo_disabled.ico qt/icons/network.ico qt/icons/other_peripherals.ico qt/icons/other_removable_devices.ico qt/icons/ports.ico + qt/icons/rdisk.ico + qt/icons/rdisk_image.ico + qt/icons/rdisk_disabled.ico + qt/icons/record.ico + qt/icons/rewind.ico qt/icons/sound.ico qt/icons/storage_controllers.ico - qt/icons/zip.ico - qt/icons/zip_disabled.ico + qt/icons/superdisk.ico + qt/icons/superdisk_image.ico + qt/icons/superdisk_disabled.ico qt/icons/active.ico + qt/icons/browse.ico + qt/icons/eject.ico + qt/icons/export.ico + qt/icons/new.ico + qt/icons/write_protected.ico qt/icons/write_active.ico qt/icons/disabled.ico qt/icons/86Box-gray.ico qt/icons/86Box-green.ico qt/icons/86Box-red.ico qt/icons/86Box-yellow.ico + qt/icons/caps_lock_off.ico + qt/icons/caps_lock_on.ico + qt/icons/kana_lock_off.ico + qt/icons/kana_lock_on.ico + qt/icons/num_lock_off.ico + qt/icons/num_lock_on.ico + qt/icons/scroll_lock_off.ico + qt/icons/scroll_lock_on.ico qt/icons/acpi_shutdown.ico @@ -51,4 +76,95 @@ qt/texture_vert.spv qt/texture_frag.spv + + qt/assets/86Box-green.png + qt/assets/86box-rb.png + qt/assets/86box-red.png + qt/assets/86box-yellow.png + qt/assets/86box.png + qt/assets/86box-wizard.png + + + qt/assets/systemicons/cpq_deskpro.png + qt/assets/systemicons/cpq_port_386.png + qt/assets/systemicons/cpq_port_II.png + qt/assets/systemicons/cpq_port_III.png + qt/assets/systemicons/cpq_portable.png + qt/assets/systemicons/cpq_pres_2240.png + qt/assets/systemicons/cpq_pres_4500.png + qt/assets/systemicons/ibm330.png + qt/assets/systemicons/ibm_at.png + qt/assets/systemicons/ibm_pc_81.png + qt/assets/systemicons/ibm_pc_82.png + qt/assets/systemicons/ibm_pcjr.png + qt/assets/systemicons/ibm_ps2_m70.png + qt/assets/systemicons/ibm_ps2_m80.png + qt/assets/systemicons/ibm_psvp_486.png + qt/assets/systemicons/ibm_psvp_p60.png + qt/assets/systemicons/ibm_xt_82.png + qt/assets/systemicons/ibm_xt_86.png + qt/assets/systemicons/olivetti_m19.png + qt/assets/systemicons/olivetti_m21.png + qt/assets/systemicons/olivetti_m24.png + qt/assets/systemicons/olivetti_m24sp.png + qt/assets/systemicons/os_archlinux_x2.png + qt/assets/systemicons/os_cloud_x2.png + qt/assets/systemicons/os_debian_x2.png + qt/assets/systemicons/os_dos_x2.png + qt/assets/systemicons/os_fedora_x2.png + qt/assets/systemicons/os_freebsd_x2.png + qt/assets/systemicons/os_gentoo_x2.png + qt/assets/systemicons/os_jrockitve_x2.png + qt/assets/systemicons/os_l4_x2.png + qt/assets/systemicons/os_linux22_x2.png + qt/assets/systemicons/os_linux24_x2.png + qt/assets/systemicons/os_linux26_x2.png + qt/assets/systemicons/os_linux_x2.png + qt/assets/systemicons/os_macosx_x2.png + qt/assets/systemicons/os_mandriva_x2.png + qt/assets/systemicons/os_netbsd_x2.png + qt/assets/systemicons/os_netware_x2.png + qt/assets/systemicons/os_openbsd_x2.png + qt/assets/systemicons/os_opensuse_x2.png + qt/assets/systemicons/os_oracle_x2.png + qt/assets/systemicons/os_oraclesolaris_x2.png + qt/assets/systemicons/os_os2_other_x2.png + qt/assets/systemicons/os_os2ecs_x2.png + qt/assets/systemicons/os_os2warp3_x2.png + qt/assets/systemicons/os_os2warp45_x2.png + qt/assets/systemicons/os_os2warp4_x2.png + qt/assets/systemicons/os_other_x2.png + qt/assets/systemicons/os_qnx_x2.png + qt/assets/systemicons/os_redhat_x2.png + qt/assets/systemicons/os_solaris_x2.png + qt/assets/systemicons/os_turbolinux_x2.png + qt/assets/systemicons/os_ubuntu_x2.png + qt/assets/systemicons/os_win10_x2.png + qt/assets/systemicons/os_win2k3_x2.png + qt/assets/systemicons/os_win2k8_x2.png + qt/assets/systemicons/os_win2k_x2.png + qt/assets/systemicons/os_win31_x2.png + qt/assets/systemicons/os_win7_x2.png + qt/assets/systemicons/os_win81_x2.png + qt/assets/systemicons/os_win8_x2.png + qt/assets/systemicons/os_win95_x2.png + qt/assets/systemicons/os_win98_x2.png + qt/assets/systemicons/os_win_other_x2.png + qt/assets/systemicons/os_winme_x2.png + qt/assets/systemicons/os_winnt4_x2.png + qt/assets/systemicons/os_winvista_x2.png + qt/assets/systemicons/os_winxp_x2.png + qt/assets/systemicons/os_xandros_x2.png + qt/assets/systemicons/pb_bora_pro.png + qt/assets/systemicons/pb_pb410.png + qt/assets/systemicons/pb_pb640.png + qt/assets/systemicons/pb_pb680.png + qt/assets/systemicons/tandy_1000.png + qt/assets/systemicons/tandy_1000_hx.png + qt/assets/systemicons/tandy_1000_sl2.png + qt/assets/systemicons/toshiba_t1000.png + qt/assets/systemicons/toshiba_t1200.png + qt/assets/systemicons/toshiba_t1200_hdd.png + + diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index bbce63651..a2bdc92ce 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -33,7 +33,7 @@ #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/cdrom.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/scsi_disk.h> #include <86box/scsi_aha154x.h> #include <86box/scsi_buslogic.h> @@ -54,6 +54,14 @@ typedef const struct { static SCSI_CARD scsi_cards[] = { // clang-format off { &device_none, }, + /* ISA/Sidecar */ + { &scsi_ls2000_device, }, + /* ISA */ + { &scsi_lcs6821n_device, }, + { &scsi_rt1000b_device, }, + { &scsi_t128_device, }, + { &scsi_t130b_device, }, + /* ISA16 */ { &aha154xa_device, }, { &aha154xb_device, }, { &aha154xc_device, }, @@ -63,18 +71,19 @@ static SCSI_CARD scsi_cards[] = { { &buslogic_542bh_device, }, { &buslogic_545s_device, }, { &buslogic_545c_device, }, - { &scsi_ls2000_device, }, - { &scsi_lcs6821n_device, }, - { &scsi_rt1000b_device, }, - { &scsi_rt1000mc_device, }, - { &scsi_t128_device, }, - { &scsi_t228_device, }, - { &scsi_t130b_device, }, + /* MCA */ { &aha1640_device, }, { &buslogic_640a_device, }, - { &ncr53c90a_mca_device, }, { &spock_device, }, { &tribble_device, }, + { &ncr53c90a_mca_device, }, + { &scsi_rt1000mc_device, }, + { &scsi_t228_device, }, + /* VLB */ + { &buslogic_445s_device, }, + { &buslogic_445c_device, }, + /* PCI */ + { &am53c974_pci_device, }, { &buslogic_958d_pci_device, }, { &ncr53c810_pci_device, }, { &ncr53c815_pci_device, }, @@ -82,10 +91,7 @@ static SCSI_CARD scsi_cards[] = { { &ncr53c825a_pci_device, }, { &ncr53c860_pci_device, }, { &ncr53c875_pci_device, }, - { &am53c974_pci_device, }, { &dc390_pci_device, }, - { &buslogic_445s_device, }, - { &buslogic_445c_device, }, { NULL, }, // clang-format on }; diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 7c887e28b..7161a53bb 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -1006,8 +1006,10 @@ aha_init(const device_t *info) switch (dev->type) { case AHA_154xA: strcpy(dev->name, "AHA-154xA"); - dev->fw_rev = "A003"; /* The 3.07 microcode says A006. */ - dev->bios_path = "roms/scsi/adaptec/aha1540a307.bin"; /*Only for port 0x330*/ + bios_rev = (char *) device_get_config_bios("bios_rev"); + dev->bios_path = (char *) device_get_bios_file(info, bios_rev, 0); + dev->fw_rev = "A006"; /*3.07 (Port 0x330) normal microcode (M_E7BC.BIN)*/ + /* This is configurable from the configuration for the 154xB, the rest of the controllers read it from the EEPROM. */ dev->HostID = device_get_config_int("hostid"); @@ -1018,19 +1020,19 @@ aha_init(const device_t *info) case AHA_154xB: strcpy(dev->name, "AHA-154xB"); - switch (dev->Base) { - case 0x0330: - dev->bios_path = "roms/scsi/adaptec/aha1540b320_330.bin"; - break; + bios_rev = (char *) device_get_config_bios("bios_rev"); + dev->bios_path = (char *) device_get_bios_file(info, bios_rev, 0); + if (!strcmp(bios_rev, "v3_08")) + dev->fw_rev = "A003"; /*3.08 (Port 0x330) normal microcode (U12 27C128 Microcode v3.08.bin)*/ + else if (!strcmp(bios_rev, "v3_10") || !strcmp(bios_rev, "v3_10_p334") || !strcmp(bios_rev, "v3_1b_p334")) + dev->fw_rev = "A005"; /*3.10 (and revisions) normal microcode (M_FC8A.BIN)*/ + else if (!strcmp(bios_rev, "v3_11")) + dev->fw_rev = "A008"; /*3.11 (Port 0x330) normal microcode (1542BU12V311.BIN)*/ + else if (!strcmp(bios_rev, "v3_20") || !strcmp(bios_rev, "v3_20_p334")) + dev->fw_rev = "A014"; /*3.20 normal microcode (M_3054.BIN)*/ + else + dev->fw_rev = "A012"; /*3.20 (port 0x330) extended timeout microcode (M_5D98.BIN)*/ - case 0x0334: - dev->bios_path = "roms/scsi/adaptec/aha1540b320_334.bin"; - break; - - default: - break; - } - dev->fw_rev = "A005"; /* The 3.2 microcode says A012. */ /* This is configurable from the configuration for the 154xB, the rest of the controllers read it from the EEPROM. */ dev->HostID = device_get_config_int("hostid"); @@ -1156,6 +1158,125 @@ aha_init(const device_t *info) } // clang-format off +static const device_config_t aha_154xa_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x334, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "None", .value = 0 }, + { .description = "0x330", .value = 0x330 }, + { .description = "0x334", .value = 0x334 }, + { .description = "0x230", .value = 0x230 }, + { .description = "0x234", .value = 0x234 }, + { .description = "0x130", .value = 0x130 }, + { .description = "0x134", .value = 0x134 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 11, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 9", .value = 9 }, + { .description = "IRQ 10", .value = 10 }, + { .description = "IRQ 11", .value = 11 }, + { .description = "IRQ 12", .value = 12 }, + { .description = "IRQ 14", .value = 14 }, + { .description = "IRQ 15", .value = 15 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 6, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 5", .value = 5 }, + { .description = "DMA 6", .value = 6 }, + { .description = "DMA 7", .value = 7 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "hostid", + .description = "Host ID", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 7, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0", .value = 0 }, + { .description = "1", .value = 1 }, + { .description = "2", .value = 2 }, + { .description = "3", .value = 3 }, + { .description = "4", .value = 4 }, + { .description = "5", .value = 5 }, + { .description = "6", .value = 6 }, + { .description = "7", .value = 7 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "bios_rev", + .description = "BIOS Revision", + .type = CONFIG_BIOS, + .default_string = "v3_07", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "Version 3.07 (Port 0x330)", + .internal_name = "v3_07", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { "roms/scsi/adaptec/aha1540a307.bin", "" } + }, + { .files_no = 0 } + }, + }, + { + .name = "bios_addr", + .description = "BIOS address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "C800H", .value = 0xc8000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + static const device_config_t aha_154xb_config[] = { { .name = "base", @@ -1233,9 +1354,93 @@ static const device_config_t aha_154xb_config[] = { }, .bios = { { 0 } } }, + { + .name = "bios_rev", + .description = "BIOS Revision", + .type = CONFIG_BIOS, + .default_string = "v3_20_p334", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "Version 3.08 (Port 0x330)", + .internal_name = "v3_08", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { "roms/scsi/adaptec/U13 27C128 BIOS v3.08.bin", "" } + }, + { + .name = "Version 3.10 (Port 0x330)", + .internal_name = "v3_10", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { "roms/scsi/adaptec/aha1540b310.bin", "" } + }, + { + .name = "Version 3.10 (Port 0x334)", + .internal_name = "v3_10_p334", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { "roms/scsi/adaptec/154xp334.bin", "" } + }, + { + .name = "Version 3.1b (Port 0x334)", + .internal_name = "v3_1b_p334", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { "roms/scsi/adaptec/154xp334_v31b.bin", "" } + }, + { + .name = "Version 3.11 (Port 0x330)", + .internal_name = "v3_11", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { "roms/scsi/adaptec/1542BU13V311.BIN", "" } + }, + { + .name = "Version 3.20 (Port 0x330)", + .internal_name = "v3_20", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { "roms/scsi/adaptec/aha1540b320_330.bin", "" } + }, + { + .name = "Version 3.20 (Port 0x330) (Ext. Timeout)", + .internal_name = "v3_20_exttimeout", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { "roms/scsi/adaptec/B_B300.BIN", "" } + }, + { + .name = "Version 3.20 (Port 0x334)", + .internal_name = "v3_20_p334", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { "roms/scsi/adaptec/aha1540b320_334.bin", "" } + }, + { .files_no = 0 } + }, + }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0, @@ -1254,7 +1459,7 @@ static const device_config_t aha_154xb_config[] = { { .name = "", .description = "", .type = CONFIG_END } }; -static const device_config_t aha_154x_config[] = { +static const device_config_t aha_154xc_config[] = { { .name = "base", .description = "Address", @@ -1312,7 +1517,7 @@ static const device_config_t aha_154x_config[] = { }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0, @@ -1389,7 +1594,7 @@ static const device_config_t aha_154xcf_config[] = { }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0, @@ -1481,7 +1686,7 @@ const device_t aha154xa_device = { .available = NULL, .speed_changed = NULL, .force_redraw = NULL, - .config = aha_154xb_config + .config = aha_154xa_config }; const device_t aha154xb_device = { @@ -1509,7 +1714,7 @@ const device_t aha154xc_device = { .available = NULL, .speed_changed = NULL, .force_redraw = NULL, - .config = aha_154x_config + .config = aha_154xc_config }; const device_t aha154xcf_device = { diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index 0e8954aff..c2ecc7b62 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -1874,7 +1874,7 @@ static const device_config_t BT_ISA_Config[] = { }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0, diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 95c8c3640..afafa00ba 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1048,7 +1048,7 @@ scsi_cdrom_read_data(scsi_cdrom_t *dev, const int msf, const int type, const int dev->sectors_num = 0; - if (dev->drv->cd_status == CD_STATUS_EMPTY) + if ((dev->drv->cd_status == CD_STATUS_EMPTY) || (dev->drv->cd_status == CD_STATUS_DVD_REJECTED)) scsi_cdrom_not_ready(dev); else if (dev->sector_pos > dev->drv->cdrom_capacity) { scsi_cdrom_lba_out_of_range(dev); @@ -1242,10 +1242,10 @@ scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, const uint8_t *cdb) if (!(scsi_cdrom_command_flags[cdb[0]] & ALLOW_UA)) scsi_cdrom_insert((void *) dev); - ready = (dev->drv->cd_status != CD_STATUS_EMPTY); + ready = (dev->drv->cd_status != CD_STATUS_EMPTY) && (dev->drv->cd_status != CD_STATUS_DVD_REJECTED); } } else - ready = (dev->drv->cd_status != CD_STATUS_EMPTY); + ready = (dev->drv->cd_status != CD_STATUS_EMPTY) && (dev->drv->cd_status != CD_STATUS_DVD_REJECTED); skip_ready_check: /* @@ -1325,10 +1325,18 @@ scsi_cdrom_update_sector_flags(scsi_cdrom_t *dev) dev->sector_type = 0x08 | ((2048 / dev->drv->sector_size) << 4); dev->sector_flags = 0x0010; break; + case 2052: + dev->sector_type = 0x18; + dev->sector_flags = 0x0030; + break; case 2056: dev->sector_type = 0x18; dev->sector_flags = 0x0050; break; + case 2060: + dev->sector_type = 0x18; + dev->sector_flags = 0x0070; + break; case 2324: case 2328: dev->sector_type = (dev->drv->sector_size == 2328) ? 0x1a : 0x1b; dev->sector_flags = 0x0018; @@ -1437,7 +1445,8 @@ scsi_cdrom_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t al { scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; - if ((dev->drv->cd_status == CD_STATUS_EMPTY) && dev->unit_attention) { + if (((dev->drv->cd_status == CD_STATUS_EMPTY) || + (dev->drv->cd_status == CD_STATUS_DVD_REJECTED)) && dev->unit_attention) { /* If the drive is not ready, there is no reason to keep the UNIT ATTENTION condition present, as we only use it to mark disc changes. @@ -2849,7 +2858,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) Also, the max_len variable is reused as this command does otherwise not use it, to avoid having to declare another variable. */ - if (dev->drv->cd_status == CD_STATUS_EMPTY) + if ((dev->drv->cd_status == CD_STATUS_EMPTY) || (dev->drv->cd_status == CD_STATUS_DVD_REJECTED)) max_len = 70; /* No media inserted. */ else if (dev->drv->cd_status == CD_STATUS_DVD) max_len = 65; /* DVD. */ @@ -2926,7 +2935,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) alloc_length = 0; - if (dev->drv->cd_status != CD_STATUS_EMPTY) { + if ((dev->drv->cd_status != CD_STATUS_EMPTY) && (dev->drv->cd_status != CD_STATUS_DVD_REJECTED)) { if (dev->drv->cd_status == CD_STATUS_DVD) { b[6] = (MMC_PROFILE_DVD_ROM >> 8) & 0xff; b[7] = MMC_PROFILE_DVD_ROM & 0xff; @@ -2950,7 +2959,8 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) alloc_length += 4; b += 4; - for (uint8_t i = 0; i < 2; i++) { + int max_profiles = cdrom_is_dvd(dev->drv->type) ? 2 : 1; + for (uint8_t i = 0; i < max_profiles; i++) { b[0] = (profiles[i] >> 8) & 0xff; b[1] = profiles[i] & 0xff; @@ -2958,7 +2968,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) b[2] |= 1; alloc_length += 4; - b += 4; + b += 4; } } if ((feature == 1) || ((cdb[1] & 3) < 2)) { @@ -3026,7 +3036,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) alloc_length += 8; b += 8; } - if ((feature == 0x1f) || ((cdb[1] & 3) < 2)) { + if (cdrom_is_dvd(dev->drv->type) && ((feature == 0x1f) || ((cdb[1] & 3) < 2))) { b[1] = 0x1f; b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ b[3] = 0; @@ -3096,7 +3106,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) gesn_event_header->notification_class |= GESN_MEDIA; /* Bits 7-4 = Reserved, Bits 4-1 = Media Status. */ - if (dev->drv->cd_status == CD_STATUS_EMPTY) + if ((dev->drv->cd_status == CD_STATUS_EMPTY) || (dev->drv->cd_status == CD_STATUS_DVD_REJECTED)) dev->buffer[4] = MEC_MEDIA_REMOVAL; else dev->buffer[4] = dev->unit_attention ? MEC_NEW_MEDIA : MEC_NO_CHANGE; diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index f91dc83a9..5f2302b4f 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -759,7 +759,7 @@ ncr53c400_init(const device_t *info) scsi_bus->bus_device = ncr->bus; scsi_bus->timer = ncr->timer; scsi_bus->priv = ncr->priv; - ncr400->status_ctrl = STATUS_BUFFER_NOT_READY; + ncr400->status_ctrl = 0x00; ncr400->buffer_host_pos = 128; timer_add(&ncr400->timer, ncr53c400_callback, ncr400, 0); @@ -821,7 +821,7 @@ corel_ls2000_available(void) static const device_config_t ncr53c400_mmio_config[] = { { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xD8000, @@ -859,9 +859,40 @@ static const device_config_t ncr53c400_mmio_config[] = { }; static const device_config_t rt1000b_config[] = { + { + .name = "bios_ver", + .description = "BIOS Revision", + .type = CONFIG_BIOS, + .default_string = "v8_10r", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "Version 8.10R", + .internal_name = "v8_10r", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { RT1000B_810R_ROM, "" } + }, + { + .name = "Version 8.20R", + .internal_name = "v8_20r", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { RT1000B_820R_ROM, "" } + }, + { .files_no = 0 } + }, + }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xD8000, @@ -895,37 +926,6 @@ static const device_config_t rt1000b_config[] = { }, .bios = { { 0 } } }, - { - .name = "bios_ver", - .description = "BIOS Revision", - .type = CONFIG_BIOS, - .default_string = "v8_10r", - .default_int = 0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { { 0 } }, - .bios = { - { - .name = "Version 8.10R", - .internal_name = "v8_10r", - .bios_type = BIOS_NORMAL, - .files_no = 1, - .local = 0, - .size = 8192, - .files = { RT1000B_810R_ROM, "" } - }, - { - .name = "Version 8.20R", - .internal_name = "v8_20r", - .bios_type = BIOS_NORMAL, - .files_no = 1, - .local = 0, - .size = 8192, - .files = { RT1000B_820R_ROM, "" } - }, - { .files_no = 0 } - }, - }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -953,7 +953,7 @@ static const device_config_t rt1000b_mc_config[] = { static const device_config_t t130b_config[] = { { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xD8000, diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 7c991bdb1..b0563020b 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -46,14 +46,25 @@ #include <86box/scsi_pcscsi.h> #include <86box/vid_ati_eeprom.h> #include <86box/fifo8.h> +#include "cpu.h" -#define DC390_ROM "roms/scsi/esp_pci/INT13.BIN" -#define AM53C974_ROM "roms/scsi/esp_pci/harom.bin" +#define DC390_ROM "roms/scsi/esp_pci/INT13.BIN" +#define AM53C974_3_01_AMD_ROM "roms/scsi/esp_pci/ebrom.bin" +#define AM53C974_3_43_ROM "roms/scsi/esp_pci/2974BIOS.BIN" +#define AM53C974_4_00_ROM "roms/scsi/esp_pci/2974bios-4-00.bin" +#define AM53C974_5_00_ROM "roms/scsi/esp_pci/2974bios-5-00.bin" +#define AM53C974_5_11_ROM "roms/scsi/esp_pci/2974bios-5-11.bin" #define ESP_REGS 16 #define ESP_FIFO_SZ 16 #define ESP_CMDFIFO_SZ 32 +enum ESPASCMode { + ESP_ASC_MODE_DIS = 0, /* Disconnected */ + ESP_ASC_MODE_INI = 1, /* Initiator */ + ESP_ASC_MODE_TGT = 2 /* Target */ +}; + #define ESP_TCLO 0x0 #define ESP_TCMID 0x1 #define ESP_FIFO 0x2 @@ -80,6 +91,13 @@ #define CMD_DMA 0x80 #define CMD_CMD 0x7f +#define CMD_GRP_MASK 0x70 + +#define CMD_GRP_MISC 0x00 +#define CMD_GRP_INIT 0x01 +#define CMD_GRP_TRGT 0x02 +#define CMD_GRP_DISC 0x04 + #define CMD_NOP 0x00 #define CMD_FLUSH 0x01 #define CMD_RESET 0x02 @@ -114,7 +132,7 @@ #define INTR_FC 0x08 #define INTR_BS 0x10 #define INTR_DC 0x20 -#define INTR_ILL 0x40 +#define INTR_IL 0x40 #define INTR_RST 0x80 #define SEQ_0 0x0 @@ -153,8 +171,7 @@ #define SBAC_PABTEN (1 << 25) typedef struct esp_t { - mem_mapping_t mmio_mapping; - mem_mapping_t ram_mapping; + char *bios_path; char nvr_path[64]; uint8_t pci_slot; int has_bios; @@ -176,6 +193,7 @@ typedef struct esp_t { uint8_t id, lun; Fifo8 cmdfifo; uint8_t cmdfifo_cdb_offset; + uint8_t asc_mode; int data_ready; int32_t xfer_counter; @@ -206,6 +224,8 @@ typedef struct esp_t { uint8_t pos_regs[8]; } esp_t; +static esp_t reset_state = { 0 }; + #define READ_FROM_DEVICE 1 #define WRITE_TO_DEVICE 0 @@ -280,10 +300,10 @@ esp_pci_update_irq(esp_t *dev) if (level) { pci_set_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); - esp_log("Raising PCI IRQ...\n"); + esp_log("Raising PCI IRQ..., SCSIL=%d, DMAL=%d\n", scsi_level, dma_level); } else { pci_clear_irq(dev->pci_slot, PCI_INTA, &dev->irq_state); - esp_log("Lowering PCI IRQ...\n"); + esp_log("Lowering PCI IRQ..., SCSIL=%d, DMAL=%d\n", scsi_level, dma_level); } } @@ -310,6 +330,7 @@ esp_irq(esp_t *dev, int level) * DMA_STAT_DONE and the ESP IRQ arriving which is visible to the * guest that can cause confusion e.g. Linux */ + esp_log("ESP IRQ issuing: WBC=%d, CMDMask=%03x.\n", dev->dma_regs[DMA_WBC], dev->dma_regs[DMA_CMD] & DMA_CMD_MASK); if (((dev->dma_regs[DMA_CMD] & DMA_CMD_MASK) == 0x03) && (dev->dma_regs[DMA_WBC] == 0)) dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE; @@ -435,12 +456,14 @@ esp_select(esp_t *dev) esp_log("ESP SCSI no devices on ID %d, LUN %d\n", dev->id, dev->lun); /* No such drive */ dev->rregs[ESP_RSTAT] = 0; + dev->asc_mode = ESP_ASC_MODE_DIS; dev->rregs[ESP_RINTR] = INTR_DC; esp_raise_irq(dev); return -1; } else esp_log("ESP SCSI device present on ID %d, LUN %d\n", dev->id, dev->lun); + dev->asc_mode = ESP_ASC_MODE_INI; return 0; } @@ -460,9 +483,10 @@ esp_transfer_data(esp_t *dev) * Initial incoming data xfer is complete for sequencer command * so raise deferred bus service and function complete interrupt */ - dev->rregs[ESP_RINTR] |= (INTR_BS | INTR_FC); - dev->rregs[ESP_RSEQ] = SEQ_CD; - break; + dev->rregs[ESP_RINTR] |= (INTR_BS | INTR_FC); + dev->rregs[ESP_RSEQ] = SEQ_CD; + esp_raise_irq(dev); + break; case CMD_SELATNS: case (CMD_SELATNS | CMD_DMA): @@ -470,22 +494,26 @@ esp_transfer_data(esp_t *dev) * Initial incoming data xfer is complete so raise command * completion interrupt */ - dev->rregs[ESP_RINTR] |= INTR_BS; - dev->rregs[ESP_RSEQ] = SEQ_MO; - break; + dev->rregs[ESP_RINTR] |= INTR_BS; + dev->rregs[ESP_RSEQ] = SEQ_MO; + esp_raise_irq(dev); + break; case CMD_TI: case (CMD_TI | CMD_DMA): /* - * Bus service interrupt raised because of initial change to - * DATA phase + * If the final COMMAND phase data was transferred using a TI + * command, clear ESP_CMD to terminate the TI command and raise + * the completion interrupt */ dev->rregs[ESP_CMD] = 0; dev->rregs[ESP_RINTR] |= INTR_BS; + esp_raise_irq(dev); + break; + + default: break; } - - esp_raise_irq(dev); } /* @@ -531,7 +559,7 @@ esp_do_command_phase(esp_t *dev) dev->ti_size = sd->buffer_length; dev->xfer_counter = sd->buffer_length; - esp_log("ESP SCSI Command = 0x%02x, ID = %d, LUN = %d, len = %d, phase = %02x.\n", buf[0], dev->id, dev->lun, sd->buffer_length, sd->phase); + esp_log("ESP SCSI Command = 0x%02x, ID = %d, LUN = %d, len = %d, phase = %02x, PCI DMA cmd mask = %02x.\n", buf[0], dev->id, dev->lun, sd->buffer_length, sd->phase, dev->dma_regs[DMA_CMD] & DMA_CMD_MASK); fifo8_reset(&dev->cmdfifo); @@ -570,10 +598,12 @@ esp_do_message_phase(esp_t *dev) dev->lun = message & 7; dev->cmdfifo_cdb_offset--; + esp_log("Scanning LUN=%d.\n", dev->lun); if (scsi_device_present(&scsi_devices[dev->bus][dev->id]) && (dev->lun > 0)) { /* We only support LUN 0 */ esp_log("LUN = %i\n", dev->lun); dev->rregs[ESP_RSTAT] = 0; + dev->asc_mode = ESP_ASC_MODE_DIS; dev->rregs[ESP_RINTR] = INTR_DC; dev->rregs[ESP_RSEQ] = SEQ_0; esp_raise_irq(dev); @@ -598,8 +628,8 @@ esp_do_cmd(esp_t *dev) { esp_log("DO CMD.\n"); esp_do_message_phase(dev); - assert(dev->cmdfifo_cdb_offset == 0); - esp_do_command_phase(dev); + if (dev->cmdfifo_cdb_offset >= 0) + esp_do_command_phase(dev); } static void @@ -610,7 +640,10 @@ esp_dma_enable(esp_t *dev, int level) dev->dma_enabled = 1; 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); + if (dev->wregs[ESP_WCCF] & 0x07) + timer_on_auto(&dev->timer, ((double)(dev->wregs[ESP_WCCF] & 0x07)) * 5.0); + else + timer_on_auto(&dev->timer, 40.0); } else { esp_log("Period = %lf\n", dev->period); timer_on_auto(&dev->timer, dev->period); @@ -631,7 +664,9 @@ esp_hard_reset(esp_t *dev) fifo8_reset(&dev->cmdfifo); dev->dma = 0; dev->tchi_written = 0; + dev->asc_mode = ESP_ASC_MODE_DIS; dev->rregs[ESP_CFG1] = dev->mca ? dev->HostID : 7; + esp_log("ESP Reset\n"); timer_stop(&dev->timer); @@ -679,25 +714,28 @@ esp_do_dma(esp_t *dev) uint8_t buf[ESP_CMDFIFO_SZ]; uint32_t len; - esp_log("ESP SCSI Actual DMA len = %d\n", esp_get_tc(dev)); - len = esp_get_tc(dev); + esp_log("ESP SCSI Actual DMA len=%d, cfg3=%02x.\n", len, dev->rregs[ESP_CFG3]); + switch (esp_get_phase(dev)) { case STAT_MO: len = MIN(len, fifo8_num_free(&dev->cmdfifo)); - if (dev->mca) { - dma_set_drq(dev->DmaChannel, 1); - while (dev->dma_86c01.pos < len) { - int val = dma_channel_read(dev->DmaChannel); - buf[dev->dma_86c01.pos++] = val & 0xff; - } - dev->dma_86c01.pos = 0; - dma_set_drq(dev->DmaChannel, 0); - } else - esp_pci_dma_memory_rw(dev, buf, len, WRITE_TO_DEVICE); + esp_log("ESP SCSI Message Out len=%d.\n", len); + if (len) { + if (dev->mca) { + dma_set_drq(dev->DmaChannel, 1); + while (dev->dma_86c01.pos < len) { + int val = dma_channel_read(dev->DmaChannel); + buf[dev->dma_86c01.pos++] = val & 0xff; + } + dev->dma_86c01.pos = 0; + dma_set_drq(dev->DmaChannel, 0); + } else + esp_pci_dma_memory_rw(dev, buf, len, WRITE_TO_DEVICE); - esp_set_tc(dev, esp_get_tc(dev) - len); + esp_set_tc(dev, esp_get_tc(dev) - len); + } fifo8_push_all(&dev->cmdfifo, buf, len); dev->cmdfifo_cdb_offset += len; @@ -745,19 +783,21 @@ esp_do_dma(esp_t *dev) case STAT_CD: len = MIN(len, fifo8_num_free(&dev->cmdfifo)); - if (dev->mca) { - dma_set_drq(dev->DmaChannel, 1); - while (dev->dma_86c01.pos < len) { - int val = dma_channel_read(dev->DmaChannel); - buf[dev->dma_86c01.pos++] = val & 0xff; - } - dev->dma_86c01.pos = 0; - dma_set_drq(dev->DmaChannel, 0); - } else - esp_pci_dma_memory_rw(dev, buf, len, WRITE_TO_DEVICE); + if (len) { + if (dev->mca) { + dma_set_drq(dev->DmaChannel, 1); + while (dev->dma_86c01.pos < len) { + int val = dma_channel_read(dev->DmaChannel); + buf[dev->dma_86c01.pos++] = val & 0xff; + } + dev->dma_86c01.pos = 0; + dma_set_drq(dev->DmaChannel, 0); + } else + esp_pci_dma_memory_rw(dev, buf, len, WRITE_TO_DEVICE); - fifo8_push_all(&dev->cmdfifo, buf, len); - esp_set_tc(dev, esp_get_tc(dev) - len); + fifo8_push_all(&dev->cmdfifo, buf, len); + esp_set_tc(dev, esp_get_tc(dev) - len); + } dev->ti_size = 0; if (esp_get_tc(dev) == 0) { /* Command has been received */ @@ -775,20 +815,22 @@ esp_do_dma(esp_t *dev) switch (dev->rregs[ESP_CMD]) { case (CMD_TI | CMD_DMA): - if (dev->mca) { - dma_set_drq(dev->DmaChannel, 1); - while (dev->dma_86c01.pos < len) { - int val = dma_channel_read(dev->DmaChannel); - 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++; - } - dma_set_drq(dev->DmaChannel, 0); - dev->dma_86c01.pos = 0; - } else - esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, len, WRITE_TO_DEVICE); + if (len) { + if (dev->mca) { + dma_set_drq(dev->DmaChannel, 1); + while (dev->dma_86c01.pos < len) { + int val = dma_channel_read(dev->DmaChannel); + 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++; + } + dma_set_drq(dev->DmaChannel, 0); + dev->dma_86c01.pos = 0; + } else + esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, len, WRITE_TO_DEVICE); - esp_set_tc(dev, esp_get_tc(dev) - len); + esp_set_tc(dev, esp_get_tc(dev) - len); + } dev->buffer_pos += len; dev->xfer_counter -= len; dev->ti_size += len; @@ -834,18 +876,19 @@ esp_do_dma(esp_t *dev) switch (dev->rregs[ESP_CMD]) { case (CMD_TI | CMD_DMA): - if (dev->mca) { - dma_set_drq(dev->DmaChannel, 1); - while (dev->dma_86c01.pos < len) { - dma_channel_write(dev->DmaChannel, 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; - dma_set_drq(dev->DmaChannel, 0); - } else - esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, len, READ_FROM_DEVICE); - + if (len) { + if (dev->mca) { + dma_set_drq(dev->DmaChannel, 1); + while (dev->dma_86c01.pos < len) { + dma_channel_write(dev->DmaChannel, 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; + dma_set_drq(dev->DmaChannel, 0); + } else + esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, len, READ_FROM_DEVICE); + } dev->buffer_pos += len; dev->xfer_counter -= len; dev->ti_size -= len; @@ -886,6 +929,7 @@ esp_do_dma(esp_t *dev) if (len) { buf[0] = dev->status; + /* Length already non-zero */ if (dev->mca) { dma_set_drq(dev->DmaChannel, 1); while (dev->dma_86c01.pos < len) { @@ -925,6 +969,7 @@ esp_do_dma(esp_t *dev) if (len) { buf[0] = 0; + /* Length already non-zero */ if (dev->mca) { dma_set_drq(dev->DmaChannel, 1); while (dev->dma_86c01.pos < len) { @@ -943,6 +988,9 @@ esp_do_dma(esp_t *dev) esp_raise_irq(dev); } break; + + default: + break; } break; @@ -991,6 +1039,7 @@ esp_do_nodma(esp_t *dev) uint8_t buf[ESP_FIFO_SZ]; int len; + esp_log("No DMA phase=%x.\n", esp_get_phase(dev)); switch (esp_get_phase(dev)) { case STAT_MO: switch (dev->rregs[ESP_CMD]) { @@ -998,8 +1047,10 @@ esp_do_nodma(esp_t *dev) /* Copy FIFO into cmdfifo */ len = esp_fifo_pop_buf(dev, buf, fifo8_num_used(&dev->fifo)); len = MIN(fifo8_num_free(&dev->cmdfifo), len); + esp_log("ESP Message Out CMD SelAtn len=%d.\n", len); fifo8_push_all(&dev->cmdfifo, buf, len); + esp_log("ESP Message Out CMD SelAtn FIFO num used=%d.\n", fifo8_num_used(&dev->cmdfifo)); if (fifo8_num_used(&dev->cmdfifo) >= 1) { /* First byte received, switch to command phase */ esp_set_phase(dev, STAT_CD); @@ -1015,11 +1066,13 @@ esp_do_nodma(esp_t *dev) case CMD_SELATNS: /* Copy one byte from FIFO into cmdfifo */ - len = esp_fifo_pop_buf(dev, buf, - MIN(fifo8_num_used(&dev->fifo), 1)); + len = esp_fifo_pop_buf(dev, buf, MIN(fifo8_num_used(&dev->fifo), 1)); + esp_log("ESP Message Out CMD SelAtnStop len1=%d.\n", len); len = MIN(fifo8_num_free(&dev->cmdfifo), len); + esp_log("ESP Message Out CMD SelAtnStop len2=%d.\n", len); fifo8_push_all(&dev->cmdfifo, buf, len); + esp_log("ESP Message Out CMD SelAtnStop FIFO num used=%d.\n", fifo8_num_used(&dev->cmdfifo)); if (fifo8_num_used(&dev->cmdfifo) >= 1) { /* First byte received, stop in message out phase */ dev->rregs[ESP_RSEQ] = SEQ_MO; @@ -1034,11 +1087,14 @@ esp_do_nodma(esp_t *dev) case CMD_TI: /* Copy FIFO into cmdfifo */ len = esp_fifo_pop_buf(dev, buf, fifo8_num_used(&dev->fifo)); + esp_log("ESP Message Out CMD TI len1=%d.\n", len); len = MIN(fifo8_num_free(&dev->cmdfifo), len); + esp_log("ESP Message Out CMD TI len2=%d.\n", len); fifo8_push_all(&dev->cmdfifo, buf, len); /* ATN remains asserted until FIFO empty */ dev->cmdfifo_cdb_offset = fifo8_num_used(&dev->cmdfifo); + esp_log("ESP Message Out CMD TI CDB offset=%d.\n", dev->cmdfifo_cdb_offset); esp_set_phase(dev, STAT_CD); dev->rregs[ESP_CMD] = 0; dev->rregs[ESP_RINTR] |= INTR_BS; @@ -1144,6 +1200,7 @@ esp_do_nodma(esp_t *dev) case STAT_ST: switch (dev->rregs[ESP_CMD]) { case CMD_ICCS: + esp_log("ICCS Status=%x.\n", dev->status); esp_fifo_push(dev, dev->status); esp_set_phase(dev, STAT_MI); @@ -1211,15 +1268,18 @@ esp_command_complete(void *priv, uint32_t status) static void esp_timer_on(esp_t *dev, scsi_device_t *sd, double p) { - if (dev->mca) { - /* Normal SCSI: 5000000 bytes per second */ - dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.2); - } else { + if ((dev->rregs[ESP_CFG3] & 0x18) == 0x18) { /* Fast SCSI: 10000000 bytes per second */ dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.1); + } else { + /* Normal SCSI: 5000000 bytes per second */ + dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.2); } - timer_on_auto(&dev->timer, dev->period + 40.0); + if ((dev->wregs[ESP_WCCF] & 0x07) == 0x00) + timer_on_auto(&dev->timer, dev->period + 40.0); + else + timer_on_auto(&dev->timer, dev->period + (((double)(dev->wregs[ESP_WCCF] & 0x07)) * 5.0)); } static void @@ -1289,8 +1349,8 @@ handle_satn_stop(void *priv) if (esp_select(dev) < 0) return; + esp_log("Selection with ATN and Stop.\n"); esp_set_phase(dev, STAT_MO); - dev->cmdfifo_cdb_offset = 0; if (dev->dma) esp_do_dma(dev); @@ -1323,6 +1383,37 @@ esp_callback(void *priv) } } +static int +esp_cmd_is_valid(esp_t *dev, uint8_t cmd) +{ + uint8_t cmd_group = (cmd & CMD_GRP_MASK) >> 4; + + /* Always allow misc commands */ + if (cmd_group == CMD_GRP_MISC) + return 1; + + switch (dev->asc_mode) { + case ESP_ASC_MODE_DIS: + /* Disconnected mode: only allow disconnected commands */ + if (cmd_group == CMD_GRP_DISC) + return 1; + + break; + + case ESP_ASC_MODE_INI: + /* Initiator mode: allow initiator commands */ + if (cmd_group == CMD_GRP_INIT) + return 1; + + break; + + default: + break; + } + + return 0; +} + static uint32_t esp_reg_read(esp_t *dev, uint32_t saddr) { @@ -1338,29 +1429,38 @@ esp_reg_read(esp_t *dev, uint32_t saddr) except TC */ ret = dev->rregs[ESP_RINTR]; dev->rregs[ESP_RINTR] = 0; - dev->rregs[ESP_RSTAT] &= ~STAT_TC; - esp_log("ESP SCSI Clear sequence step\n"); + dev->rregs[ESP_RSTAT] &= ~(0x08 | STAT_PE | STAT_GE | STAT_TC); esp_lower_irq(dev); - esp_log("ESP RINTR read old val = %02x\n", ret); + esp_log("Read Interrupt=%02x (old).\n", ret); break; case ESP_TCHI: /* Return the unique id if the value has never been written */ - if (dev->mca) { + if (!dev->mca && !dev->tchi_written) + ret = TCHI_AM53C974; + else ret = dev->rregs[ESP_TCHI]; - } else { - if (!dev->tchi_written) - ret = TCHI_AM53C974; - else - ret = dev->rregs[ESP_TCHI]; - } + + esp_log("Read TCHI Register=%02x.\n", ret); break; case ESP_RFLAGS: ret = fifo8_num_used(&dev->fifo); break; + case ESP_RSTAT: + ret = dev->rregs[ESP_RSTAT]; + esp_log("Read SCSI Status Register=%02x.\n", ret); + break; + case ESP_RSEQ: + ret = dev->rregs[ESP_RSEQ]; + esp_log("Read Sequence Step=%02x, intr=%02x.\n", ret, dev->rregs[ESP_RINTR]); + break; + case ESP_CFG2: + ret = dev->rregs[ESP_CFG2] & 0x40; + esp_log("Read CFG2 Register=%02x.\n", ret); + break; default: ret = dev->rregs[saddr]; break; } - esp_log("Read reg %02x = %02x\n", saddr, ret); + esp_log("%04X:%08X: Read ESP reg%02x=%02x\n", CS, cpu_state.pc, saddr, ret); return ret; } @@ -1385,6 +1485,11 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) break; case ESP_CMD: dev->rregs[ESP_CMD] = val; + if (!esp_cmd_is_valid(dev, dev->rregs[ESP_CMD])) { + dev->rregs[ESP_RSTAT] |= INTR_IL; + esp_raise_irq(dev); + break; + } if (val & CMD_DMA) { dev->dma = 1; @@ -1419,19 +1524,21 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_pci_soft_reset(dev); break; case CMD_BUSRESET: - for (uint8_t i = 0; i < 16; i++) + esp_log("ESP Bus Reset val=%02x.\n", (dev->rregs[ESP_CFG1] & CFG1_RESREPT)); + for (uint8_t i = 0; i < 16; i++) { scsi_device_reset(&scsi_devices[dev->bus][i]); - - if (!(dev->wregs[ESP_CFG1] & CFG1_RESREPT)) { + } + if (!(dev->rregs[ESP_CFG1] & CFG1_RESREPT)) { dev->rregs[ESP_RINTR] |= INTR_RST; esp_log("ESP Bus Reset with IRQ\n"); esp_raise_irq(dev); } break; case CMD_TI: - esp_log("Transfer Information val = %02X\n", val); + esp_log("Transfer Information val=%02X\n", val); break; case CMD_ICCS: + esp_log("ESP SCSI ICCS\n"); esp_write_response(dev); dev->rregs[ESP_RINTR] |= INTR_FC; dev->rregs[ESP_RSTAT] |= STAT_MI; @@ -1446,8 +1553,8 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) handle_satn_stop(dev); break; case CMD_MSGACC: + dev->asc_mode = ESP_ASC_MODE_DIS; dev->rregs[ESP_RINTR] |= INTR_DC; - dev->rregs[ESP_RSEQ] = 0; dev->rregs[ESP_RFLAGS] = 0; esp_log("ESP SCSI MSGACC IRQ\n"); esp_raise_irq(dev); @@ -1463,7 +1570,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) break; case CMD_ENSEL: dev->rregs[ESP_RINTR] = 0; - esp_log("ESP Enable Selection, do cmd = %d\n", dev->do_cmd); + esp_log("ESP Enable Selection.\n"); break; case CMD_DISSEL: dev->rregs[ESP_RINTR] = 0; @@ -1483,7 +1590,13 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) case ESP_WSYNO: break; case ESP_CFG1: + dev->rregs[ESP_CFG1] = val; + esp_log("ESP CFG1=%02x.\n", val); + break; case ESP_CFG2: + dev->rregs[ESP_CFG2] = val & ~0x8f; + esp_log("ESP CFG2=%02x.\n", dev->rregs[ESP_CFG2]); + break; case ESP_CFG3: case ESP_RES3: case ESP_RES4: @@ -1502,9 +1615,12 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) static void esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir) { - uint32_t sg_pos = 0; uint32_t addr; int expected_dir; + int sg_pos = 0; + uint32_t DMALen; + uint32_t DMAPtr; + uint32_t WAC = 0; if (dev->dma_regs[DMA_CMD] & DMA_CMD_DIR) expected_dir = READ_FROM_DEVICE; @@ -1516,39 +1632,55 @@ esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir) return; } - if (dev->dma_regs[DMA_CMD] & DMA_CMD_MDL) { - if (dev->dma_regs[DMA_STC]) { - if (dev->dma_regs[DMA_WBC] > len) - dev->dma_regs[DMA_WBC] = len; + if (dev->dma_regs[DMA_WBC] < len) + len = dev->dma_regs[DMA_WBC]; + + if (dev->dma_regs[DMA_CMD] & DMA_CMD_MDL) { + if (len) { + dma_bm_read(dev->dma_regs[DMA_WMAC], (uint8_t *)&DMAPtr, 4, 4); + dev->dma_regs[DMA_WAC] = DMAPtr | dev->dma_regs[DMA_SPA]; + DMALen = len; + WAC = dev->dma_regs[DMA_SPA]; + for (uint32_t i = 0; i < len; i += 4) { + if (WAC == 0) { + dma_bm_read(dev->dma_regs[DMA_WMAC], (uint8_t *)&DMAPtr, 4, 4); + dev->dma_regs[DMA_WAC] = DMAPtr; + } - esp_log("WAC MDL=%08x, STC=%d, ID=%d.\n", dev->dma_regs[DMA_WAC] | (dev->dma_regs[DMA_WMAC] & 0xff000), dev->dma_regs[DMA_STC], dev->id); - for (uint32_t i = 0; i < len; i++) { addr = dev->dma_regs[DMA_WAC]; - if (expected_dir) - dma_bm_write(addr | (dev->dma_regs[DMA_WMAC] & 0xff000), &buf[sg_pos], len, 4); - else - dma_bm_read(addr | (dev->dma_regs[DMA_WMAC] & 0xff000), &buf[sg_pos], len, 4); + esp_log("Data Buffer %s: length %d (%u), pointer 0x%04X\n", + expected_dir ? "read" : "write", len, len, addr); - sg_pos++; - dev->dma_regs[DMA_WBC]--; - dev->dma_regs[DMA_WAC]++; - - if (dev->dma_regs[DMA_WAC] & 0x1000) { - dev->dma_regs[DMA_WAC] = 0; - dev->dma_regs[DMA_WMAC] += 0x1000; + if (addr && DMALen) { + if (expected_dir) + dma_bm_write(addr, &buf[sg_pos], DMALen, 4); + else + dma_bm_read(addr, &buf[sg_pos], DMALen, 4); } + sg_pos += 4; + DMALen -= 4; + + /* update status registers */ + dev->dma_regs[DMA_WBC] -= 4; + dev->dma_regs[DMA_WAC] += 4; + WAC += 4; + if (WAC >= 0x1000) { + WAC = 0; + dev->dma_regs[DMA_WMAC] += 4; + } + + if (DMALen < 0) + DMALen = 0; + if (dev->dma_regs[DMA_WBC] <= 0) { dev->dma_regs[DMA_WBC] = 0; - dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE; + break; } } } } else { - if (dev->dma_regs[DMA_WBC] < len) - len = dev->dma_regs[DMA_WBC]; - addr = dev->dma_regs[DMA_WAC]; if (expected_dir) @@ -1559,9 +1691,12 @@ esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir) /* update status registers */ dev->dma_regs[DMA_WBC] -= len; dev->dma_regs[DMA_WAC] += len; + } - if (dev->dma_regs[DMA_WBC] == 0) - dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE; + esp_log("Finished count=%d.\n", dev->dma_regs[DMA_WBC]); + if (dev->dma_regs[DMA_WBC] == 0) { + esp_log("DMA transfer finished.\n"); + dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE; } } @@ -1574,13 +1709,13 @@ esp_pci_dma_read(esp_t *dev, uint16_t saddr) if (saddr == DMA_STAT) { if (!(dev->sbac & SBAC_STATUS)) { - dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_ERROR | DMA_STAT_ABORT | DMA_STAT_DONE); + dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_PWDN | DMA_STAT_ERROR | DMA_STAT_ABORT | DMA_STAT_DONE); esp_log("ESP PCI DMA Read done cleared\n"); esp_pci_update_irq(dev); } } - esp_log("ESP PCI DMA Read regs addr = %04x, temp = %06x\n", saddr, ret); + esp_log("ESP PCI DMA Read regs addr=%04x, ret=%06x, STAT=%02x\n", saddr, ret, dev->dma_regs[DMA_STAT]); return ret; } @@ -1595,8 +1730,8 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val) esp_log("ESP PCI DMA Write CMD = %02x\n", val & DMA_CMD_MASK); switch (val & DMA_CMD_MASK) { case 0: /*IDLE*/ + esp_log("IDLE/NOP\n"); esp_dma_enable(dev, 0); - esp_log("PCI DMA disable\n"); break; case 1: /*BLAST*/ dev->dma_regs[DMA_STAT] |= DMA_STAT_BCMBLT; @@ -1605,12 +1740,12 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val) scsi_device_command_stop(&scsi_devices[dev->bus][dev->id]); break; case 3: /*START*/ + dev->dma_regs[DMA_WBC] = dev->dma_regs[DMA_STC]; dev->dma_regs[DMA_WAC] = dev->dma_regs[DMA_SPA]; - dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA] & 0xfffffffc; - if (!dev->dma_regs[DMA_STC]) - dev->dma_regs[DMA_STC] = 0x1000000; - dev->dma_regs[DMA_WBC] = dev->dma_regs[DMA_STC]; + if (val & DMA_CMD_MDL) + dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA] & 0xfffffffc; + dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT | DMA_STAT_DONE | DMA_STAT_ABORT | DMA_STAT_ERROR | DMA_STAT_PWDN); esp_dma_enable(dev, 1); esp_log("PCI DMA enable, MDL bit=%02x, SPA=%08x, SMDLA=%08x, STC=%d, ID=%d, SCSICMD=%02x.\n", val & DMA_CMD_MDL, dev->dma_regs[DMA_SPA], dev->dma_regs[DMA_SMDLA], dev->dma_regs[DMA_STC], dev->id, dev->cmdfifo.data[1]); @@ -1685,7 +1820,7 @@ esp_io_pci_read(esp_t *dev, uint32_t addr, unsigned int size) } else if (addr == 0x70) { /* DMA SCSI Bus and control */ ret = dev->sbac; - esp_log("ESP PCI SBAC read = %02x\n", ret); + esp_log("ESP PCI SBAC read=%08x\n", ret); } else { /* Invalid region */ ret = 0; @@ -1695,7 +1830,11 @@ esp_io_pci_read(esp_t *dev, uint32_t addr, unsigned int size) ret >>= (addr & 3) * 8; ret &= ~(~(uint64_t) 0 << (8 * size)); - esp_log("ESP PCI I/O read: addr = %02x, val = %02x\n", addr, ret); + if (addr == 0x70) + esp_log("%04X:%08X: SBAC PCI I/O read: addr=%02x, val=%02x\n", CS, cpu_state.pc, addr, ret); + else + esp_log("%04X:%08X: ESP PCI I/O read: addr=%02x, val=%02x\n", CS, cpu_state.pc, addr, ret); + return ret; } @@ -1740,6 +1879,7 @@ esp_io_pci_write(esp_t *dev, uint32_t addr, uint32_t val, unsigned int size) esp_pci_dma_write(dev, (addr - 0x40) >> 2, val); } else if (addr == 0x70) { /* DMA SCSI Bus and control */ + esp_log("ESP PCI SBAC write=%08x\n", val); dev->sbac = val; } } @@ -2015,7 +2155,7 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) { esp_t *dev = (esp_t *) priv; - // esp_log("ESP PCI: Reading register %02X\n", addr & 0xff); + esp_log("ESP PCI: Reading register %02X\n", addr & 0xff); switch (addr) { case 0x00: @@ -2051,6 +2191,8 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) return 0; /*devubclass*/ case 0x0B: return 1; /*Class code*/ + case 0x0C: + return esp_pci_regs[0x0c]; case 0x0E: return 0; /*Header type */ case 0x10: @@ -2081,9 +2223,11 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) return dev->irq; case 0x3D: return PCI_INTA; - + case 0x3E: + return 0x04; + case 0x3F: + return 0x28; case 0x40 ... 0x4f: - esp_log("ESP PCI: Read value %02X to register %02X, ID=%d\n", esp_pci_regs[addr], addr, dev->id); return esp_pci_regs[addr]; default: @@ -2101,7 +2245,7 @@ esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) int eesk; int eedi; - // esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); + esp_log("%04X:%08X: ESP PCI: Write value %02X to register %02X\n", CS, cpu_state.pc, val, addr); if (!dev->local) { if ((addr >= 0x80) && (addr <= 0xFF)) { @@ -2142,6 +2286,10 @@ esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) esp_pci_regs[addr] &= ~(val & 0xf9); break; + case 0x0c: + esp_pci_regs[addr] = val; + break; + case 0x10: case 0x11: case 0x12: @@ -2192,7 +2340,6 @@ esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) return; case 0x40 ... 0x4f: - esp_log("ESP PCI: Write value %02X to register %02X, ID=%i.\n", val, addr, dev->id); esp_pci_regs[addr] = val; return; @@ -2201,10 +2348,31 @@ esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) } } +static void +esp_pci_reset(void *priv) +{ + esp_t *dev = (esp_t *) priv; + + timer_disable(&dev->timer); + + reset_state.bios.mapping = dev->bios.mapping; + + reset_state.timer = dev->timer; + + reset_state.pci_slot = dev->pci_slot; + + memcpy(dev, &reset_state, sizeof(esp_t)); + + dev->sbac = 1 << 19; +} + static void * -dc390_init(UNUSED(const device_t *info)) +dc390_init(const device_t *info) { esp_t *dev = calloc(1, sizeof(esp_t)); + const char *bios_rev = NULL; + uint32_t mask = 0; + uint32_t size = 0x8000; dev->bus = scsi_get_bus(); @@ -2224,11 +2392,18 @@ dc390_init(UNUSED(const device_t *info)) dev->has_bios = device_get_config_int("bios"); if (dev->has_bios) { - dev->BIOSBase = 0xd0000; + dev->BIOSBase = 0xc8000; if (dev->local) { - ;//rom_init(&dev->bios, AM53C974_ROM, 0xd0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + bios_rev = (char *) device_get_config_bios("bios_rev"); + dev->bios_path = (char *) device_get_bios_file(info, bios_rev, 0); + if (!strcmp(bios_rev, "v3_43")) + mask = 0x4000; + else if (!strcmp(bios_rev, "v3_01_amd")) + size = 0x4000; + + rom_init(&dev->bios, dev->bios_path, dev->BIOSBase, size, size - 1, mask, MEM_MAPPING_EXTERNAL); } else - rom_init(&dev->bios, DC390_ROM, 0xd0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&dev->bios, DC390_ROM, dev->BIOSBase, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); } /* Enable our BIOS space in PCI, if needed. */ @@ -2248,13 +2423,16 @@ dc390_init(UNUSED(const device_t *info)) } esp_pci_hard_reset(dev); - for (uint8_t i = 0; i < 16; i++) + for (uint8_t i = 0; i < 16; i++) { scsi_device_reset(&scsi_devices[dev->bus][i]); + } timer_add(&dev->timer, esp_callback, dev, 0); scsi_bus_set_speed(dev->bus, 10000000.0); + memcpy(&reset_state, dev, sizeof(esp_t)); + return dev; } @@ -2436,7 +2614,7 @@ ncr53c9x_mca_init(const device_t *info) timer_add(&dev->timer, esp_callback, dev, 0); - scsi_bus_set_speed(dev->bus, 5000000.0); + scsi_bus_set_speed(dev->bus, 10000000.0); return dev; } @@ -2472,6 +2650,80 @@ static const device_config_t bios_enable_config[] = { // clang-format on }; +static const device_config_t am53c974a_bios_enable_config[] = { + // clang-format off + { + .name = "bios_rev", + .description = "BIOS Revision", + .type = CONFIG_BIOS, + .default_string = "v3_01_amd", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "Version 3.01 (AMD)", + .internal_name = "v3_01_amd", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 16384, + .files = { AM53C974_3_01_AMD_ROM, "" } + }, + { + .name = "Version 3.43 (Dawicontrol)", + .internal_name = "v3_43", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { AM53C974_3_43_ROM, "" } + }, + { + .name = "Version 4.00 (Dawicontrol)", + .internal_name = "v4_00", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { AM53C974_4_00_ROM, "" } + }, + { + .name = "Version 5.00 (Dawicontrol)", + .internal_name = "v5_00", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { AM53C974_5_00_ROM, "" } + }, + { + .name = "Version 5.11 (Dawicontrol)", + .internal_name = "v5_11", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { AM53C974_5_11_ROM, "" } + }, + { .files_no = 0 } + }, + }, + { + .name = "bios", + .description = "Enable BIOS", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + const device_t dc390_pci_device = { .name = "Tekram DC-390 PCI", .internal_name = "dc390", @@ -2479,7 +2731,7 @@ const device_t dc390_pci_device = { .local = 0, .init = dc390_init, .close = esp_close, - .reset = NULL, + .reset = esp_pci_reset, .available = NULL, .speed_changed = NULL, .force_redraw = NULL, @@ -2493,11 +2745,11 @@ const device_t am53c974_pci_device = { .local = 1, .init = dc390_init, .close = esp_close, - .reset = NULL, + .reset = esp_pci_reset, .available = NULL, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL + .config = am53c974a_bios_enable_config }; const device_t ncr53c90a_mca_device = { diff --git a/src/scsi/scsi_spock.c b/src/scsi/scsi_spock.c index 6f0b7aacb..0bb2d70ba 100644 --- a/src/scsi/scsi_spock.c +++ b/src/scsi/scsi_spock.c @@ -130,6 +130,7 @@ typedef struct { int adapter_id; int assign; int present[8]; + int id_connected; int cmd_status; int cir_status; @@ -448,7 +449,6 @@ static void spock_process_imm_cmd(spock_t *scsi) { int i; - int j = 0; int adapter_id; int phys_id; int lun_id; @@ -467,14 +467,23 @@ spock_process_imm_cmd(spock_t *scsi) if (scsi->command & (1 << 23)) { spock_log("Assign: adapter id=%d\n", adapter_id); scsi->dev_id[adapter_id].phys_id = -1; + scsi->id_connected = 0; spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); } else { if (phys_id != scsi->adapter_id) { scsi->dev_id[adapter_id].phys_id = phys_id; scsi->dev_id[adapter_id].lun_id = lun_id; - spock_log("Assign: adapter dev=%x scsi ID=%i LUN=%i.\n", adapter_id, scsi->dev_id[adapter_id].phys_id, scsi->dev_id[adapter_id].lun_id); + if (scsi_device_present(&scsi_devices[scsi->bus][phys_id])) { + scsi->present[scsi->id_connected] = 1; + if (lun_id == 0) + scsi->id_connected++; + } else + scsi->present[scsi->id_connected] = 0; + + spock_log("Assign: adapter dev=%d, scsi ID=%i, LUN=%i, attention devsel=%d, present=%d, connected=%d.\n", adapter_id, scsi->dev_id[adapter_id].phys_id, scsi->dev_id[adapter_id].lun_id, scsi->attention & 0x0f, scsi->present[scsi->id_connected], scsi->id_connected); spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); } else { /*Can not assign adapter*/ + scsi->id_connected = 0; spock_log("Assign: PUN=%d, cannot assign adapter.\n", phys_id); spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL); } @@ -495,35 +504,15 @@ spock_process_imm_cmd(spock_t *scsi) spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); break; case CMD_RESET: + scsi->id_connected = 0; spock_log("Reset command, attention=%02x.\n", scsi->attention & 0x0f); if ((scsi->attention & 0x0f) == 0x0f) { /*Adapter reset*/ for (i = 0; i < 8; i++) scsi_device_reset(&scsi_devices[scsi->bus][i]); - for (i = 6; i > -1; i--) { - if (scsi_device_present(&scsi_devices[scsi->bus][i])) { - spock_log("Adapter Reset, SCSI reset present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[i].phys_id, scsi_devices[scsi->bus][i].type); - scsi->present[j] = i; - j++; - } else { - scsi->present[j] = 0xff; - spock_log("Adapter Reset, SCSI reset not present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[i].phys_id, scsi_devices[scsi->bus][i].type); - } - } - } else if ((scsi->attention & 0x0f) < 7) { /*Device reset*/ + } else if ((scsi->attention & 0x0f) < 7) /*Device reset*/ scsi_device_reset(&scsi_devices[scsi->bus][scsi->attention & 0x0f]); - for (i = 6; i > -1; i--) { - if (scsi_device_present(&scsi_devices[scsi->bus][i])) { - spock_log("Device Reset, SCSI reset present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[i].phys_id, scsi_devices[scsi->bus][i].type); - scsi->present[j] = i; - j++; - } else { - scsi->present[j] = 0xff; - spock_log("Device Reset, SCSI reset not present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[i].phys_id, scsi_devices[scsi->bus][i].type); - } - } - } scsi->scb_state = 0; spock_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); break; @@ -538,7 +527,6 @@ static void spock_execute_cmd(spock_t *scsi, scb_t *scb) { int c; - int j = 0; int old_scb_state; if (scsi->in_reset) { @@ -556,17 +544,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) scsi->dev_id[c].phys_id = -1; scsi->in_reset = 0; - - for (c = 6; c >= 0; c--) { - if (scsi_device_present(&scsi_devices[scsi->bus][c])) { - spock_log("Reset, SCSI reset present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[c].phys_id, scsi_devices[scsi->bus][c].type); - scsi->present[j] = c; - j++; - } else { - scsi->present[j] = 0xff; - spock_log("Reset, SCSI reset not present devices=%d, phys ID=%d, type=%04x.\n", j, scsi->dev_id[c].phys_id, scsi_devices[scsi->bus][c].type); - } - } + spock_log("Reset.\n"); return; } @@ -698,12 +676,15 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) break; case CMD_DEVICE_INQUIRY: - if (scsi->present[scsi->scb_id] != 0xff) + if (scsi->scb_id != 15) { + if (scsi->present[scsi->scb_id]) + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + else + scsi->cdb_id = 0xff; + } else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - else - scsi->cdb_id = 0xff; - spock_log("Device Inquiry, ID=%d\n", scsi->cdb_id); + spock_log("Device Inquiry, ID=%d, connected=%d, present=%d.\n", scsi->cdb_id, scsi->id_connected, scsi->present[scsi->scb_id + 1]); scsi->cdb[0] = GPCMD_INQUIRY; scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ scsi->cdb[2] = 0; /*Page code*/ @@ -718,13 +699,16 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) return; case CMD_SEND_OTHER_SCSI: - if (scsi->present[scsi->scb_id] != 0xff) + if (scsi->scb_id != 15) { + if (scsi->present[scsi->scb_id]) + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + else + scsi->cdb_id = 0xff; + } else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - else - scsi->cdb_id = 0xff; dma_bm_read(scsi->scb_addr + 0x18, scsi->cdb, 12, 2); - spock_log("Send Other SCSI, SCB ID=%d, PHYS ID=%d, CDB[0]=%02x, CDB_ID=%d, ID Present=%d.\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->cdb[0], scsi->cdb_id, scsi->present[scsi->scb_id]); + spock_log("Send Other SCSI, SCB ID=%d, PHYS ID=%d, LUN=%d, CDB[0]=%02x, CDB_ID=%d, ID Present=%d.\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->dev_id[scsi->scb_id].lun_id, scsi->cdb[0], scsi->cdb_id, scsi->present[scsi->scb_id + 1]); 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; @@ -732,10 +716,13 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) return; case CMD_READ_DEVICE_CAPACITY: - if (scsi->present[scsi->scb_id] != 0xff) + if (scsi->scb_id != 15) { + if (scsi->present[scsi->scb_id]) + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + else + scsi->cdb_id = 0xff; + } else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - else - scsi->cdb_id = 0xff; spock_log("Device Capacity, SCB ID=%d, PHYS ID=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id); scsi->cdb[0] = GPCMD_READ_CDROM_CAPACITY; @@ -754,10 +741,13 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) return; case CMD_READ_DATA: - if (scsi->present[scsi->scb_id] != 0xff) + if (scsi->scb_id != 15) { + if (scsi->present[scsi->scb_id]) + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + else + scsi->cdb_id = 0xff; + } else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - else - scsi->cdb_id = 0xff; spock_log("Device Read Data, SCB ID=%d, PHYS ID=%d\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id); scsi->cdb[0] = GPCMD_READ_10; @@ -776,10 +766,13 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) return; case CMD_WRITE_DATA: - if (scsi->present[scsi->scb_id] != 0xff) + if (scsi->scb_id != 15) { + if (scsi->present[scsi->scb_id]) + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + else + scsi->cdb_id = 0xff; + } else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - else - scsi->cdb_id = 0xff; spock_log("Device Write Data\n"); scsi->cdb[0] = GPCMD_WRITE_10; @@ -798,10 +791,13 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) return; case CMD_VERIFY: - if (scsi->present[scsi->scb_id] != 0xff) + if (scsi->scb_id != 15) { + if (scsi->present[scsi->scb_id]) + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + else + scsi->cdb_id = 0xff; + } else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - else - scsi->cdb_id = 0xff; spock_log("Device Verify\n"); scsi->cdb[0] = GPCMD_VERIFY_10; @@ -821,10 +817,13 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) return; case CMD_WRITE_VERIFY: - if (scsi->present[scsi->scb_id] != 0xff) + if (scsi->scb_id != 15) { + if (scsi->present[scsi->scb_id]) + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + else + scsi->cdb_id = 0xff; + } else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - else - scsi->cdb_id = 0xff; spock_log("Device Write with Verify\n"); scsi->cdb[0] = GPCMD_WRITE_AND_VERIFY_10; @@ -843,10 +842,13 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) return; case CMD_REQUEST_SENSE: - if (scsi->present[scsi->scb_id] != 0xff) + if (scsi->scb_id != 15) { + if (scsi->present[scsi->scb_id]) + scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; + else + scsi->cdb_id = 0xff; + } else scsi->cdb_id = scsi->dev_id[scsi->scb_id].phys_id; - else - scsi->cdb_id = 0xff; spock_log("Device Request Sense, ID=%d\n", scsi->cdb_id); scsi->cdb[0] = GPCMD_REQUEST_SENSE; @@ -870,7 +872,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) if (scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id]) && (scsi->cdb_id != 0xff)) { if (scsi->last_status == SCSI_STATUS_OK) { scsi->scb_state = 3; - spock_log("Status is Good on device ID %d, cdb id = %d.\n", scsi->scb_id, scsi->cdb_id); + spock_log("Status is Good on device ID %d, cdb id = %d, devsel = %d.\n", scsi->scb_id, scsi->cdb_id, scsi->attention & 0x0f); } else if (scsi->last_status == SCSI_STATUS_CHECK_CONDITION) { uint16_t term_stat_block_addr7 = (0xc << 8) | 2; uint16_t term_stat_block_addr8 = 0x20; @@ -905,7 +907,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) } else { spock_set_irq(scsi, scsi->scb_id, IRQ_TYPE_SCB_COMPLETE); scsi->scb_state = 0; - spock_log("Complete SCB ID = %d.\n", scsi->attention & 0x0f); + spock_log("Complete SCB ID = %d.\n", scsi->scb_id); } break; @@ -1084,10 +1086,10 @@ spock_callback(void *priv) case 4: case 0x0f: /*Start SCB*/ scsi->cmd_status = 1; - scsi->scb_addr = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); - scsi->scb_id = scsi->attention & 0x0f; + scsi->scb_addr = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); + scsi->scb_id = scsi->attention & 0x0f; scsi->cmd_timer = SPOCK_TIME * 2; - spock_log("Start SCB at ID = %d, attention = %02x\n", scsi->scb_id, scsi->attention >> 4); + spock_log("Start SCB at ID = %d, attention = %02x, cdb_id = %d\n", scsi->scb_id, scsi->attention >> 4, scsi->cdb_id); scsi->scb_state = 1; break; @@ -1182,6 +1184,7 @@ spock_reset(void *priv) scsi->in_invalid = 0; scsi->attention_wait = 0; scsi->basic_ctrl = 0; + scsi->id_connected = 0; spock_log("Actual Reset.\n"); } diff --git a/src/scsi/scsi_t128.c b/src/scsi/scsi_t128.c index 94166054c..e2f963900 100644 --- a/src/scsi/scsi_t128.c +++ b/src/scsi/scsi_t128.c @@ -241,9 +241,14 @@ t128_callback(void *priv) uint8_t c; uint8_t temp; uint8_t status; + double period = scsi_bus->period / 60.0; - if (scsi_bus->tx_mode != PIO_TX_BUS) - timer_on_auto(&t128->timer, scsi_bus->period / 60.0); + if (scsi_bus->tx_mode != PIO_TX_BUS) { + if (period >= 10.0) + timer_on_auto(&t128->timer, period); + else + timer_on_auto(&t128->timer, 10.0); + } if (scsi_bus->data_wait & 1) { scsi_bus->clear_req = 3; @@ -287,7 +292,6 @@ t128_callback(void *priv) t128->status &= ~0x02; t128->pos = 0; t128->host_pos = 0; - scsi_bus->data_repeat = 0; t128_log("T128 Remaining blocks to be written=%d\n", t128->block_count); if (scsi_bus->data_pos >= dev->buffer_length) { t128->block_loaded = 0; @@ -336,7 +340,6 @@ t128_callback(void *priv) t128->status &= ~0x02; t128->pos = 0; t128->host_pos = 0; - scsi_bus->data_repeat = 0; t128_log("T128 blocks read=%d, total len=%d\n", scsi_bus->data_pos, dev->buffer_length); if (scsi_bus->data_pos >= dev->buffer_length) { scsi_bus->bus_out |= BUS_REQ; @@ -545,7 +548,7 @@ t128_available(void) static const device_config_t t128_config[] = { { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xD8000, diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt index 6106871bc..dd4106fbd 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -18,6 +18,7 @@ add_library(sio OBJECT sio_acc3221.c sio_ali5123.c + sio_f82c606.c sio_f82c710.c sio_82091aa.c sio_fdc37c6xx.c diff --git a/src/sio/sio_82091aa.c b/src/sio/sio_82091aa.c index d3cd5017a..5ef60d20f 100644 --- a/src/sio/sio_82091aa.c +++ b/src/sio/sio_82091aa.c @@ -42,6 +42,7 @@ typedef struct i82091aa_t { uint16_t base_address; fdc_t *fdc; serial_t *uart[2]; + lpt_t *lpt; } i82091aa_t; static void @@ -53,11 +54,11 @@ fdc_handler(i82091aa_t *dev) } static void -lpt1_handler(i82091aa_t *dev) +lpt_handler(i82091aa_t *dev) { uint16_t lpt_port = LPT1_ADDR; - lpt1_remove(); + lpt_port_remove(dev->lpt); switch ((dev->regs[0x20] >> 1) & 0x03) { case 0x00: @@ -78,9 +79,9 @@ lpt1_handler(i82091aa_t *dev) } if ((dev->regs[0x20] & 0x01) && lpt_port) - lpt1_setup(lpt_port); + lpt_port_setup(dev->lpt, lpt_port); - lpt1_irq((dev->regs[0x20] & 0x08) ? LPT1_IRQ : LPT2_IRQ); + lpt_port_irq(dev->lpt, (dev->regs[0x20] & 0x08) ? LPT1_IRQ : LPT2_IRQ); } static void @@ -176,7 +177,7 @@ i82091aa_write(uint16_t port, uint8_t val, void *priv) case 0x20: *reg = (val & 0xef); if (valxor & 0x07) - lpt1_handler(dev); + lpt_handler(dev); break; case 0x21: *reg = (val & 0x2f); @@ -236,7 +237,7 @@ i82091aa_reset(i82091aa_t *dev) fdc_reset(dev->fdc); fdc_handler(dev); - lpt1_handler(dev); + lpt_handler(dev); serial_handler(dev, 0); serial_handler(dev, 1); serial_set_clock_src(dev->uart[0], (24000000.0 / 13.0)); @@ -264,6 +265,8 @@ i82091aa_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->lpt = device_add_inst(&lpt_port_device, 1); + dev->has_ide = (info->local >> 9) & 0x03; i82091aa_reset(dev); @@ -295,6 +298,20 @@ const device_t i82091aa_device = { .config = NULL }; +const device_t i82091aa_26e_device = { + .name = "Intel 82091AA Super I/O (Port 26Eh)", + .internal_name = "i82091aa_26e", + .flags = 0, + .local = 0x140, + .init = i82091aa_init, + .close = i82091aa_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t i82091aa_398_device = { .name = "Intel 82091AA Super I/O (Port 398h)", .internal_name = "i82091aa_398", diff --git a/src/sio/sio_acc3221.c b/src/sio/sio_acc3221.c index 203b1c1f1..c9cb8b6cf 100644 --- a/src/sio/sio_acc3221.c +++ b/src/sio/sio_acc3221.c @@ -38,6 +38,7 @@ typedef struct acc3221_t { uint8_t regs[256]; fdc_t *fdc; serial_t *uart[2]; + lpt_t *lpt; } acc3221_t; /* Configuration Register Index, BE (R/W): @@ -302,10 +303,10 @@ typedef struct acc3221_t { static void acc3221_lpt_handle(acc3221_t *dev) { - lpt1_remove(); + lpt_port_remove(dev->lpt); if (!(dev->regs[0xbe] & REG_BE_LPT1_DISABLE)) - lpt1_setup(dev->regs[0xbf] << 2); + lpt_port_setup(dev->lpt, dev->regs[0xbf] << 2); } static void @@ -436,9 +437,10 @@ acc3221_reset(acc3221_t *dev) serial_remove(dev->uart[1]); serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); - lpt1_remove(); - lpt1_setup(LPT1_ADDR); - lpt1_irq(LPT1_IRQ); + lpt_port_remove(dev->lpt); + lpt_port_setup(dev->lpt, LPT1_ADDR); + + lpt_port_irq(dev->lpt, LPT1_IRQ); fdc_reset(dev->fdc); } @@ -461,6 +463,8 @@ acc3221_init(UNUSED(const device_t *info)) dev->uart[0] = device_add_inst(&ns16450_device, 1); dev->uart[1] = device_add_inst(&ns16450_device, 2); + dev->lpt = device_add_inst(&lpt_port_device, 1); + io_sethandler(0x00f2, 0x0002, acc3221_read, NULL, NULL, acc3221_write, NULL, NULL, dev); acc3221_reset(dev); diff --git a/src/sio/sio_ali5123.c b/src/sio/sio_ali5123.c index 398d00839..71c074ea8 100644 --- a/src/sio/sio_ali5123.c +++ b/src/sio/sio_ali5123.c @@ -47,6 +47,7 @@ typedef struct ali5123_t { int cur_reg; fdc_t *fdc; serial_t *uart[3]; + lpt_t *lpt; } ali5123_t; static void ali5123_write(uint16_t port, uint8_t val, void *priv); @@ -81,21 +82,61 @@ ali5123_fdc_handler(ali5123_t *dev) static void ali5123_lpt_handler(ali5123_t *dev) { - uint16_t ld_port = 0; + uint16_t ld_port = 0x0000; + uint16_t mask = 0xfffc; uint8_t global_enable = !(dev->regs[0x22] & (1 << 3)); uint8_t local_enable = !!dev->ld_regs[3][0x30]; uint8_t lpt_irq = dev->ld_regs[3][0x70]; + uint8_t lpt_dma = dev->ld_regs[3][0x74]; + uint8_t lpt_mode = dev->ld_regs[3][0xf0] & 0x07; if (lpt_irq > 15) lpt_irq = 0xff; - lpt1_remove(); - if (global_enable && local_enable) { - ld_port = make_port(dev, 3) & 0xFFFC; - if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC)) - lpt1_setup(ld_port); + if (lpt_dma >= 4) + lpt_dma = 0xff; + + lpt_port_remove(dev->lpt); + lpt_set_fifo_threshold(dev->lpt, (dev->ld_regs[3][0xf0] & 0x78) >> 3); + if ((lpt_mode == 0x04) && (dev->ld_regs[3][0xf1] & 0x80)) + lpt_mode = 0x00; + switch (lpt_mode) { + default: + case 0x04: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x00: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 1); + break; + case 0x01: case 0x05: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x02: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + case 0x03: case 0x07: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; } - lpt1_irq(lpt_irq); + if (global_enable && local_enable) { + ld_port = (make_port(dev, 3) & 0xfffc) & mask; + if ((ld_port >= 0x0100) && (ld_port <= (0x0ffc & mask))) + lpt_port_setup(dev->lpt, ld_port); + } + lpt_port_irq(dev->lpt, lpt_irq); + lpt_port_dma(dev->lpt, lpt_dma); } static void @@ -247,7 +288,7 @@ ali5123_write(uint16_t port, uint8_t val, void *priv) dev->regs[dev->cur_reg] = val; } else { valxor = val ^ dev->ld_regs[cur_ld][dev->cur_reg]; - if (((dev->cur_reg & 0xf0) == 0x70) && (cur_ld < 4)) + if (((dev->cur_reg & 0xf0) == 0x70) && (cur_ld < 4) && (cur_ld != 3)) return; /* Block writes to some logical devices. */ if (cur_ld > 0x0c) @@ -357,6 +398,9 @@ ali5123_write(uint16_t port, uint8_t val, void *priv) case 0x60: case 0x61: case 0x70: + case 0x74: + case 0xf0: + case 0xf1: if ((dev->cur_reg == 0x30) && (val & 0x01)) dev->regs[0x22] &= ~0x08; if (valxor) @@ -472,6 +516,7 @@ ali5123_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); dev->uart[2] = device_add_inst(&ns16550_device, 3); + dev->lpt = device_add_inst(&lpt_port_device, 1); dev->chip_id = info->local & 0xff; @@ -480,7 +525,7 @@ ali5123_init(const device_t *info) io_sethandler(FDC_PRIMARY_ADDR, 0x0002, ali5123_read, NULL, NULL, ali5123_write, NULL, NULL, dev); - device_add(&keyboard_ps2_ali_pci_device); + device_add(&kbc_ps2_ali_pci_device); return dev; } diff --git a/src/sio/sio_detect.c b/src/sio/sio_detect.c index ffa0ec9d0..d36522fe0 100644 --- a/src/sio/sio_detect.c +++ b/src/sio/sio_detect.c @@ -47,11 +47,12 @@ sio_detect_write(uint16_t port, uint8_t val, void *priv) static uint8_t sio_detect_read(uint16_t port, void *priv) { - const sio_detect_t *dev = (sio_detect_t *) priv; + /*const sio_detect_t *dev = (sio_detect_t *) priv*/; + uint8_t ret = 0xff /*dev->regs[port & 1]*/; - pclog("sio_detect_read : port=%04x = %02X\n", port, dev->regs[port & 1]); + pclog("sio_detect_read : port=%04x = %02X\n", port, ret); - return 0xff /*dev->regs[port & 1]*/; + return ret; } static void diff --git a/src/sio/sio_f82c606.c b/src/sio/sio_f82c606.c new file mode 100644 index 000000000..1e6eacccc --- /dev/null +++ b/src/sio/sio_f82c606.c @@ -0,0 +1,329 @@ +/* + * 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 Chips & Technologies 82C606 CHIPSpak + * Multifunction Controller. + * + * Relevant literature: + * + * [1] Chips and Technologies, Inc., + * 82C605/82C606 CHIPSpak/CHIPSport MULTIFUNCTION CONTROLLERS, + * PRELIMINARY Data Sheet, Revision 1, May 1987. + * + * + * Authors: Eluan Costa Miranda, + * Lubomir Rintel, + * Miran Grca, + * + * Copyright 2020-2025 Eluan Costa Miranda. + * Copyright 2021-2025 Lubomir Rintel. + * Copyright 2025 Miran Grca. + */ +#include +#include +#include +#include +#include +#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/gameport.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/nvr.h> +#include <86box/sio.h> +#include <86box/machine.h> + +typedef struct upc_t { + int configuration_state; /* state of algorithm to enter configuration mode */ + int configuration_mode; + uint16_t cri_addr; /* cri = configuration index register, addr is even */ + uint16_t cap_addr; /* cap = configuration access port, addr is odd and is cri_addr + 1 */ + uint8_t cri; /* currently indexed register */ + uint8_t last_write; + + /* these regs are not affected by reset */ + uint8_t regs[15]; /* there are 16 indexes, but there is no need to store the last one which is: R = cri_addr / 4, W = exit config mode */ + nvr_t *nvr; + void *gameport; + serial_t *uart[2]; + lpt_t *lpt; +} upc_t; + +#ifdef ENABLE_F82C606_LOG +int f82c606_do_log = ENABLE_F82C606_LOG; + +static void +f82c606_log(const char *fmt, ...) +{ + va_list ap; + + if (f82c606_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define f82c606_log(fmt, ...) +#endif + +static void +f82c606_update_ports(upc_t *dev, int set) +{ + uint8_t uart1_int = 0xff; + uint8_t uart2_int = 0xff; + uint8_t lpt_int = 0xff; + int nvr_int = -1; + + serial_remove(dev->uart[0]); + serial_remove(dev->uart[1]); + lpt_port_remove(dev->lpt); + + nvr_at_handler(0, ((uint16_t) dev->regs[3]) << 2, dev->nvr); + nvr_at_handler(0, 0x70, dev->nvr); + + gameport_remap(dev->gameport, 0); + + if (!set) + return; + + switch (dev->regs[8] & 0xc0) { + case 0x40: + nvr_int = 3; + break; + case 0x80: + uart1_int = COM2_IRQ; + break; + case 0xc0: + uart2_int = COM2_IRQ; + break; + + default: + break; + } + + switch (dev->regs[8] & 0x30) { + case 0x10: + nvr_int = 4; + break; + case 0x20: + uart1_int = COM1_IRQ; + break; + case 0x30: + uart2_int = COM1_IRQ; + break; + + default: + break; + } + + switch (dev->regs[8] & 0x0c) { + case 0x04: + nvr_int = 5; + break; + case 0x08: + uart1_int = 5; + break; + case 0x0c: + lpt_int = LPT2_IRQ; + break; + + default: + break; + } + + switch (dev->regs[8] & 0x03) { + case 0x01: + nvr_int = 7; + break; + case 0x02: + uart2_int = 7; + break; + case 0x03: + lpt_int = LPT1_IRQ; + break; + + default: + break; + } + + if (dev->regs[0] & 1) { + gameport_remap(dev->gameport, ((uint16_t) dev->regs[7]) << 2); + f82c606_log("Game port at %04X\n", ((uint16_t) dev->regs[7]) << 2); + } + + if (dev->regs[0] & 2) { + serial_setup(dev->uart[0], ((uint16_t) dev->regs[4]) << 2, uart1_int); + f82c606_log("UART 1 at %04X, IRQ %i\n", ((uint16_t) dev->regs[4]) << 2, uart1_int); + } + + if (dev->regs[0] & 4) { + serial_setup(dev->uart[1], ((uint16_t) dev->regs[5]) << 2, uart2_int); + f82c606_log("UART 2 at %04X, IRQ %i\n", ((uint16_t) dev->regs[5]) << 2, uart2_int); + } + + if (dev->regs[0] & 8) { + lpt_port_setup(dev->lpt, ((uint16_t) dev->regs[6]) << 2); + lpt_port_irq(dev->lpt, lpt_int); + f82c606_log("LPT1 at %04X, IRQ %i\n", ((uint16_t) dev->regs[6]) << 2, lpt_int); + } + + nvr_at_handler(1, ((uint16_t) dev->regs[3]) << 2, dev->nvr); + nvr_irq_set(nvr_int, dev->nvr); + f82c606_log("RTC at %04X, IRQ %i\n", ((uint16_t) dev->regs[3]) << 2, nvr_int); +} + +static uint8_t +f82c606_config_read(uint16_t port, void *priv) +{ + const upc_t *dev = (upc_t *) priv; + uint8_t temp = 0xff; + + if (dev->configuration_mode) { + if (port == dev->cri_addr) { + temp = dev->cri; + } else if (port == dev->cap_addr) { + if (dev->cri == 0xf) + temp = dev->cri_addr / 4; + else + temp = dev->regs[dev->cri]; + } + } + + return temp; +} + +static void +f82c606_config_write(uint16_t port, uint8_t val, void *priv) +{ + upc_t *dev = (upc_t *) priv; + int configuration_state_event = 0; + + switch (port) { + case 0x2fa: + if ((dev->configuration_state == 0) && (val != 0x00) && (val != 0xff)) { + configuration_state_event = 1; + dev->last_write = val; + } else if (dev->configuration_state == 4) { + if ((val | dev->last_write) == 0xff) { + dev->cri_addr = ((uint16_t) dev->last_write) << 2; + dev->cap_addr = dev->cri_addr + 1; + dev->configuration_mode = 1; + f82c606_update_ports(dev, 0); + /* TODO: is the value of cri reset here or when exiting configuration mode? */ + io_sethandler(dev->cri_addr, 0x0002, + f82c606_config_read, NULL, NULL, + f82c606_config_write, NULL, NULL, dev); + } else + dev->configuration_mode = 0; + } + break; + case 0x3fa: + if ((dev->configuration_state == 1) && ((val | dev->last_write) == 0xff)) + configuration_state_event = 1; + else if ((dev->configuration_state == 2) && (val == 0x36)) + configuration_state_event = 1; + else if (dev->configuration_state == 3) { + dev->last_write = val; + configuration_state_event = 1; + } + break; + default: + break; + } + + if (dev->configuration_mode) { + if (port == dev->cri_addr) { + dev->cri = val & 0xf; + } else if (port == dev->cap_addr) { + if (dev->cri == 0xf) { + dev->configuration_mode = 0; + io_removehandler(dev->cri_addr, 0x0002, + f82c606_config_read, NULL, NULL, + f82c606_config_write, NULL, NULL, dev); + /* TODO: any benefit in updating at each register write instead of when exiting config mode? */ + f82c606_update_ports(dev, 1); + } else + dev->regs[dev->cri] = val; + } + } + + /* TODO: is the state only reset when accessing 0x2fa and 0x3fa wrongly? */ + if ((port == 0x2fa || port == 0x3fa) && configuration_state_event) + dev->configuration_state++; + else + dev->configuration_state = 0; +} + +static void +f82c606_reset(void *priv) +{ + upc_t *dev = (upc_t *) priv; + + /* Set power-on defaults. */ + dev->regs[0] = 0x00; /* Enable */ + dev->regs[1] = 0x00; /* Configuration Register */ + dev->regs[2] = 0x00; /* Ext Baud Rate Select */ + dev->regs[3] = 0xb0; /* RTC Base */ + dev->regs[4] = 0xfe; /* UART1 Base */ + dev->regs[5] = 0xbe; /* UART2 Base */ + dev->regs[6] = 0x9e; /* Parallel Base */ + dev->regs[7] = 0x80; /* Game Base */ + dev->regs[8] = 0xec; /* Interrupt Select */ + + f82c606_update_ports(dev, 1); +} + +static void +f82c606_close(void *priv) +{ + upc_t *dev = (upc_t *) priv; + + free(dev); +} + +static void * +f82c606_init(const device_t *info) +{ + upc_t *dev = (upc_t *) calloc(1, sizeof(upc_t)); + + dev->nvr = device_add(&at_nvr_old_device); + dev->gameport = gameport_add(&gameport_sio_device); + + dev->uart[0] = device_add_inst(&ns16450_device, 1); + dev->uart[1] = device_add_inst(&ns16450_device, 2); + + dev->lpt = device_add_inst(&lpt_port_device, 1); + + io_sethandler(0x02fa, 0x0001, NULL, NULL, NULL, f82c606_config_write, NULL, NULL, dev); + io_sethandler(0x03fa, 0x0001, NULL, NULL, NULL, f82c606_config_write, NULL, NULL, dev); + + f82c606_reset(dev); + + return dev; +} + +const device_t f82c606_device = { + .name = "82C606 CHIPSpak Multifunction Controller", + .internal_name = "f82c606", + .flags = 0, + .local = 0, + .init = f82c606_init, + .close = f82c606_close, + .reset = f82c606_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sio/sio_f82c710.c b/src/sio/sio_f82c710.c index a7aa101c6..0e9cb0d9b 100644 --- a/src/sio/sio_f82c710.c +++ b/src/sio/sio_f82c710.c @@ -6,23 +6,23 @@ * * This file is part of the 86Box distribution. * - * Implementation of the Chips & Technologies F82C710 Universal Peripheral - * Controller (UPC) and 82C606 CHIPSpak Multifunction Controller. + * Implementation of the Chips & Technologies F82C710 Universal + * Peripheral Controller (UPC). * * Relevant literature: * * [1] Chips and Technologies, Inc., - * 82C605/82C606 CHIPSpak/CHIPSport MULTIFUNCTION CONTROLLERS, - * PRELIMINARY Data Sheet, Revision 1, May 1987. - * + * 82710 Univeral Peripheral Controller, Data Sheet, + * PRELIMINARY, August 1990. + * * + * Authors: Eluan Costa Miranda, + * Lubomir Rintel, + * Miran Grca, * - * - * Authors: Eluan Costa Miranda - * Lubomir Rintel - * - * Copyright 2020 Eluan Costa Miranda. - * Copyright 2021 Lubomir Rintel. + * Copyright 2020-2025 Eluan Costa Miranda. + * Copyright 2021-2025 Lubomir Rintel. + * Copyright 2025 Miran Grca. */ #include #include @@ -40,24 +40,38 @@ #include <86box/hdc_ide.h> #include <86box/fdd.h> #include <86box/fdc.h> -#include <86box/nvr.h> +#include <86box/machine.h> +#include <86box/mouse.h> +#include <86box/plat_fallthrough.h> #include <86box/sio.h> +#include "cpu.h" typedef struct upc_t { - uint32_t local; - int configuration_state; /* state of algorithm to enter configuration mode */ + int configuration_state; /* State of algorithm to enter the + configuration mode. */ int configuration_mode; - uint16_t cri_addr; /* cri = configuration index register, addr is even */ - uint16_t cap_addr; /* cap = configuration access port, addr is odd and is cri_addr + 1 */ - uint8_t cri; /* currently indexed register */ + uint8_t next_value; + uint16_t cri_addr; /* CRI = Configuration Index Register, + addr is even. */ + uint16_t cap_addr; /* CAP = Configuration Access Port, addr is + odd and is cri_addr + 1. */ + uint8_t cri; /* Currently indexed register. */ uint8_t last_write; + uint16_t mouse_base; - /* these regs are not affected by reset */ - uint8_t regs[15]; /* there are 16 indexes, but there is no need to store the last one which is: R = cri_addr / 4, W = exit config mode */ + /* These regs are not affected by reset */ + uint8_t regs[15]; /* There are 16 indexes, but there is no + need to store the last one which is: + R = cri_addr / 4, W = exit config mode. */ + int serial_irq; + int lpt_irq; + int xta; fdc_t *fdc; - nvr_t *nvr; void *gameport; - serial_t *uart[2]; + void *mouse; + void *hdc_xta; + serial_t *uart; + lpt_t *lpt; } upc_t; #ifdef ENABLE_F82C710_LOG @@ -79,150 +93,86 @@ f82c710_log(const char *fmt, ...) #endif static void -f82c710_update_ports(upc_t *dev, int set) +serial_handler(upc_t *dev) { - uint16_t com_addr = 0; - uint16_t lpt_addr = 0; + uint16_t com_addr = 0x0000; - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); - lpt1_remove(); - lpt2_remove(); - fdc_remove(dev->fdc); - ide_pri_disable(); + serial_remove(dev->uart); - if (!set) - return; + if (dev->regs[0x00] & 0x04) { + com_addr = dev->regs[0x04] << 2; - if (dev->regs[0] & 4) { - com_addr = dev->regs[4] * 4; - if (com_addr == COM1_ADDR) - serial_setup(dev->uart[0], com_addr, COM1_IRQ); - else if (com_addr == COM2_ADDR) - serial_setup(dev->uart[1], com_addr, COM2_IRQ); + serial_setup(dev->uart, com_addr, dev->serial_irq); } - - if (dev->regs[0] & 8) { - lpt_addr = dev->regs[6] * 4; - lpt1_setup(lpt_addr); - if ((lpt_addr == LPT1_ADDR) || (lpt_addr == LPT_MDA_ADDR)) - lpt1_irq(LPT1_IRQ); - else if (lpt_addr == LPT2_ADDR) - lpt1_irq(LPT2_IRQ); - } - - if (dev->regs[12] & 0x80) - ide_pri_enable(); - - if (dev->regs[12] & 0x20) - fdc_set_base(dev->fdc, FDC_PRIMARY_ADDR); } static void -f82c606_update_ports(upc_t *dev, int set) +lpt_handler(upc_t *dev) { - uint8_t uart1_int = 0xff; - uint8_t uart2_int = 0xff; - uint8_t lpt1_int = 0xff; - int nvr_int = -1; + uint16_t lpt_addr = 0x0000; - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); - lpt1_remove(); - lpt2_remove(); + lpt_port_remove(dev->lpt); - nvr_at_handler(0, ((uint16_t) dev->regs[3]) << 2, dev->nvr); - nvr_at_handler(0, 0x70, dev->nvr); + if (dev->regs[0x00] & 0x08) { + lpt_addr = dev->regs[0x06] << 2; - gameport_remap(dev->gameport, 0); + lpt_port_setup(dev->lpt, lpt_addr); + lpt_port_irq(dev->lpt, dev->lpt_irq); - if (!set) - return; - - switch (dev->regs[8] & 0xc0) { - case 0x40: - nvr_int = 3; - break; - case 0x80: - uart1_int = COM2_IRQ; - break; - case 0xc0: - uart2_int = COM2_IRQ; - break; - - default: - break; + lpt_set_ext(dev->lpt, !!(dev->regs[0x01] & 0x40)); } +} - switch (dev->regs[8] & 0x30) { - case 0x10: - nvr_int = 4; - break; - case 0x20: - uart1_int = COM1_IRQ; - break; - case 0x30: - uart2_int = COM1_IRQ; - break; +static void +ide_handler(upc_t *dev) +{ + if (dev->xta) { + if (dev->hdc_xta != NULL) + xta_handler(dev->hdc_xta, 0); + } else + ide_pri_disable(); - default: - break; + if (dev->regs[0x0c] & 0x80) { + if (dev->regs[0x0c] & 0x40) { + if (dev->xta && (dev->hdc_xta != NULL)) + xta_handler(dev->hdc_xta, 1); + } else { + if (!dev->xta) + ide_pri_enable(); + } } +} - switch (dev->regs[8] & 0x0c) { - case 0x04: - nvr_int = 5; - break; - case 0x08: - uart1_int = 5; - break; - case 0x0c: - lpt1_int = LPT2_IRQ; - break; +static void +fdc_handler(upc_t *dev) +{ + fdc_remove(dev->fdc); - default: - break; - } + if (dev->regs[0x0c] & 0x20) + fdc_set_base(dev->fdc, FDC_PRIMARY_ADDR); - switch (dev->regs[8] & 0x03) { - case 0x01: - nvr_int = 7; - break; - case 0x02: - uart2_int = 7; - break; - case 0x03: - lpt1_int = LPT1_IRQ; - break; + fdc_set_power_down(dev->fdc, !!(dev->regs[0x0c] & 0x10)); +} - default: - break; - } +static void +mouse_handler(upc_t *dev) +{ + if (dev->mouse_base != 0x0000) + mouse_upc_handler(0, dev->mouse_base, dev->mouse); - if (dev->regs[0] & 1) { - gameport_remap(dev->gameport, ((uint16_t) dev->regs[7]) << 2); - f82c710_log("Game port at %04X\n", ((uint16_t) dev->regs[7]) << 2); - } + dev->mouse_base = dev->regs[0x0d] << 2; - if (dev->regs[0] & 2) { - serial_setup(dev->uart[0], ((uint16_t) dev->regs[4]) << 2, uart1_int); - f82c710_log("UART 1 at %04X, IRQ %i\n", ((uint16_t) dev->regs[4]) << 2, uart1_int); - } + if (dev->mouse_base != 0x0000) + mouse_upc_handler(1, dev->mouse_base, dev->mouse); +} - if (dev->regs[0] & 4) { - serial_setup(dev->uart[1], ((uint16_t) dev->regs[5]) << 2, uart2_int); - f82c710_log("UART 2 at %04X, IRQ %i\n", ((uint16_t) dev->regs[5]) << 2, uart2_int); - } - - if (dev->regs[0] & 8) { - lpt1_setup(((uint16_t) dev->regs[6]) << 2); - lpt1_irq(lpt1_int); - f82c710_log("LPT1 at %04X, IRQ %i\n", ((uint16_t) dev->regs[6]) << 2, lpt1_int); - } - - nvr_at_handler(1, ((uint16_t) dev->regs[3]) << 2, dev->nvr); - nvr_irq_set(nvr_int, dev->nvr); - f82c710_log("RTC at %04X, IRQ %i\n", ((uint16_t) dev->regs[3]) << 2, nvr_int); +static void +f82c710_update_ports(upc_t *dev) +{ + serial_handler(dev); + lpt_handler(dev); + ide_handler(dev); + fdc_handler(dev); } static uint8_t @@ -235,9 +185,9 @@ f82c710_config_read(uint16_t port, void *priv) if (port == dev->cri_addr) { temp = dev->cri; } else if (port == dev->cap_addr) { - if (dev->cri == 0xf) - temp = dev->cri_addr / 4; - else + if (dev->cri == 0x0f) + temp = dev->cri_addr >> 2; + else if (dev->cri < 0x0f) temp = dev->regs[dev->cri]; } } @@ -248,66 +198,111 @@ f82c710_config_read(uint16_t port, void *priv) static void f82c710_config_write(uint16_t port, uint8_t val, void *priv) { - upc_t *dev = (upc_t *) priv; - int configuration_state_event = 0; + upc_t * dev = (upc_t *) priv; + uint8_t valxor = 0x00; + int configuration_state_event = 0; switch (port) { + default: + break; case 0x2fa: - if ((dev->configuration_state == 0) && (val != 0x00) && (val != 0xff) && (dev->local == 606)) { + if (dev->configuration_state == 0) { configuration_state_event = 1; - dev->last_write = val; - } else if ((dev->configuration_state == 0) && (val == 0x55) && (dev->local == 710)) - configuration_state_event = 1; - else if (dev->configuration_state == 4) { - if ((val | dev->last_write) == 0xff) { - dev->cri_addr = ((uint16_t) dev->last_write) << 2; - dev->cap_addr = dev->cri_addr + 1; + dev->next_value = 0xff - val; + } else if (dev->configuration_state == 4) { + uint8_t addr_verify = dev->cri_addr >> 2; + addr_verify += val; + if (addr_verify == 0xff) { dev->configuration_mode = 1; - if (dev->local == 606) - f82c606_update_ports(dev, 0); - else if (dev->local == 710) - f82c710_update_ports(dev, 0); /* TODO: is the value of cri reset here or when exiting configuration mode? */ - io_sethandler(dev->cri_addr, 0x0002, f82c710_config_read, NULL, NULL, f82c710_config_write, NULL, NULL, dev); + io_sethandler(dev->cri_addr, 0x0002, + f82c710_config_read, NULL, NULL, + f82c710_config_write, NULL, NULL, dev); } else dev->configuration_mode = 0; } break; case 0x3fa: - if ((dev->configuration_state == 1) && ((val | dev->last_write) == 0xff) && (dev->local == 606)) - configuration_state_event = 1; - else if ((dev->configuration_state == 1) && (val == 0xaa) && (dev->local == 710)) + if ((dev->configuration_state == 1) && (val == dev->next_value)) configuration_state_event = 1; else if ((dev->configuration_state == 2) && (val == 0x36)) configuration_state_event = 1; else if (dev->configuration_state == 3) { - dev->last_write = val; + dev->cri_addr = val << 2; + dev->cap_addr = dev->cri_addr + 1; configuration_state_event = 1; } break; - default: - break; } if (dev->configuration_mode) { - if (port == dev->cri_addr) { + if (port == dev->cri_addr) dev->cri = val & 0xf; - } else if (port == dev->cap_addr) { - if (dev->cri == 0xf) { - dev->configuration_mode = 0; - io_removehandler(dev->cri_addr, 0x0002, f82c710_config_read, NULL, NULL, f82c710_config_write, NULL, NULL, dev); - /* TODO: any benefit in updating at each register write instead of when exiting config mode? */ - if (dev->local == 606) - f82c606_update_ports(dev, 1); - else if (dev->local == 710) - f82c710_update_ports(dev, 1); - } else - dev->regs[dev->cri] = val; + else if (port == dev->cap_addr) { + valxor = (dev->regs[dev->cri] ^ val); + switch (dev->cri) { + case 0x00: + dev->regs[dev->cri] = (dev->regs[dev->cri] & 0x10) | (val & 0xef); + if (valxor & 0x08) + lpt_handler(dev); + if (valxor & 0x04) + serial_handler(dev); + break; + case 0x01: + dev->regs[dev->cri] = (dev->regs[dev->cri] & 0x07) | (val & 0xf8); + if (valxor & 0x40) + serial_handler(dev); + break; + case 0x02: + dev->regs[dev->cri] = (dev->regs[dev->cri] & 0x08) | (val & 0xf0); + break; + case 0x03: + case 0x07: case 0x08: + /* TODO: Reserved - is it actually writable? */ + fallthrough; + case 0x09: case 0x0a: + case 0x0b: + dev->regs[dev->cri] = val; + break; + case 0x04: + dev->regs[dev->cri] = (dev->regs[dev->cri] & 0x01) | (val & 0xfe); + if (valxor & 0xfe) + serial_handler(dev); + break; + case 0x06: + dev->regs[dev->cri] = val; + if (valxor) + lpt_handler(dev); + break; + case 0x0c: + dev->regs[dev->cri] = val; + if (valxor & 0xc0) + ide_handler(dev); + if (valxor & 0x30) + fdc_handler(dev); + break; + case 0x0d: + dev->regs[dev->cri] = val; + if (valxor) + mouse_handler(dev); + break; + case 0x0e: + dev->regs[dev->cri] = (dev->regs[dev->cri] & 0x20) | (val & 0xdf); + if (valxor) + mouse_handler(dev); + break; + case 0x0f: + dev->configuration_mode = 0; + io_removehandler(dev->cri_addr, 0x0002, + f82c710_config_read, NULL, NULL, + f82c710_config_write, NULL, NULL, dev); + break; + } } } /* TODO: is the state only reset when accessing 0x2fa and 0x3fa wrongly? */ - if ((port == 0x2fa || port == 0x3fa) && configuration_state_event) + if (((port == 0x2fa) || (port == 0x3fa)) && configuration_state_event) dev->configuration_state++; else dev->configuration_state = 0; @@ -318,39 +313,27 @@ f82c710_reset(void *priv) { upc_t *dev = (upc_t *) priv; - /* Set power-on defaults. */ - if (dev->local == 606) { - dev->regs[0] = 0x00; /* Enable */ - dev->regs[1] = 0x00; /* Configuration Register */ - dev->regs[2] = 0x00; /* Ext Baud Rate Select */ - dev->regs[3] = 0xb0; /* RTC Base */ - dev->regs[4] = 0xfe; /* UART1 Base */ - dev->regs[5] = 0xbe; /* UART2 Base */ - dev->regs[6] = 0x9e; /* Parallel Base */ - dev->regs[7] = 0x80; /* Game Base */ - dev->regs[8] = 0xec; /* Interrupt Select */ - } else if (dev->local == 710) { - dev->regs[0] = 0x0c; - dev->regs[1] = 0x00; - dev->regs[2] = 0x00; - dev->regs[3] = 0x00; - dev->regs[4] = 0xfe; - dev->regs[5] = 0x00; - dev->regs[6] = 0x9e; - dev->regs[7] = 0x00; - dev->regs[8] = 0x00; - dev->regs[9] = 0xb0; - dev->regs[10] = 0x00; - dev->regs[11] = 0x00; - dev->regs[12] = 0xa0; - dev->regs[13] = 0x00; - dev->regs[14] = 0x00; - } + dev->configuration_state = 0; + dev->configuration_mode = 0; - if (dev->local == 606) - f82c606_update_ports(dev, 1); - else if (dev->local == 710) - f82c710_update_ports(dev, 1); + /* Set power-on defaults. */ + dev->regs[0x00] = 0x0c; + dev->regs[0x01] = 0x00; + dev->regs[0x02] = 0x00; + dev->regs[0x03] = 0x00; + dev->regs[0x04] = 0xfe; + dev->regs[0x05] = 0x00; + dev->regs[0x06] = 0x9e; + dev->regs[0x07] = 0x00; + dev->regs[0x08] = 0x00; + dev->regs[0x09] = 0xb0; + dev->regs[0x0a] = 0x00; + dev->regs[0x0b] = 0x00; + dev->regs[0x0c] = 0xa0; + dev->regs[0x0d] = 0x00; + dev->regs[0x0e] = 0x00; + + f82c710_update_ports(dev); } static void @@ -365,16 +348,19 @@ static void * f82c710_init(const device_t *info) { upc_t *dev = (upc_t *) calloc(1, sizeof(upc_t)); - dev->local = info->local; - if (dev->local == 606) { - dev->nvr = device_add(&at_nvr_old_device); - dev->gameport = gameport_add(&gameport_sio_device); - } else if (dev->local == 710) - dev->fdc = device_add(&fdc_at_device); + if (strstr(machine_get_internal_name(), "5086") != NULL) + dev->fdc = device_add(&fdc_at_actlow_device); + else + dev->fdc = device_add(&fdc_at_device); - dev->uart[0] = device_add_inst(&ns16450_device, 1); - dev->uart[1] = device_add_inst(&ns16450_device, 2); + dev->uart = device_add_inst(&ns16450_device, 1); + dev->lpt = device_add_inst(&lpt_port_device, 1); + + dev->mouse = device_add_params(&mouse_upc_device, (void *) (uintptr_t) (is8086 ? 2 : 12)); + + dev->serial_irq = device_get_config_int("serial_irq"); + dev->lpt_irq = device_get_config_int("lpt_irq"); io_sethandler(0x02fa, 0x0001, NULL, NULL, NULL, f82c710_config_write, NULL, NULL, dev); io_sethandler(0x03fa, 0x0001, NULL, NULL, NULL, f82c710_config_write, NULL, NULL, dev); @@ -384,30 +370,126 @@ f82c710_init(const device_t *info) return dev; } -const device_t f82c606_device = { - .name = "82C606 CHIPSpak Multifunction Controller", - .internal_name = "f82c606", - .flags = 0, - .local = 606, - .init = f82c710_init, - .close = f82c710_close, - .reset = f82c710_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL +static void * +f82c710_pc5086_init(const device_t *info) +{ + upc_t *dev = f82c710_init(info); + + int hdc_present = device_get_config_int("hdc_present"); + + if (hdc_present) + dev->hdc_xta = device_add(&xta_st50x_pc5086_device); + + dev->xta = 1; + + f82c710_reset(dev); + + return dev; +} + +static const device_config_t f82c710_config[] = { + { + .name = "serial_irq", + .description = "Serial port IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "lpt_irq", + .description = "Parallel port IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 7, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 7", .value = 7 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t f82c710_pc5086_config[] = { + { + .name = "serial_irq", + .description = "Serial port IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "lpt_irq", + .description = "Parallel port IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 7, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 7", .value = 7 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "hdc_present", + .description = "Hard disk", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } }; const device_t f82c710_device = { .name = "F82C710 UPC Super I/O", .internal_name = "f82c710", .flags = 0, - .local = 710, + .local = 0, .init = f82c710_init, .close = f82c710_close, .reset = f82c710_reset, .available = NULL, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL + .config = f82c710_config +}; + +const device_t f82c710_pc5086_device = { + .name = "F82C710 UPC Super I/O (PC5086)", + .internal_name = "f82c710_pc5086", + .flags = 0, + .local = 0, + .init = f82c710_pc5086_init, + .close = f82c710_close, + .reset = f82c710_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = f82c710_pc5086_config }; diff --git a/src/sio/sio_fdc37c669.c b/src/sio/sio_fdc37c669.c index 3be28c6ba..0f563afa0 100644 --- a/src/sio/sio_fdc37c669.c +++ b/src/sio/sio_fdc37c669.c @@ -42,6 +42,7 @@ typedef struct fdc37c669_t { int rw_locked; int cur_reg; fdc_t *fdc; + lpt_t *lpt; serial_t *uart[2]; } fdc37c669_t; @@ -105,9 +106,9 @@ fdc37c669_lpt_handler(fdc37c669_t *dev) { uint8_t mask = ~(dev->regs[0x04] & 0x01); - lpt_port_remove(dev->id); + lpt_port_remove(dev->lpt); if ((dev->regs[0x01] & 0x04) && (dev->regs[0x23] >= 0x40)) - lpt_port_setup(dev->id, ((uint16_t) (dev->regs[0x23] & mask)) << 2); + lpt_port_setup(dev->lpt, ((uint16_t) (dev->regs[0x23] & mask)) << 2); } static void @@ -251,7 +252,7 @@ fdc37c669_write(uint16_t port, uint8_t val, void *priv) if (valxor & 0xf0) fdc_set_irq(dev->fdc, val >> 4); if (valxor & 0x0f) - lpt_port_irq(dev->id, val & 0x0f); + lpt_port_irq(dev->lpt, val & 0x0f); break; case 0x28: dev->regs[dev->cur_reg] = val; @@ -345,6 +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); + dev->lpt = device_add_inst(&lpt_port_device, next_id + 1); + 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); diff --git a/src/sio/sio_fdc37c67x.c b/src/sio/sio_fdc37c67x.c index 931734048..c9d0bd149 100644 --- a/src/sio/sio_fdc37c67x.c +++ b/src/sio/sio_fdc37c67x.c @@ -6,16 +6,15 @@ * * This file is part of the 86Box distribution. * - * Implementation of the SMC FDC37C67X Super I/O Chip. - * - * + * Implementation of the SMC FDC37C67x Super I/O Chips. * * Authors: Miran Grca, * - * Copyright 2016-2018 Miran Grca. + * Copyright 2025 Miran Grca. */ -#include +#include #include +#include #include #include #include @@ -23,65 +22,69 @@ #include <86box/io.h> #include <86box/timer.h> #include <86box/device.h> -#include <86box/pic.h> #include <86box/pci.h> +#include <86box/pic.h> #include <86box/lpt.h> #include <86box/serial.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/fdd.h> #include <86box/fdc.h> -#include "cpu.h" -#include <86box/sio.h> +#include <86box/keyboard.h> +#include <86box/machine.h> +#include <86box/apm.h> +#include <86box/plat.h> #include <86box/plat_unused.h> - -#define AB_RST 0x80 +#include <86box/video.h> +#include <86box/sio.h> +#include "cpu.h" typedef struct fdc37c67x_t { - uint8_t chip_id; - uint8_t is_apm; - uint8_t tries; - uint8_t gpio_regs[2]; - uint8_t auxio_reg; - uint8_t regs[48]; - uint8_t ld_regs[11][256]; - uint16_t gpio_base; /* Set to EA */ - uint16_t auxio_base; - uint16_t sio_base; - int locked; - int cur_reg; - fdc_t *fdc; - serial_t *uart[2]; + uint8_t is_compaq; + uint8_t max_ld; + uint8_t tries; + uint8_t port_370; + uint8_t gpio_reg; + uint8_t regs[48]; + uint8_t ld_regs[11][256]; + uint16_t kbc_type; + uint16_t superio_base; + uint16_t fdc_base; + uint16_t lpt_base; + uint16_t kbc_base; + uint16_t gpio_base; /* Set to EA */ + uint16_t uart_base[2]; + int locked; + int cur_reg; + fdc_t *fdc; + void *kbc; + serial_t *uart[2]; + lpt_t *lpt; } fdc37c67x_t; static void fdc37c67x_write(uint16_t port, uint8_t val, void *priv); static uint8_t fdc37c67x_read(uint16_t port, void *priv); static uint16_t -make_port(fdc37c67x_t *dev, uint8_t ld) +make_port_superio(const fdc37c67x_t *dev) { - uint16_t r0 = dev->ld_regs[ld][0x60]; - uint16_t r1 = dev->ld_regs[ld][0x61]; + const uint16_t r0 = dev->regs[0x26]; + const uint16_t r1 = dev->regs[0x27]; - uint16_t p = (r0 << 8) + r1; + const uint16_t p = (r1 << 8) + r0; return p; } -static uint8_t -fdc37c67x_auxio_read(UNUSED(uint16_t port), void *priv) +static uint16_t +make_port(const fdc37c67x_t *dev, const uint8_t ld) { - const fdc37c67x_t *dev = (fdc37c67x_t *) priv; + const uint16_t r0 = dev->ld_regs[ld][0x60]; + const uint16_t r1 = dev->ld_regs[ld][0x61]; - return dev->auxio_reg; -} + const uint16_t p = (r0 << 8) + r1; -static void -fdc37c67x_auxio_write(UNUSED(uint16_t port), uint8_t val, void *priv) -{ - fdc37c67x_t *dev = (fdc37c67x_t *) priv; - - dev->auxio_reg = val; + return p; } static uint8_t @@ -90,7 +93,18 @@ fdc37c67x_gpio_read(uint16_t port, void *priv) const fdc37c67x_t *dev = (fdc37c67x_t *) priv; uint8_t ret = 0xff; - ret = dev->gpio_regs[port & 1]; + if (dev->locked) { + if (dev->is_compaq) + ret = fdc37c67x_read(port & 0x0001, priv); + } else if (port & 0x0001) switch (dev->gpio_reg) { + case 0x03: + ret = dev->ld_regs[0x08][0xf4]; + break; + case 0x0c ... 0x0f: + ret = dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08]; + break; + } else + ret = dev->gpio_reg; return ret; } @@ -100,377 +114,498 @@ fdc37c67x_gpio_write(uint16_t port, uint8_t val, void *priv) { fdc37c67x_t *dev = (fdc37c67x_t *) priv; - if (!(port & 1)) - dev->gpio_regs[0] = (dev->gpio_regs[0] & 0xfc) | (val & 0x03); + if (dev->locked) { + if (dev->is_compaq) + fdc37c67x_write(port & 0x0001, val, priv); + } else if (port & 0x0001) switch (dev->gpio_reg) { + case 0x03: + dev->ld_regs[0x08][0xf4] = val & 0xef; + break; + case 0x0c: case 0x0e: + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val & 0x9e; + break; + case 0x0d: + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val & 0xd7; + break; + case 0x0f: + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val & 0x17; + break; + } else + dev->gpio_reg = val; +} + +static void +fdc37c67x_superio_handler(fdc37c67x_t *dev) +{ + if (!dev->is_compaq) { + if (dev->superio_base != 0x0000) + io_removehandler(dev->superio_base, 0x0002, + fdc37c67x_read, NULL, NULL, fdc37c67x_write, NULL, NULL, dev); + dev->superio_base = make_port_superio(dev); + if (dev->superio_base != 0x0000) + io_sethandler(dev->superio_base, 0x0002, + fdc37c67x_read, NULL, NULL, fdc37c67x_write, NULL, NULL, dev); + } } static void fdc37c67x_fdc_handler(fdc37c67x_t *dev) { - uint16_t ld_port = 0; - uint8_t global_enable = !!(dev->regs[0x22] & (1 << 0)); - uint8_t local_enable = !!dev->ld_regs[0][0x30]; + const uint8_t global_enable = !!(dev->regs[0x22] & (1 << 0)); + const uint8_t local_enable = !!dev->ld_regs[0][0x30]; + const uint16_t old_base = dev->fdc_base; - fdc_remove(dev->fdc); - if (global_enable && local_enable) { - ld_port = make_port(dev, 0) & 0xFFF8; - if ((ld_port >= 0x0100) && (ld_port <= 0x0FF8)) - fdc_set_base(dev->fdc, ld_port); + dev->fdc_base = 0x0000; + + if (global_enable && local_enable) + dev->fdc_base = make_port(dev, 0) & 0xfff8; + + if (dev->fdc_base != old_base) { + if ((old_base >= 0x0100) && (old_base <= 0x0ff8)) + fdc_remove(dev->fdc); + + if ((dev->fdc_base >= 0x0100) && (dev->fdc_base <= 0x0ff8)) + fdc_set_base(dev->fdc, dev->fdc_base); } } static void fdc37c67x_lpt_handler(fdc37c67x_t *dev) { - uint16_t ld_port = 0; + uint16_t ld_port = 0x0000; + uint16_t mask = 0xfffc; uint8_t global_enable = !!(dev->regs[0x22] & (1 << 3)); uint8_t local_enable = !!dev->ld_regs[3][0x30]; uint8_t lpt_irq = dev->ld_regs[3][0x70]; + uint8_t lpt_dma = dev->ld_regs[3][0x74]; + uint8_t lpt_mode = dev->ld_regs[3][0xf0] & 0x07; if (lpt_irq > 15) lpt_irq = 0xff; - lpt1_remove(); + if (lpt_dma >= 4) + lpt_dma = 0xff; + + lpt_port_remove(dev->lpt); + lpt_set_fifo_threshold(dev->lpt, (dev->ld_regs[3][0xf0] & 0x78) >> 3); + switch (lpt_mode) { + default: + case 0x04: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x00: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 1); + break; + case 0x01: case 0x05: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x02: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + case 0x03: case 0x07: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + } if (global_enable && local_enable) { - ld_port = make_port(dev, 3) & 0xFFFC; - if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC)) - lpt1_setup(ld_port); + ld_port = (make_port(dev, 3) & 0xfffc) & mask; + if ((ld_port >= 0x0100) && (ld_port <= (0x0ffc & mask))) + lpt_port_setup(dev->lpt, ld_port); } - lpt1_irq(lpt_irq); + lpt_port_irq(dev->lpt, lpt_irq); + lpt_port_dma(dev->lpt, lpt_dma); } static void -fdc37c67x_serial_handler(fdc37c67x_t *dev, int uart) +fdc37c67x_serial_handler(fdc37c67x_t *dev, const int uart) { - uint16_t ld_port = 0; - uint8_t uart_no = 4 + uart; - uint8_t global_enable = !!(dev->regs[0x22] & (1 << uart_no)); - uint8_t local_enable = !!dev->ld_regs[uart_no][0x30]; + const uint8_t uart_no = 4 + uart; + const uint8_t global_enable = !!(dev->regs[0x22] & (1 << uart_no)); + const uint8_t local_enable = !!dev->ld_regs[uart_no][0x30]; + const uint16_t old_base = dev->uart_base[uart]; + double clock_src = 24000000.0 / 13.0; - serial_remove(dev->uart[uart]); - if (global_enable && local_enable) { - ld_port = make_port(dev, uart_no) & 0xFFF8; - if ((ld_port >= 0x0100) && (ld_port <= 0x0FF8)) - serial_setup(dev->uart[uart], ld_port, dev->ld_regs[uart_no][0x70]); + dev->uart_base[uart] = 0x0000; + + if (global_enable && local_enable) + dev->uart_base[uart] = make_port(dev, uart_no) & 0xfff8; + + if (dev->uart_base[uart] != old_base) { + if ((old_base >= 0x0100) && (old_base <= 0x0ff8)) + serial_remove(dev->uart[uart]); + + if ((dev->uart_base[uart] >= 0x0100) && (dev->uart_base[uart] <= 0x0ff8)) + serial_setup(dev->uart[uart], dev->uart_base[uart], dev->ld_regs[uart_no][0x70]); } + + switch (dev->ld_regs[uart_no][0xf0] & 0x03) { + case 0x00: + clock_src = 24000000.0 / 13.0; + break; + case 0x01: + clock_src = 24000000.0 / 12.0; + break; + case 0x02: + clock_src = 24000000.0 / 1.0; + break; + case 0x03: + clock_src = 24000000.0 / 1.625; + break; + + default: + break; + } + + serial_set_clock_src(dev->uart[uart], clock_src); + + /* + TODO: If UART 2's own IRQ pin is also enabled when shared, + it should also be asserted. + */ + if (dev->ld_regs[4][0xf0] & 0x80) { + serial_irq(dev->uart[0], dev->ld_regs[4][0x70]); + serial_irq(dev->uart[1], dev->ld_regs[4][0x70]); + } else + serial_irq(dev->uart[uart], dev->ld_regs[uart_no][0x70]); } static void -fdc37c67x_auxio_handler(fdc37c67x_t *dev) +fdc37c67x_kbc_handler(fdc37c67x_t *dev) { - uint16_t ld_port = 0; - uint8_t local_enable = !!dev->ld_regs[8][0x30]; + const uint8_t local_enable = !!dev->ld_regs[7][0x30]; + const uint16_t old_base = dev->kbc_base; - io_removehandler(dev->auxio_base, 0x0001, - fdc37c67x_auxio_read, NULL, NULL, fdc37c67x_auxio_write, NULL, NULL, dev); - if (local_enable) { - dev->auxio_base = ld_port = make_port(dev, 8); - if ((ld_port >= 0x0100) && (ld_port <= 0x0FFF)) - io_sethandler(dev->auxio_base, 0x0001, - fdc37c67x_auxio_read, NULL, NULL, fdc37c67x_auxio_write, NULL, NULL, dev); - } -} + dev->kbc_base = local_enable ? 0x0060 : 0x0000; -static void -fdc37c67x_sio_handler(UNUSED(fdc37c67x_t *dev)) -{ -#if 0 - if (dev->sio_base) { - io_removehandler(dev->sio_base, 0x0002, - fdc37c67x_read, NULL, NULL, fdc37c67x_write, NULL, NULL, dev); - } - dev->sio_base = (((uint16_t) dev->regs[0x27]) << 8) | dev->regs[0x26]; - if (dev->sio_base) { - io_sethandler(dev->sio_base, 0x0002, - fdc37c67x_read, NULL, NULL, fdc37c67x_write, NULL, NULL, dev); - } -#endif + if (dev->kbc_base != old_base) + kbc_at_handler(local_enable, dev->kbc_base, dev->kbc); + + kbc_at_set_irq(0, dev->ld_regs[7][0x70], dev->kbc); + kbc_at_set_irq(1, dev->ld_regs[7][0x72], dev->kbc); } static void fdc37c67x_gpio_handler(fdc37c67x_t *dev) { - uint16_t ld_port = 0; - uint8_t local_enable; + const uint8_t local_enable = !!(dev->regs[0x03] & 0x80) || + (dev->is_compaq && dev->locked); + const uint16_t old_base = dev->gpio_base; - local_enable = !!(dev->regs[0x03] & 0x80); + dev->gpio_base = 0x0000; - io_removehandler(dev->gpio_base, 0x0002, - fdc37c67x_gpio_read, NULL, NULL, fdc37c67x_gpio_write, NULL, NULL, dev); - if (local_enable) { - switch (dev->regs[0x03] & 0x03) { - case 0: - ld_port = 0xe0; - break; - case 1: - ld_port = 0xe2; - break; - case 2: - ld_port = 0xe4; - break; - case 3: - ld_port = 0xea; /* Default */ - break; + if (local_enable) switch (dev->regs[0x03] & 0x03) { + default: + break; + case 0: + dev->gpio_base = 0x00e0; + break; + case 1: + dev->gpio_base = 0x00e2; + break; + case 2: + dev->gpio_base = 0x00e4; + break; + case 3: + dev->gpio_base = 0x00ea; /* Default */ + break; + } - default: - break; - } - dev->gpio_base = ld_port; - if (ld_port > 0x0000) + if (dev->gpio_base != old_base) { + if (old_base != 0x0000) + io_removehandler(old_base, 0x0002, + fdc37c67x_gpio_read, NULL, NULL, fdc37c67x_gpio_write, NULL, NULL, dev); + + if (dev->gpio_base > 0x0000) io_sethandler(dev->gpio_base, 0x0002, fdc37c67x_gpio_read, NULL, NULL, fdc37c67x_gpio_write, NULL, NULL, dev); } } static void -fdc37c67x_smi_handler(fdc37c67x_t *dev) +fdc37c67x_state_change(fdc37c67x_t *dev, const uint8_t locked) { - /* TODO: 8042 P1.2 SMI#. */ - pic_reset_smi_irq_mask(); - pic_set_smi_irq_mask(dev->ld_regs[3][0x70], dev->ld_regs[8][0xb4] & 0x02); - pic_set_smi_irq_mask(dev->ld_regs[5][0x70], dev->ld_regs[8][0xb4] & 0x04); - pic_set_smi_irq_mask(dev->ld_regs[4][0x70], dev->ld_regs[8][0xb4] & 0x08); - pic_set_smi_irq_mask(dev->ld_regs[0][0x70], dev->ld_regs[8][0xb4] & 0x10); - pic_set_smi_irq_mask(12, dev->ld_regs[8][0xb5] & 0x01); - pic_set_smi_irq_mask(1, dev->ld_regs[8][0xb5] & 0x02); - pic_set_smi_irq_mask(10, dev->ld_regs[8][0xb5] & 0x80); + dev->locked = locked; + fdc_3f1_enable(dev->fdc, !locked); } static void fdc37c67x_write(uint16_t port, uint8_t val, void *priv) { fdc37c67x_t *dev = (fdc37c67x_t *) priv; - uint8_t index = (port & 1) ? 0 : 1; - uint8_t valxor = 0x00; - uint8_t keep = 0x00; + uint8_t index = !(port & 1); + uint8_t valxor; - if (index) { - if ((val == 0x55) && !dev->locked) { - if (dev->tries) { - dev->locked = 1; - fdc_3f1_enable(dev->fdc, 0); - dev->tries = 0; - } else - dev->tries++; - } else { - if (dev->locked) { - if (val == 0xaa) { - dev->locked = 0; - fdc_3f1_enable(dev->fdc, 1); - return; - } + if (port == 0x00fb) { + fdc37c67x_state_change(dev, 1); + dev->tries = 0; + } else if (port == 0x00f9) + fdc37c67x_state_change(dev, 0); + else if (index) { + if ((!dev->is_compaq) && (val == 0x55) && !dev->locked) { + fdc37c67x_state_change(dev, 1); + dev->tries = 0; + } else if (dev->locked) { + if ((!dev->is_compaq) && (val == 0xaa)) + fdc37c67x_state_change(dev, 0); + else dev->cur_reg = val; - } else { - if (dev->tries) - dev->tries = 0; - } - } - return; - } else { - if (dev->locked) { - if (dev->cur_reg < 48) { - valxor = val ^ dev->regs[dev->cur_reg]; - if ((val == 0x20) || (val == 0x21)) - return; - dev->regs[dev->cur_reg] = val; - } else { - valxor = val ^ dev->ld_regs[dev->regs[7]][dev->cur_reg]; - if (((dev->cur_reg & 0xF0) == 0x70) && (dev->regs[7] < 4)) - return; - /* Block writes to some logical devices. */ - if (dev->regs[7] > 0x0a) - return; - else - switch (dev->regs[7]) { - case 0x01: - case 0x02: - case 0x07: - return; + } else if ((!dev->is_compaq) && dev->tries) + dev->tries = 0; + } else if (dev->locked) { + if (dev->cur_reg < 0x30) { + valxor = val ^ dev->regs[dev->cur_reg]; - default: + switch (dev->cur_reg) { + case 0x02: + dev->regs[dev->cur_reg] = val; + if (val == 0x02) + fdc37c67x_state_change(dev, 0); + break; + case 0x03: + dev->regs[dev->cur_reg] = val & 0x83; + fdc37c67x_gpio_handler(dev); + break; + case 0x07: case 0x26: + case 0x2b ... 0x2f: + dev->regs[dev->cur_reg] = val; + break; + case 0x22: + dev->regs[dev->cur_reg] = val & 0x39; + + if (valxor & 0x01) + fdc37c67x_fdc_handler(dev); + if (valxor & 0x08) + fdc37c67x_lpt_handler(dev); + if (valxor & 0x10) + fdc37c67x_serial_handler(dev, 0); + if (valxor & 0x20) + fdc37c67x_serial_handler(dev, 1); + break; + case 0x23: + dev->regs[dev->cur_reg] = val & 0x39; + break; + case 0x24: + dev->regs[dev->cur_reg] = val & 0x4e; + break; + case 0x27: + dev->regs[dev->cur_reg] = val; + fdc37c67x_superio_handler(dev); + break; + default: + break; + } + } else { + valxor = val ^ dev->ld_regs[dev->regs[7]][dev->cur_reg]; + + if (dev->regs[7] <= dev->max_ld) switch (dev->regs[7]) { + case 0x00: /* FDD */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + case 0x74: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x01; + if (valxor) + fdc37c67x_fdc_handler(dev); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xef; + + if (valxor & 0x01) + fdc_update_enh_mode(dev->fdc, val & 0x01); + if (valxor & 0x0c) { + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); + switch (val & 0x0c) { + case 0x00: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2); + break; + case 0x04: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA); + break; + } + fdc_update_enh_mode(dev->fdc, val & 0x01); + } + if (valxor & 0x10) + fdc_set_swap(dev->fdc, (val & 0x10) >> 4); + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xfc; + + if (valxor & 0x0c) + fdc_update_densel_force(dev->fdc, (val & 0xc) >> 2); + break; + case 0xf2: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor & 0xc0) + fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); + if (valxor & 0x30) + fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); + if (valxor & 0x0c) + fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); + if (valxor & 0x03) + fdc_update_rwc(dev->fdc, 0, (val & 0x03)); + break; + case 0xf4 ... 0xf7: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x5b; + + if (valxor & 0x18) + fdc_update_drvrate(dev->fdc, dev->cur_reg - 0xf4, + (val & 0x18) >> 3); break; } - dev->ld_regs[dev->regs[7]][dev->cur_reg] = val | keep; + break; + case 0x03: /* Parallel Port */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + case 0x74: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x08; + if (valxor) + fdc37c67x_lpt_handler(dev); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + if (valxor & 0x7f) + fdc37c67x_lpt_handler(dev); + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + break; + } + break; + case 0x04: /* Serial port 1 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x10; + if (valxor) + fdc37c67x_serial_handler(dev, 0); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x83; + + if (valxor & 0x83) { + fdc37c67x_serial_handler(dev, 0); + fdc37c67x_serial_handler(dev, 1); + } + break; + } + break; + case 0x05: /* Serial port 2 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + case 0x74: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x20; + if (valxor) + fdc37c67x_serial_handler(dev, 1); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + + if (valxor & 0x03) { + fdc37c67x_serial_handler(dev, 0); + fdc37c67x_serial_handler(dev, 1); + } + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x7f; + break; + case 0xf2: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + } + break; + case 0x07: /* Keyboard */ + switch (dev->cur_reg) { + case 0x30: + case 0x70: case 0x72: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) + fdc37c67x_kbc_handler(dev); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x84; + break; + } + break; + case 0x08: /* Aux. I/O */ + switch (dev->cur_reg) { + case 0x30: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xb4: case 0xb6: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x9e; + break; + case 0xb5: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xd7; + break; + case 0xb7: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x17; + break; + case 0xb8: + case 0xf1 ... 0xf3: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xc0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = (dev->ld_regs[dev->regs[7]][dev->cur_reg] & 0xe4) | (val & 0x1b); + break; + case 0xc1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x0f; + for (int i = 0; i < 4; i++) + fdc_set_fdd_changed(i, !!(val & (1 << i))); + break; + case 0xf4: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xef; + break; + } + break; } - } else - return; - } - - if (dev->cur_reg < 48) { - switch (dev->cur_reg) { - case 0x03: - if (valxor & 0x83) - fdc37c67x_gpio_handler(dev); - dev->regs[0x03] &= 0x83; - break; - case 0x22: - if (valxor & 0x01) - fdc37c67x_fdc_handler(dev); - if (valxor & 0x08) - fdc37c67x_lpt_handler(dev); - if (valxor & 0x10) - fdc37c67x_serial_handler(dev, 0); - if (valxor & 0x20) - fdc37c67x_serial_handler(dev, 1); - break; - case 0x26: - case 0x27: - fdc37c67x_sio_handler(dev); - break; - - default: - break; } - - return; - } - - switch (dev->regs[7]) { - case 0: - /* FDD */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x01; - if (valxor) - fdc37c67x_fdc_handler(dev); - break; - case 0xF0: - if (valxor & 0x01) - fdc_update_enh_mode(dev->fdc, val & 0x01); - if (valxor & 0x10) - fdc_set_swap(dev->fdc, (val & 0x10) >> 4); - break; - case 0xF1: - if (valxor & 0xC) - fdc_update_densel_force(dev->fdc, (val & 0xc) >> 2); - break; - case 0xF2: - if (valxor & 0xC0) - fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); - if (valxor & 0x30) - fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); - if (valxor & 0x0C) - fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); - if (valxor & 0x03) - fdc_update_rwc(dev->fdc, 0, (val & 0x03)); - break; - case 0xF4: - if (valxor & 0x18) - fdc_update_drvrate(dev->fdc, 0, (val & 0x18) >> 3); - break; - case 0xF5: - if (valxor & 0x18) - fdc_update_drvrate(dev->fdc, 1, (val & 0x18) >> 3); - break; - case 0xF6: - if (valxor & 0x18) - fdc_update_drvrate(dev->fdc, 2, (val & 0x18) >> 3); - break; - case 0xF7: - if (valxor & 0x18) - fdc_update_drvrate(dev->fdc, 3, (val & 0x18) >> 3); - break; - - default: - break; - } - break; - case 3: - /* Parallel port */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x08; - if (valxor) - fdc37c67x_lpt_handler(dev); - if (dev->cur_reg == 0x70) - fdc37c67x_smi_handler(dev); - break; - - default: - break; - } - break; - case 4: - /* Serial port 1 */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x10; - if (valxor) - fdc37c67x_serial_handler(dev, 0); - if (dev->cur_reg == 0x70) - fdc37c67x_smi_handler(dev); - break; - - default: - break; - } - break; - case 5: - /* Serial port 2 */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x20; - if (valxor) - fdc37c67x_serial_handler(dev, 1); - if (dev->cur_reg == 0x70) - fdc37c67x_smi_handler(dev); - break; - - default: - break; - } - break; - case 8: - /* Auxiliary I/O */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if (valxor) - fdc37c67x_auxio_handler(dev); - break; - case 0xb4: - case 0xb5: - fdc37c67x_smi_handler(dev); - break; - - default: - break; - } - break; - - default: - break; } } static uint8_t fdc37c67x_read(uint16_t port, void *priv) { - fdc37c67x_t *dev = (fdc37c67x_t *) priv; - uint8_t index = (port & 1) ? 0 : 1; - uint8_t ret = 0xff; - uint16_t smi_stat = pic_get_smi_irq_status(); - int f_irq = dev->ld_regs[0][0x70]; - int p_irq = dev->ld_regs[3][0x70]; - int s1_irq = dev->ld_regs[4][0x70]; - int s2_irq = dev->ld_regs[5][0x70]; + fdc37c67x_t *dev = (fdc37c67x_t *) priv; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ret = 0xff; + + /* Compaq Presario 4500: Unlock at FB, Register at EA, Data at EB, Lock at F9. */ + if ((port == 0xea) || (port == 0xf9) || (port == 0xfb)) + index = 1; + else if (port == 0xeb) + index = 0; if (dev->locked) { if (index) @@ -478,28 +613,25 @@ fdc37c67x_read(uint16_t port, void *priv) else { if (dev->cur_reg < 0x30) { if (dev->cur_reg == 0x20) - ret = dev->chip_id; + ret = 0x47; else ret = dev->regs[dev->cur_reg]; - } else { - if ((dev->regs[7] == 0) && (dev->cur_reg == 0xF2)) { - ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); - } else + } else if (dev->regs[7] <= dev->max_ld) { + if ((dev->regs[7] == 0x00) && (dev->cur_reg == 0xf2)) + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | + (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); + else if ((dev->regs[7] == 0x08) && (dev->cur_reg == 0xc1)) { + ret = dev->ld_regs[dev->regs[7]][dev->cur_reg] & 0xf0; + for (int i = 0; i < 4; i++) + ret |= (fdc_get_fdd_changed(i) << i); + } else if ((dev->regs[7] == 0x08) && (dev->cur_reg == 0xc2)) + ret = fdc_get_shadow(dev->fdc); + else if ((dev->regs[7] == 0x08) && (dev->cur_reg == 0xc3)) + ret = serial_get_shadow(dev->uart[0]); + else if ((dev->regs[7] == 0x08) && (dev->cur_reg == 0xc4)) + ret = serial_get_shadow(dev->uart[1]); + else if ((dev->regs[7] != 0x06) || (dev->cur_reg != 0xf3)) ret = dev->ld_regs[dev->regs[7]][dev->cur_reg]; - - /* TODO: 8042 P1.2 SMI#. */ - if ((dev->regs[7] == 8) && (dev->cur_reg == 0xb6)) { - ret = dev->ld_regs[dev->regs[7]][dev->cur_reg] & 0xe1; - ret |= ((!!(smi_stat & (1 << p_irq))) << 1); - ret |= ((!!(smi_stat & (1 << s2_irq))) << 2); - ret |= ((!!(smi_stat & (1 << s1_irq))) << 3); - ret |= ((!!(smi_stat & (1 << f_irq))) << 4); - } else if ((dev->regs[7] == 8) && (dev->cur_reg == 0xb7)) { - ret = dev->ld_regs[dev->regs[7]][dev->cur_reg] & 0xec; - ret |= ((!!(smi_stat & (1 << 12))) << 0); - ret |= ((!!(smi_stat & (1 << 1))) << 1); - ret |= ((!!(smi_stat & (1 << 10))) << 4); - } } } } @@ -508,75 +640,86 @@ fdc37c67x_read(uint16_t port, void *priv) } static void -fdc37c67x_reset(fdc37c67x_t *dev) +fdc37c67x_reset(void *priv) { - memset(dev->regs, 0, 48); + fdc37c67x_t *dev = (fdc37c67x_t *) priv; + + memset(dev->regs, 0x00, sizeof(dev->regs)); dev->regs[0x03] = 0x03; - dev->regs[0x20] = dev->chip_id; + dev->regs[0x20] = 0x40; + dev->regs[0x21] = 0x01; dev->regs[0x22] = 0x39; dev->regs[0x24] = 0x04; - dev->regs[0x26] = 0xf0; + dev->regs[0x26] = dev->port_370 ? 0x70 : 0xf0; dev->regs[0x27] = 0x03; - for (uint8_t i = 0; i < 11; i++) - memset(dev->ld_regs[i], 0, 256); + for (uint8_t i = 0; i <= 0x0a; i++) + memset(dev->ld_regs[i], 0x00, 256); /* Logical device 0: FDD */ - dev->ld_regs[0][0x30] = 1; - dev->ld_regs[0][0x60] = 3; - dev->ld_regs[0][0x61] = 0xf0; - dev->ld_regs[0][0x70] = 6; - dev->ld_regs[0][0x74] = 2; - dev->ld_regs[0][0xf0] = 0x0e; - dev->ld_regs[0][0xf2] = 0xff; + dev->ld_regs[0x00][0x30] = 0x00; + dev->ld_regs[0x00][0x60] = 0x03; + dev->ld_regs[0x00][0x61] = 0xf0; + dev->ld_regs[0x00][0x70] = 0x06; + dev->ld_regs[0x00][0x74] = 0x02; + dev->ld_regs[0x00][0xf0] = 0x0e; + dev->ld_regs[0x00][0xf2] = 0xff; /* Logical device 3: Parallel Port */ - dev->ld_regs[3][0x30] = 1; - dev->ld_regs[3][0x60] = 3; - dev->ld_regs[3][0x61] = 0x78; - dev->ld_regs[3][0x70] = 7; - dev->ld_regs[3][0x74] = 4; - dev->ld_regs[3][0xf0] = 0x3c; + dev->ld_regs[0x03][0x30] = 0x00; + dev->ld_regs[0x03][0x60] = 0x03; + dev->ld_regs[0x03][0x61] = 0x78; + dev->ld_regs[0x03][0x70] = 0x07; + dev->ld_regs[0x03][0x74] = 0x04; + dev->ld_regs[0x03][0xf0] = 0x3c; /* Logical device 4: Serial Port 1 */ - dev->ld_regs[4][0x30] = 1; - dev->ld_regs[4][0x60] = 3; - dev->ld_regs[4][0x61] = 0xf8; - dev->ld_regs[4][0x70] = 4; - dev->ld_regs[4][0xf0] = 3; - serial_setup(dev->uart[0], COM1_ADDR, dev->ld_regs[4][0x70]); + dev->ld_regs[0x04][0x30] = 0x00; + dev->ld_regs[0x04][0x60] = 0x03; + dev->ld_regs[0x04][0x61] = 0xf8; + dev->ld_regs[0x04][0x70] = 0x04; + serial_irq(dev->uart[0], dev->ld_regs[4][0x70]); /* Logical device 5: Serial Port 2 */ - dev->ld_regs[5][0x30] = 1; - dev->ld_regs[5][0x60] = 2; - dev->ld_regs[5][0x61] = 0xf8; - dev->ld_regs[5][0x70] = 3; - dev->ld_regs[5][0x74] = 4; - dev->ld_regs[5][0xf1] = 2; - dev->ld_regs[5][0xf2] = 3; - serial_setup(dev->uart[1], COM2_ADDR, dev->ld_regs[5][0x70]); + dev->ld_regs[0x05][0x30] = 0x00; + dev->ld_regs[0x05][0x60] = 0x02; + dev->ld_regs[0x05][0x61] = 0xf8; + dev->ld_regs[0x05][0x70] = 0x03; + dev->ld_regs[0x05][0x74] = 0x04; + dev->ld_regs[0x05][0xf1] = 0x02; + dev->ld_regs[0x05][0xf2] = 0x03; + serial_irq(dev->uart[1], dev->ld_regs[5][0x70]); /* Logical device 7: Keyboard */ - dev->ld_regs[7][0x30] = 1; - dev->ld_regs[7][0x61] = 0x60; - dev->ld_regs[7][0x70] = 1; - dev->ld_regs[7][0x72] = 12; + dev->ld_regs[0x07][0x30] = 0x00; + dev->ld_regs[0x07][0x61] = 0x60; + dev->ld_regs[0x07][0x70] = 0x01; /* Logical device 8: Auxiliary I/O */ - dev->ld_regs[8][0xc0] = 6; - dev->ld_regs[8][0xc1] = 3; + dev->ld_regs[0x08][0x30] = 0x00; + dev->ld_regs[0x08][0x60] = 0x00; + dev->ld_regs[0x08][0x61] = 0x00; + dev->ld_regs[0x08][0xc0] = 0x06; + dev->ld_regs[0x08][0xc1] = 0x03; fdc37c67x_gpio_handler(dev); fdc37c67x_lpt_handler(dev); fdc37c67x_serial_handler(dev, 0); fdc37c67x_serial_handler(dev, 1); - fdc37c67x_auxio_handler(dev); - fdc37c67x_sio_handler(dev); + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); fdc_reset(dev->fdc); + fdc37c67x_fdc_handler(dev); + for (int i = 0; i < 4; i++) + fdc_set_fdd_changed(i, 1); + + fdc37c67x_kbc_handler(dev); + + fdc37c67x_superio_handler(dev); + dev->locked = 0; } @@ -595,35 +738,65 @@ fdc37c67x_init(const device_t *info) 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->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); - dev->chip_id = info->local & 0xff; + dev->lpt = device_add_inst(&lpt_port_device, 1); - dev->gpio_regs[0] = 0xff; -#if 0 - dev->gpio_regs[1] = (info->local == 0x0030) ? 0xff : 0xfd; -#endif - dev->gpio_regs[1] = (dev->chip_id == 0x30) ? 0xff : 0xfd; + dev->kbc_type = info->local & FDC37XXXX_KBC; + + dev->is_compaq = (dev->kbc_type == FDC37XXX1); + + dev->port_370 = !!(info->local & FDC37XXXX_370); + + dev->max_ld = 8; + + if (dev->is_compaq) { + io_sethandler(0x0f9, 0x0001, + fdc37c67x_read, NULL, NULL, fdc37c67x_write, NULL, NULL, dev); + io_sethandler(0x0fb, 0x0001, + fdc37c67x_read, NULL, NULL, fdc37c67x_write, NULL, NULL, dev); + } + + switch (dev->kbc_type) { + case FDC37XXX1: + dev->kbc = device_add(&kbc_ps2_compaq_device); + break; + case FDC37XXX2: + dev->kbc = device_add(&kbc_ps2_intel_ami_pci_device); + break; + case FDC37XXX3: + default: + dev->kbc = device_add(&kbc_ps2_pci_device); + break; + case FDC37XXX5: + dev->kbc = device_add(&kbc_ps2_phoenix_device); + break; + case FDC37XXX7: + dev->kbc = device_add(&kbc_ps2_phoenix_pci_device); + break; + } + + /* Set the defaults here so the ports can be removed by fdc37c67x_reset(). */ + dev->fdc_base = 0x03f0; + dev->lpt_base = 0x0378; + dev->uart_base[0] = 0x03f8; + dev->uart_base[1] = 0x02f8; + dev->kbc_base = 0x0060; fdc37c67x_reset(dev); - io_sethandler(FDC_SECONDARY_ADDR, 0x0002, - fdc37c67x_read, NULL, NULL, fdc37c67x_write, NULL, NULL, dev); - io_sethandler(FDC_PRIMARY_ADDR, 0x0002, - fdc37c67x_read, NULL, NULL, fdc37c67x_write, NULL, NULL, dev); - return dev; } const device_t fdc37c67x_device = { - .name = "SMC FDC37C67X Super I/O", + .name = "SMC FDC37C67x Super I/O", .internal_name = "fdc37c67x", .flags = 0, - .local = 0x40, + .local = 0, .init = fdc37c67x_init, .close = fdc37c67x_close, - .reset = NULL, + .reset = fdc37c67x_reset, .available = NULL, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/sio/sio_fdc37c6xx.c b/src/sio/sio_fdc37c6xx.c index 0f3460565..3b2a8b942 100644 --- a/src/sio/sio_fdc37c6xx.c +++ b/src/sio/sio_fdc37c6xx.c @@ -44,6 +44,7 @@ typedef struct fdc37c6xx_t { int com4_addr; fdc_t *fdc; serial_t *uart[2]; + lpt_t *lpt; } fdc37c6xx_t; static void @@ -106,26 +107,78 @@ set_serial_addr(fdc37c6xx_t *dev, int port) } static void -lpt1_handler(fdc37c6xx_t *dev) +lpt_handler(fdc37c6xx_t *dev) { - lpt1_remove(); - switch (dev->regs[1] & 3) { - case 1: - lpt1_setup(LPT_MDA_ADDR); - lpt1_irq(LPT_MDA_IRQ); + uint16_t lpt_port = 0x0000; + uint16_t mask = 0xfffc; + uint8_t local_enable = 1; + uint8_t lpt_irq = LPT1_IRQ; + /* DMA is guesswork - what channel do boards actually use? */ + uint8_t lpt_dma = 3; + uint8_t lpt_ext = !(dev->regs[1] & 0x08); + uint8_t lpt_mode = (dev->chip_id >= 0x65) ? (dev->regs[4] & 0x03) : 0x00; + + switch (dev->regs[1] & 0x03) { + case 0x01: + lpt_port = LPT_MDA_ADDR; + lpt_irq = LPT_MDA_IRQ; break; - case 2: - lpt1_setup(LPT1_ADDR); - lpt1_irq(LPT1_IRQ /*LPT2_IRQ*/); + case 0x02: + lpt_port = LPT1_ADDR; + lpt_irq = LPT1_IRQ /*LPT2_IRQ*/; break; - case 3: - lpt1_setup(LPT2_ADDR); - lpt1_irq(LPT1_IRQ /*LPT2_IRQ*/); + case 0x03: + lpt_port = LPT2_ADDR; + lpt_irq = LPT1_IRQ /*LPT2_IRQ*/; break; default: + local_enable = 0; break; } + + if (lpt_irq > 15) + lpt_irq = 0xff; + + if (lpt_dma >= 4) + lpt_dma = 0xff; + + lpt_port_remove(dev->lpt); + lpt_set_fifo_threshold(dev->lpt, dev->regs[0x0a] & 0x0f); + if (lpt_ext) switch (lpt_mode) { + default: + case 0x00: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 1); + break; + case 0x01: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x02: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + case 0x03: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + } else { + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + } + + if (local_enable && (lpt_port >= 0x0100) && (lpt_port <= (0x0ffc & mask))) + lpt_port_setup(dev->lpt, lpt_port); + + lpt_port_irq(dev->lpt, lpt_irq); } static void @@ -183,7 +236,7 @@ fdc37c6xx_write(uint16_t port, uint8_t val, void *priv) break; case 1: if (valxor & 3) - lpt1_handler(dev); + lpt_handler(dev); if (valxor & 0x60) { set_com34_addr(dev); set_serial_addr(dev, 0); @@ -232,7 +285,7 @@ fdc37c6xx_read(uint16_t port, void *priv) uint8_t ret = 0xff; if (dev->tries == 2) { - if (port == 0x3f1) + if ((port == 0x3f1) && (dev->cur_reg <= dev->max_reg)) ret = dev->regs[dev->cur_reg]; } @@ -251,8 +304,8 @@ fdc37c6xx_reset(fdc37c6xx_t *dev) serial_remove(dev->uart[1]); serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); - lpt1_remove(); - lpt1_setup(LPT1_ADDR); + lpt_port_remove(dev->lpt); + lpt_port_setup(dev->lpt, LPT1_ADDR); fdc_reset(dev->fdc); fdc_remove(dev->fdc); @@ -293,7 +346,7 @@ fdc37c6xx_reset(fdc37c6xx_t *dev) set_serial_addr(dev, 0); set_serial_addr(dev, 1); - lpt1_handler(dev); + lpt_handler(dev); fdc_handler(dev); @@ -314,7 +367,10 @@ fdc37c6xx_init(const device_t *info) { fdc37c6xx_t *dev = (fdc37c6xx_t *) calloc(1, sizeof(fdc37c6xx_t)); - dev->fdc = device_add(&fdc_at_smc_device); + if (dev->chip_id >= 0x63) + dev->fdc = device_add(&fdc_at_smc_device); + else + dev->fdc = device_add(&fdc_at_smc_661_device); dev->chip_id = info->local & 0xff; dev->has_ide = (info->local >> 8) & 0xff; @@ -327,6 +383,8 @@ fdc37c6xx_init(const device_t *info) dev->uart[1] = device_add_inst(&ns16450_device, 2); } + dev->lpt = device_add_inst(&lpt_port_device, 1); + io_sethandler(FDC_PRIMARY_ADDR, 0x0002, fdc37c6xx_read, NULL, NULL, fdc37c6xx_write, NULL, NULL, dev); diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 8d8f76cb6..9d0acfae2 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -6,17 +6,15 @@ * * This file is part of the 86Box distribution. * - * Implementation of the SMC FDC37C932FR and FDC37C935 Super - * I/O Chips. - * - * + * Implementation of the SMC FDC37C93x Super I/O Chips. * * Authors: Miran Grca, * * Copyright 2016-2018 Miran Grca. */ -#include +#include #include +#include #include #include #include @@ -25,6 +23,7 @@ #include <86box/timer.h> #include <86box/device.h> #include <86box/pci.h> +#include <86box/pic.h> #include <86box/lpt.h> #include <86box/serial.h> #include <86box/hdc.h> @@ -37,20 +36,28 @@ #include <86box/apm.h> #include <86box/access_bus.h> #include <86box/acpi.h> -#include <86box/sio.h> +#include <86box/plat.h> #include <86box/plat_unused.h> +#include <86box/video.h> +#include <86box/sio.h> +#include "cpu.h" typedef struct fdc37c93x_t { uint8_t chip_id; uint8_t is_apm; uint8_t is_compaq; uint8_t has_nvr; + uint8_t max_ld; uint8_t tries; uint8_t port_370; - uint8_t gpio_regs[2]; + uint8_t gpio_reg; + uint8_t gpio_regs[256]; + uint8_t gpio_pulldn[8]; uint8_t auxio_reg; uint8_t regs[48]; + uint8_t alt_regs[3][8]; uint8_t ld_regs[11][256]; + uint16_t kbc_type; uint16_t superio_base; uint16_t fdc_base; uint16_t lpt_base; @@ -68,11 +75,21 @@ typedef struct fdc37c93x_t { acpi_t *acpi; void *kbc; serial_t *uart[2]; + lpt_t *lpt; } fdc37c93x_t; static void fdc37c93x_write(uint16_t port, uint8_t val, void *priv); static uint8_t fdc37c93x_read(uint16_t port, void *priv); +static uint8_t gp_func_regs[8][8] = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, /* GP00-GP07 */ + { 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7 }, /* GP10-GP17 */ + { 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef }, /* GP20-GP27 */ + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, /* GP30-GP37 */ + { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 }, /* GP40-GP47 */ + { 0xc8, 0xc9, 0xff, 0xcb, 0xcc, 0xff, 0xff, 0xff }, /* GP50-GP57 */ + { 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7 }, /* GP60-GP67 */ + { 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf } }; /* GP70-GP77 */ + static uint16_t make_port_superio(const fdc37c93x_t *dev) { @@ -122,14 +139,562 @@ fdc37c93x_auxio_write(UNUSED(uint16_t port), uint8_t val, void *priv) dev->auxio_reg = val; } +static __inline uint8_t +fdc37c93x_do_read_gp(fdc37c93x_t *dev, int reg, int bit) +{ + /* Update bit 2 on the Acer V35N according to the selected graphics card type. */ + if ((reg == 2) && (strstr(machine_get_internal_name(), "acer") != NULL)) + dev->gpio_pulldn[reg] = (dev->gpio_pulldn[reg] & 0xfb) | (video_is_mda() ? 0x00 : 0x04); + + return dev->gpio_regs[reg] & dev->gpio_pulldn[reg] & (1 << bit); +} + +static __inline uint8_t +fdc37c93x_do_read_alt(const fdc37c93x_t *dev, int alt, int reg, int bit) +{ + return dev->alt_regs[alt][reg] & (1 << bit); +} + +static uint8_t +fdc37c93x_read_gp(const fdc37c93x_t *dev, int reg, int bit) +{ + uint8_t gp_reg = gp_func_regs[reg][bit]; + uint8_t gp_func_reg = dev->ld_regs[0x08][gp_reg]; + uint8_t gp_func; + uint8_t ret = 1 << bit; + + if (gp_func_reg & 0x01) switch (reg) { + default: + /* Do nothing, this GP does not exist. */ + break; + case 1: + switch (bit) { + default: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + else + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + gp_func = (gp_func_reg >> 3) & 0x03; + if (!(gp_func & 0x01)) { + if (gp_func & 0x02) + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + else + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + } + break; + case 3: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x01) + /* TODO: Write to power LED if it's ever implemented. */ + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + else + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 6: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 1 ... 3: + ret = fdc37c93x_do_read_alt(dev, gp_func - 1, reg, bit); + break; + } + break; + } + break; + case 2: + switch (bit) { + default: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + else + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 0: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 2: + ret = kbc_at_read_p(dev->kbc, 2, 0x01) ? (1 << bit) : 0x00; + break; + } + break; + case 1: case 2: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 1: case 2: + ret = fdc37c93x_do_read_alt(dev, gp_func - 1, reg, bit); + break; + } + break; + case 5: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + else + ret = kbc_at_read_p(dev->kbc, 2, 0x02) ? (1 << bit) : 0x00; + break; + case 6: case 7: + /* Do nothing, these bits do not exist. */ + break; + } + break; + case 4: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + } + break; + case 0: case 1: + switch (gp_func) { + case 0: + ret = fdc_get_media_id(dev->fdc, bit ^ 1) ? (1 << bit) : 0x00; + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + } + break; + case 6: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 2: + /* TODO: Write to power LED if it's ever implemented. */ + ret = fdc37c93x_do_read_alt(dev, 1, reg, bit); + break; + case 3: + ret = fdc37c93x_do_read_alt(dev, 2, reg, bit); + break; + } + break; + case 7: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 2: + ret = fdc37c93x_do_read_alt(dev, 1, reg, bit); + break; + } + break; + } + break; + case 5: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + break; + case 0: case 3: case 4: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + } + break; + case 1: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + } + break; + } + break; + case 6: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 2: + ret = kbc_at_read_p(dev->kbc, 1, 1 << bit); + break; + } + break; + case 0: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 2: + /* TODO: Write to power LED if it's ever implemented. */ + ret = fdc37c93x_do_read_alt(dev, 1, reg, bit); + break; + } + break; + case 1: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + case 2: + ret = fdc37c93x_do_read_alt(dev, 1, reg, bit); + break; + } + break; + } + break; + case 7: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + switch (gp_func) { + case 0: + ret = fdc37c93x_do_read_alt(dev, 0, reg, bit); + break; + case 1: + ret = fdc37c93x_do_read_gp((fdc37c93x_t *) dev, reg, bit); + break; + } + break; + } + break; + } + + if (gp_func_reg & 0x02) + ret ^= (1 << bit); + + return ret; +} + +static __inline void +fdc37c93x_do_write_gp(fdc37c93x_t *dev, int reg, int bit, int set) +{ + dev->gpio_regs[reg] = (dev->gpio_regs[reg] & ~(1 << bit)) | + (set << bit); +} + +static __inline void +fdc37c93x_do_write_alt(fdc37c93x_t *dev, int alt, int reg, int bit, int set) +{ + dev->alt_regs[alt][reg] = (dev->alt_regs[alt][reg] & ~(1 << bit)) | + (set << bit); +} + +static void +fdc37c93x_write_gp(fdc37c93x_t *dev, int reg, int bit, int set) +{ + uint8_t gp_func_reg = dev->ld_regs[0x08][gp_func_regs[reg][bit]]; + uint8_t gp_func; + + if (gp_func_reg & 0x02) + set = !set; + + if (!(gp_func_reg & 0x01)) switch (reg) { + default: + /* Do nothing, this GP does not exist. */ + break; + case 1: + switch (bit) { + default: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + fdc37c93x_do_write_gp(dev, reg, bit, set); + else + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + gp_func = (gp_func_reg >> 3) & 0x03; + if (!(gp_func & 0x01)) { + if (gp_func & 0x02) { + set ? picint(1 << 13) : picintc(1 << 13); + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + } else + fdc37c93x_do_write_gp(dev, reg, bit, set); + } + break; + case 3: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x01) + /* TODO: Write to power LED if it's ever implemented. */ + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + else + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 6: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (gp_func) { + case 0: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 1 ... 3: + fdc37c93x_do_write_alt(dev, gp_func - 1, reg, bit, set); + break; + } + break; + } + break; + case 2: + switch (bit) { + default: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + fdc37c93x_do_write_gp(dev, reg, bit, set); + else + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 0: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (gp_func) { + case 0: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 2: + kbc_at_write_p(dev->kbc, 2, 0xfe, set); + break; + } + break; + case 1: case 2: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (gp_func) { + case 0: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 1: case 2: + fdc37c93x_do_write_alt(dev, gp_func - 1, reg, bit, set); + break; + } + break; + case 5: + gp_func = (gp_func_reg >> 3) & 0x01; + if (gp_func == 0x00) + fdc37c93x_do_write_gp(dev, reg, bit, set); + else + kbc_at_write_p(dev->kbc, 2, 0xfd, set << 1); + break; + case 6: case 7: + /* Do nothing, these bits do not exist. */ + break; + } + break; + case 4: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + } + break; + case 0: case 1: + switch (gp_func) { + case 0: + fdc_set_media_id(dev->fdc, bit ^ 1, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + } + break; + case 6: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 2: + /* TODO: Write to power LED if it's ever implemented. */ + fdc37c93x_do_write_alt(dev, 1, reg, bit, set); + break; + case 3: + fdc37c93x_do_write_alt(dev, 2, reg, bit, set); + break; + } + break; + case 7: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 2: + fdc37c93x_do_write_alt(dev, 1, reg, bit, set); + if (!set) + smi_raise(); + break; + } + break; + } + break; + case 5: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + break; + case 0: case 3: case 4: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + } + break; + case 1: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + if (set) + plat_power_off(); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + } + break; + } + break; + case 6: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 2: + kbc_at_write_p(dev->kbc, 1, ~(1 << bit), set << bit); + break; + } + break; + case 0: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 2: + /* TODO: Write to power LED if it's ever implemented. */ + fdc37c93x_do_write_alt(dev, 1, reg, bit, set); + break; + } + break; + case 1: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + case 2: + fdc37c93x_do_write_alt(dev, 1, reg, bit, set); + break; + } + break; + } + break; + case 7: + gp_func = (gp_func_reg >> 3) & 0x03; + switch (bit) { + default: + switch (gp_func) { + case 0: + fdc37c93x_do_write_alt(dev, 0, reg, bit, set); + break; + case 1: + fdc37c93x_do_write_gp(dev, reg, bit, set); + break; + } + break; + } + break; + } +} + static uint8_t fdc37c93x_gpio_read(uint16_t port, void *priv) { const fdc37c93x_t *dev = (fdc37c93x_t *) priv; uint8_t ret = 0xff; - if (strcmp(machine_get_internal_name(), "vectra54")) - ret = dev->gpio_regs[port & 1]; + if (dev->locked) { + if (dev->is_compaq) + ret = fdc37c93x_read(port & 0x0001, priv); + } else if (port & 0x0001) switch (dev->gpio_reg) { + case 0x01: case 0x02: + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, dev->gpio_reg, i); + break; + case 0x03: + ret = dev->ld_regs[0x08][0xf4]; + break; + case 0x04 ... 0x07: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, dev->gpio_reg, i); + } + break; + case 0x08 ... 0x0f: + if (dev->chip_id >= FDC37C93X_FR) + ret = dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08]; + break; + } else + ret = dev->gpio_reg; return ret; } @@ -139,8 +704,52 @@ fdc37c93x_gpio_write(uint16_t port, uint8_t val, void *priv) { fdc37c93x_t *dev = (fdc37c93x_t *) priv; - if (!(port & 1)) - dev->gpio_regs[0] = (dev->gpio_regs[0] & 0xfc) | (val & 0x03); + if (dev->locked) { + if (dev->is_compaq) + fdc37c93x_write(port & 0x0001, val, priv); + } else if (port & 0x0001) switch (dev->gpio_reg) { + case 0x01: case 0x02: + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, dev->gpio_reg, i, val & (1 << i)); + break; + case 0x03: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[0x08][0xf4] = val & 0xef; + else + dev->ld_regs[0x08][0xf4] = val & 0x0f; + break; + case 0x04 ... 0x07: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, dev->gpio_reg, i, val & (1 << i)); + break; + case 0x08: case 0x0a: + case 0x0c: case 0x0e: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val; + break; + case 0x09: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val & 0xd3; + break; + case 0x0b: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val & 0x17; + break; + case 0x0d: + if (dev->chip_id == FDC37C93X_APM) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val; + else if (dev->chip_id == FDC37C93X_FR) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val & 0xbf; + break; + case 0x0f: + if (dev->chip_id == FDC37C93X_APM) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val & 0x7f; + else if (dev->chip_id == FDC37C93X_FR) + dev->ld_regs[0x08][0xb0 + dev->gpio_reg - 0x08] = val & 0x3f; + break; + } else + dev->gpio_reg = val; } static void @@ -181,28 +790,59 @@ fdc37c93x_fdc_handler(fdc37c93x_t *dev) static void fdc37c93x_lpt_handler(fdc37c93x_t *dev) { - const uint8_t global_enable = !!(dev->regs[0x22] & (1 << 3)); - const uint8_t local_enable = !!dev->ld_regs[3][0x30]; - uint8_t lpt_irq = dev->ld_regs[3][0x70]; - const uint16_t old_base = dev->lpt_base; + uint16_t ld_port = 0x0000; + uint16_t mask = 0xfffc; + uint8_t global_enable = !!(dev->regs[0x22] & (1 << 3)); + uint8_t local_enable = !!dev->ld_regs[3][0x30]; + uint8_t lpt_irq = dev->ld_regs[3][0x70]; + uint8_t lpt_dma = dev->ld_regs[3][0x74]; + uint8_t lpt_mode = dev->ld_regs[3][0xf0] & 0x07; if (lpt_irq > 15) lpt_irq = 0xff; - dev->lpt_base = 0x0000; + if (lpt_dma >= 4) + lpt_dma = 0xff; - if (global_enable && local_enable) - dev->lpt_base = make_port(dev, 3) & 0xfffc; - - if (dev->lpt_base != old_base) { - if ((old_base >= 0x0100) && (old_base <= 0x0ffc)) - lpt1_remove(); - - if ((dev->lpt_base >= 0x0100) && (dev->lpt_base <= 0x0ffc)) - lpt1_setup(dev->lpt_base); + lpt_port_remove(dev->lpt); + lpt_set_fifo_threshold(dev->lpt, (dev->ld_regs[3][0xf0] & 0x78) >> 3); + switch (lpt_mode) { + default: + case 0x04: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x00: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 1); + break; + case 0x01: case 0x05: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x02: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + case 0x03: case 0x07: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; } - - lpt1_irq(lpt_irq); + if (global_enable && local_enable) { + ld_port = (make_port(dev, 3) & 0xfffc) & mask; + if ((ld_port >= 0x0100) && (ld_port <= (0x0ffc & mask))) + lpt_port_setup(dev->lpt, ld_port); + } + lpt_port_irq(dev->lpt, lpt_irq); + lpt_port_dma(dev->lpt, lpt_dma); } static void @@ -212,6 +852,7 @@ fdc37c93x_serial_handler(fdc37c93x_t *dev, const int uart) const uint8_t global_enable = !!(dev->regs[0x22] & (1 << uart_no)); const uint8_t local_enable = !!dev->ld_regs[uart_no][0x30]; const uint16_t old_base = dev->uart_base[uart]; + double clock_src = 24000000.0 / 13.0; dev->uart_base[uart] = 0x0000; @@ -226,7 +867,35 @@ fdc37c93x_serial_handler(fdc37c93x_t *dev, const int uart) serial_setup(dev->uart[uart], dev->uart_base[uart], dev->ld_regs[uart_no][0x70]); } - serial_irq(dev->uart[uart], dev->ld_regs[uart_no][0x70]); + switch (dev->ld_regs[uart_no][0xf0] & 0x03) { + case 0x00: + clock_src = 24000000.0 / 13.0; + break; + case 0x01: + clock_src = 24000000.0 / 12.0; + break; + case 0x02: + clock_src = 24000000.0 / 1.0; + break; + case 0x03: + clock_src = 24000000.0 / 1.625; + break; + + default: + break; + } + + serial_set_clock_src(dev->uart[uart], clock_src); + + /* + TODO: If UART 2's own IRQ pin is also enabled when shared, + it should also be asserted. + */ + if ((dev->chip_id >= FDC37C93X_FR) && (dev->ld_regs[4][0xf0] & 0x80)) { + serial_irq(dev->uart[0], dev->ld_regs[4][0x70]); + serial_irq(dev->uart[1], dev->ld_regs[4][0x70]); + } else + serial_irq(dev->uart[uart], dev->ld_regs[uart_no][0x70]); } static void @@ -276,7 +945,10 @@ fdc37c93x_kbc_handler(fdc37c93x_t *dev) dev->kbc_base = local_enable ? 0x0060 : 0x0000; if (dev->kbc_base != old_base) - kbc_at_handler(local_enable, dev->kbc); + kbc_at_handler(local_enable, dev->kbc_base, dev->kbc); + + kbc_at_set_irq(0, dev->ld_regs[7][0x70], dev->kbc); + kbc_at_set_irq(1, dev->ld_regs[7][0x72], dev->kbc); } static void @@ -304,7 +976,8 @@ fdc37c93x_auxio_handler(fdc37c93x_t *dev) static void fdc37c93x_gpio_handler(fdc37c93x_t *dev) { - const uint8_t local_enable = !dev->locked && !!(dev->regs[0x03] & 0x80); + const uint8_t local_enable = !!(dev->regs[0x03] & 0x80) || + (dev->is_compaq && dev->locked); const uint16_t old_base = dev->gpio_base; dev->gpio_base = 0x0000; @@ -383,23 +1056,15 @@ static void fdc37c93x_write(uint16_t port, uint8_t val, void *priv) { fdc37c93x_t *dev = (fdc37c93x_t *) priv; - uint8_t index = (port & 1) ? 0 : 1; + uint8_t index = !(port & 1); uint8_t valxor; - /* Compaq Presario 4500: Unlock at FB, Register at EA, Data at EB, Lock at F9. */ - if (port == 0xea) - index = 1; - else if (port == 0xeb) - index = 0; - - if (port == 0xfb) { + if (port == 0x00fb) { fdc37c93x_state_change(dev, 1); dev->tries = 0; - return; - } else if (port == 0xf9) { + } else if (port == 0x00f9) fdc37c93x_state_change(dev, 0); - return; - } else if (index) { + else if (index) { if ((!dev->is_compaq) && (val == 0x55) && !dev->locked) { if (dev->tries) { fdc37c93x_state_change(dev, 1); @@ -407,338 +1072,503 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) } else dev->tries++; } else if (dev->locked) { - if ((!dev->is_compaq) && (val == 0xaa)) { + if ((!dev->is_compaq) && (val == 0xaa)) fdc37c93x_state_change(dev, 0); - return; - } - dev->cur_reg = val; + else + dev->cur_reg = val; } else if ((!dev->is_compaq) && dev->tries) dev->tries = 0; - return; - } else { - if (dev->locked) { - if (dev->cur_reg < 48) { - valxor = val ^ dev->regs[dev->cur_reg]; - if ((val == 0x20) || (val == 0x21)) - return; - dev->regs[dev->cur_reg] = val; - } else { - uint8_t keep = 0x00; + } else if (dev->locked) { + if (dev->cur_reg < 0x30) { + valxor = val ^ dev->regs[dev->cur_reg]; - valxor = val ^ dev->ld_regs[dev->regs[7]][dev->cur_reg]; - if (((dev->cur_reg & 0xF0) == 0x70) && (dev->regs[7] < 4)) - return; - /* Block writes to some logical devices. */ - if (dev->regs[7] > 0x0a) - return; - else - switch (dev->regs[7]) { - // case 0x01: - // case 0x02: - // return; - case 0x06: - if (!dev->has_nvr) - return; - /* Bits 0 to 3 of logical device 6 (RTC) register F0h must stay set - once they are set. */ - else if (dev->cur_reg == 0xf0) - keep = dev->ld_regs[dev->regs[7]][dev->cur_reg] & 0x0f; - break; - case 0x09: - /* If we're on the FDC37C935, return as this is not a valid - logical device there. */ - if (!dev->is_apm && (dev->chip_id == 0x02)) - return; - break; - case 0x0a: - /* If we're not on the FDC37C931APM, return as this is not a - valid logical device there. */ - if (!dev->is_apm) - return; - break; - - default: - break; - } - dev->ld_regs[dev->regs[7]][dev->cur_reg] = val | keep; - } - } else - return; - } - - if (dev->cur_reg < 48) { - switch (dev->cur_reg) { - case 0x02: - if (val == 0x02) - fdc37c93x_state_change(dev, 0); - break; - case 0x03: - dev->regs[0x03] &= 0x83; - break; - case 0x22: - if (valxor & 0x01) - fdc37c93x_fdc_handler(dev); - if (valxor & 0x08) - fdc37c93x_lpt_handler(dev); - if (valxor & 0x10) - fdc37c93x_serial_handler(dev, 0); - if (valxor & 0x20) - fdc37c93x_serial_handler(dev, 1); - if ((valxor & 0x40) && (dev->chip_id != 0x02)) - fdc37c93x_access_bus_handler(dev); - break; - - case 0x27: - if (dev->chip_id != 0x02) - fdc37c93x_superio_handler(dev); - break; - - default: - break; - } - - return; - } - - switch (dev->regs[7]) { - case 0: - /* FDD */ switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x01; - if (valxor) - fdc37c93x_fdc_handler(dev); + case 0x02: + dev->regs[dev->cur_reg] = val; + if (val == 0x02) + fdc37c93x_state_change(dev, 0); break; - case 0xF0: + case 0x03: + dev->regs[dev->cur_reg] = val & 0x83; + fdc37c93x_gpio_handler(dev); + break; + case 0x07: case 0x26: + case 0x2e ... 0x2f: + dev->regs[dev->cur_reg] = val; + break; + case 0x22: + if (dev->chip_id >= FDC37C93X_FR) + dev->regs[dev->cur_reg] = val & 0x7f; + else + dev->regs[dev->cur_reg] = val & 0x6f; + if (valxor & 0x01) - fdc_update_enh_mode(dev->fdc, val & 0x01); - if (valxor & 0x10) - fdc_set_swap(dev->fdc, (val & 0x10) >> 4); - break; - case 0xF1: - if (valxor & 0xC) - fdc_update_densel_force(dev->fdc, (val & 0xc) >> 2); - break; - case 0xF2: - if (valxor & 0xC0) - fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); - if (valxor & 0x30) - fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); - if (valxor & 0x0C) - fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); - if (valxor & 0x03) - fdc_update_rwc(dev->fdc, 0, (val & 0x03)); - break; - case 0xF4: - if (valxor & 0x18) - fdc_update_drvrate(dev->fdc, 0, (val & 0x18) >> 3); - break; - case 0xF5: - if (valxor & 0x18) - fdc_update_drvrate(dev->fdc, 1, (val & 0x18) >> 3); - break; - case 0xF6: - if (valxor & 0x18) - fdc_update_drvrate(dev->fdc, 2, (val & 0x18) >> 3); - break; - case 0xF7: - if (valxor & 0x18) - fdc_update_drvrate(dev->fdc, 3, (val & 0x18) >> 3); - break; - - default: - break; - } - break; - case 3: - /* Parallel port */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x08; - if (valxor) + fdc37c93x_fdc_handler(dev); + if (valxor & 0x08) fdc37c93x_lpt_handler(dev); - break; - - default: - break; - } - break; - case 4: - /* Serial port 1 */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x10; - if (valxor) + if (valxor & 0x10) fdc37c93x_serial_handler(dev, 0); - break; - - default: - break; - } - break; - case 5: - /* Serial port 2 */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x20; - if (valxor) + if (valxor & 0x20) fdc37c93x_serial_handler(dev, 1); - break; - - default: - break; - } - break; - case 6: - /* RTC/NVR */ - if (!dev->has_nvr) - return; - switch (dev->cur_reg) { - case 0x30: - if (valxor) { - fdc37c93x_nvr_pri_handler(dev); - if (dev->chip_id != 0x02) - fdc37c93x_nvr_sec_handler(dev); - } - break; - case 0x62: - case 0x63: - if ((dev->chip_id != 0x02) && valxor) - fdc37c93x_nvr_sec_handler(dev); - break; - case 0xf0: - if (valxor) { - nvr_lock_set(0x80, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x01), dev->nvr); - nvr_lock_set(0xa0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x02), dev->nvr); - nvr_lock_set(0xc0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x04), dev->nvr); - nvr_lock_set(0xe0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x08), dev->nvr); - if ((dev->chip_id == 0x02) && (dev->ld_regs[6][dev->cur_reg] & 0x80)) - nvr_bank_set(0, 1, dev->nvr); - else if ((dev->chip_id != 0x02) && (dev->ld_regs[6][dev->cur_reg] & 0x80)) - switch ((dev->ld_regs[6][dev->cur_reg] >> 4) & 0x07) { - default: - case 0x00: - nvr_bank_set(0, 0xff, dev->nvr); - nvr_bank_set(1, 1, dev->nvr); - break; - case 0x01: - nvr_bank_set(0, 0, dev->nvr); - nvr_bank_set(1, 1, dev->nvr); - break; - case 0x02: - case 0x04: - nvr_bank_set(0, 0xff, dev->nvr); - nvr_bank_set(1, 0xff, dev->nvr); - break; - case 0x03: - case 0x05: - nvr_bank_set(0, 0, dev->nvr); - nvr_bank_set(1, 0xff, dev->nvr); - break; - case 0x06: - nvr_bank_set(0, 0xff, dev->nvr); - nvr_bank_set(1, 2, dev->nvr); - break; - case 0x07: - nvr_bank_set(0, 0, dev->nvr); - nvr_bank_set(1, 2, dev->nvr); - break; - } - else { - nvr_bank_set(0, 0, dev->nvr); - if (dev->chip_id != 0x02) - nvr_bank_set(1, 0xff, dev->nvr); - } - - fdc37c93x_nvr_pri_handler(dev); - if (dev->chip_id != 0x02) - fdc37c93x_nvr_sec_handler(dev); - } - break; - - default: - break; - } - break; - case 7: - /* Keyboard */ - switch (dev->cur_reg) { - case 0x30: - if (valxor) - fdc37c93x_kbc_handler(dev); - break; - - default: - break; - } - break; - case 8: - /* Auxiliary I/O */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if (valxor) - fdc37c93x_auxio_handler(dev); - break; - - default: - break; - } - break; - case 9: - /* Access bus (FDC37C932FR and FDC37C931APM only) */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x70: - if ((dev->cur_reg == 0x30) && (val & 0x01)) - dev->regs[0x22] |= 0x40; - if (valxor) + if ((dev->chip_id >= FDC37C93X_FR) && (valxor & 0x40)) fdc37c93x_access_bus_handler(dev); break; + case 0x23: + if (dev->chip_id >= FDC37C93X_FR) + dev->regs[dev->cur_reg] = val & 0x7f; + else + dev->regs[dev->cur_reg] = val & 0x6f; + break; + case 0x24: + if (dev->chip_id >= FDC37C93X_FR) + dev->regs[dev->cur_reg] = val & 0xcf; + else + dev->regs[dev->cur_reg] = val & 0xcc; + + if ((dev->chip_id >= FDC37C93X_FR) && (valxor & 0x01)) { + serial_set_clock_src(dev->uart[0], (val & 0x01) ? + 48000000.0 : 24000000.0); + serial_set_clock_src(dev->uart[1], (val & 0x01) ? + 48000000.0 : 24000000.0); + } + break; + case 0x27: + if (dev->chip_id >= FDC37C93X_FR) { + dev->regs[dev->cur_reg] = val; + + fdc37c93x_superio_handler(dev); + } + break; + case 0x28: + if (dev->chip_id >= FDC37C93X_FR) + dev->regs[dev->cur_reg] = val & 0x1f; + break; default: break; } - break; - case 10: - /* Access bus (FDC37C931APM only) */ - switch (dev->cur_reg) { - case 0x30: - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x70: - if (valxor) - fdc37c93x_acpi_handler(dev); - break; + } else { + valxor = val ^ dev->ld_regs[dev->regs[7]][dev->cur_reg]; - default: + if ((dev->regs[7] <= dev->max_ld) && ((dev->regs[7] != 0x08) || + (dev->cur_reg < 0xb0) || (dev->cur_reg > 0xdf) || + (dev->chip_id >= FDC37C93X_FR))) switch (dev->regs[7]) { + case 0x00: /* FDD */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + case 0x74: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x01; + if (valxor) + fdc37c93x_fdc_handler(dev); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x1f; + + if (valxor & 0x01) + fdc_update_enh_mode(dev->fdc, val & 0x01); + if (valxor & 0x0c) { + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); + switch (val & 0x0c) { + case 0x00: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2); + break; + case 0x04: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA); + break; + } + fdc_update_enh_mode(dev->fdc, val & 0x01); + } + if (valxor & 0x10) + fdc_set_swap(dev->fdc, (val & 0x10) >> 4); + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xfc; + + if (valxor & 0x0c) + fdc_update_densel_force(dev->fdc, (val & 0xc) >> 2); + break; + case 0xf2: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor & 0xc0) + fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); + if (valxor & 0x30) + fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); + if (valxor & 0x0c) + fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); + if (valxor & 0x03) + fdc_update_rwc(dev->fdc, 0, (val & 0x03)); + break; + case 0xf4 ... 0xf7: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x5b; + + if (valxor & 0x18) + fdc_update_drvrate(dev->fdc, dev->cur_reg - 0xf4, + (val & 0x18) >> 3); + break; + } + break; + case 0x01: /* IDE1 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x02; + break; + case 0xf0: case 0xf1: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x1f; + else if (dev->cur_reg == 0xf0) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + } + break; + case 0x02: /* IDE2 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x04; + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x01; + break; + } + break; + case 0x03: /* Parallel Port */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + case 0x74: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x08; + if (valxor) + fdc37c93x_lpt_handler(dev); + break; + /* + Bits 2:0: Mode: + - 000: Bi-directional (SPP); + - 001: EPP-1.9 and SPP; + - 010: ECP; + - 011: ECP and EPP-1.9; + - 101: EPP-1.7 and SPP; + - 110: ECP and EPP-1.7. + Bits 6:3: ECP FIFO Threshold. + */ + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + if (valxor & 0x7f) + fdc37c93x_lpt_handler(dev); + break; + case 0xf1: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + break; + } + break; + case 0x04: /* Serial port 1 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x10; + if (valxor) + fdc37c93x_serial_handler(dev, 0); + break; + case 0xf0: + if (dev->chip_id >= FDC37C93X_FR) { + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x83; + } else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + + if (valxor & 0x83) { + fdc37c93x_serial_handler(dev, 0); + fdc37c93x_serial_handler(dev, 1); + } + break; + } + break; + case 0x05: /* Serial port 2 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + case 0x74: + if (((dev->cur_reg != 0x62) && (dev->cur_reg != 0x63)) || + (dev->chip_id == FDC37C93X_FR)) { + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x20; + if (valxor) + fdc37c93x_serial_handler(dev, 1); + } + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + + if (valxor & 0x03) { + fdc37c93x_serial_handler(dev, 0); + fdc37c93x_serial_handler(dev, 1); + } + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x7f; + break; + case 0xf2: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + } + break; + case 0x06: /* RTC */ + switch (dev->cur_reg) { + case 0x30: + // case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + if (((dev->cur_reg != 0x62) && (dev->cur_reg != 0x63)) || + (dev->chip_id >= FDC37C93X_FR)) { + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) { + fdc37c93x_nvr_pri_handler(dev); + + if (dev->chip_id >= FDC37C93X_FR) + fdc37c93x_nvr_sec_handler(dev); + } + } + break; + case 0xf0: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x8f; + + if (valxor) { + nvr_lock_set(0x80, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x01), dev->nvr); + nvr_lock_set(0xa0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x02), dev->nvr); + nvr_lock_set(0xc0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x04), dev->nvr); + nvr_lock_set(0xe0, 0x20, !!(dev->ld_regs[6][dev->cur_reg] & 0x08), dev->nvr); + if (dev->ld_regs[6][dev->cur_reg] & 0x80) { + if (dev->chip_id == FDC37C93X_NORMAL) + nvr_bank_set(0, 1, dev->nvr); + else switch ((dev->ld_regs[6][dev->cur_reg] >> 4) & 0x07) { + case 0x00: + default: + nvr_bank_set(0, 0xff, dev->nvr); + nvr_bank_set(1, 1, dev->nvr); + break; + case 0x01: + nvr_bank_set(0, 0, dev->nvr); + nvr_bank_set(1, 1, dev->nvr); + break; + case 0x02: case 0x04: + nvr_bank_set(0, 0xff, dev->nvr); + nvr_bank_set(1, 0xff, dev->nvr); + break; + case 0x03: case 0x05: + nvr_bank_set(0, 0, dev->nvr); + nvr_bank_set(1, 0xff, dev->nvr); + break; + case 0x06: + nvr_bank_set(0, 0xff, dev->nvr); + nvr_bank_set(1, 2, dev->nvr); + break; + case 0x07: + nvr_bank_set(0, 0, dev->nvr); + nvr_bank_set(1, 2, dev->nvr); + break; + } + } else { + nvr_bank_set(0, 0, dev->nvr); + if (dev->chip_id >= FDC37C93X_FR) + nvr_bank_set(1, 0xff, dev->nvr); + } + + fdc37c93x_nvr_pri_handler(dev); + if (dev->chip_id >= FDC37C93X_FR) + fdc37c93x_nvr_sec_handler(dev); + } + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x1f; + break; + case 0xf2: case 0xf3: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xf4: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x83; + break; + } + break; + case 0x07: /* Keyboard */ + switch (dev->cur_reg) { + case 0x30: + case 0x70: case 0x72: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) + fdc37c93x_kbc_handler(dev); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x87; + break; + } + break; + case 0x08: /* Aux. I/O */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) + fdc37c93x_auxio_handler(dev); + break; + case 0xb0: case 0xb2: + case 0xb4: case 0xb6: + case 0xe0: case 0xe1: + case 0xe9: case 0xf2: + case 0xf3: + case 0xc0 ... 0xc9: + case 0xcb ... 0xcc: + case 0xd0 ... 0xdf: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xb1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xd3; + break; + case 0xb3: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x17; + break; + case 0xb5: + if (dev->chip_id == FDC37C93X_APM) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xbf; + break; + case 0xb7: + if (dev->chip_id == FDC37C93X_APM) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x7f; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x3f; + break; + case 0xb8: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x3f; + break; + case 0x18: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x18; + break; + case 0xe2 ... 0xe5: + case 0xe7: + case 0xeb ... 0xed: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x0f; + break; + case 0xe6: case 0xe8: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x1f; + break; + case 0xea: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x9f; + break; + case 0xef: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xf8; + break; + case 0xf1: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x83; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + break; + case 0xf4: + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xef; + else + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x0f; + break; + case 0xf6: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, 1, i, val & (1 << i)); + break; + case 0xf7: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, 2, i, val & (1 << i)); + break; + case 0xf8: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, 4, i, val & (1 << i)); + break; + case 0xf9: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, 5, i, val & (1 << i)); + break; + case 0xfa: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, 6, i, val & (1 << i)); + break; + case 0xfb: + if (dev->chip_id >= FDC37C93X_FR) + for (uint8_t i = 0; i < 8; i++) + fdc37c93x_write_gp(dev, 7, i, val & (1 << i)); + break; + } + break; + case 0x09: /* Access.Bus */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x40; + if (valxor) + fdc37c93x_access_bus_handler(dev); + break; + } + break; + case 0x0a: /* ACPI */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) + fdc37c93x_acpi_handler(dev); + break; + } break; } - break; - - default: - break; + } } } @@ -764,10 +1594,56 @@ fdc37c93x_read(uint16_t port, void *priv) ret = dev->chip_id; else ret = dev->regs[dev->cur_reg]; - } else { - if ((dev->regs[7] == 0) && (dev->cur_reg == 0xF2)) { - ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); - } else + } else if (dev->regs[7] <= dev->max_ld) { + if ((dev->regs[7] == 0x00) && (dev->cur_reg == 0xf2)) + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | + (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); + else if ((dev->regs[7] == 0x08) && (dev->cur_reg >= 0xf6) && + (dev->cur_reg <= 0xfb) && + (dev->chip_id >= FDC37C93X_FR)) switch (dev->cur_reg) { + case 0xf6: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, 1, i); + } + break; + case 0xf7: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, 2, i); + } + break; + case 0xf8: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, 4, i); + } + break; + case 0xf9: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, 5, i); + } + break; + case 0xfa: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, 6, i); + } + break; + case 0xfb: + if (dev->chip_id >= FDC37C93X_FR) { + ret = 0x00; + for (uint8_t i = 0; i < 8; i++) + ret |= fdc37c93x_read_gp(dev, 7, i); + } + break; + } else if ((dev->regs[7] != 0x06) || (dev->cur_reg != 0xf3)) ret = dev->ld_regs[dev->regs[7]][dev->cur_reg]; } } @@ -777,8 +1653,10 @@ fdc37c93x_read(uint16_t port, void *priv) } static void -fdc37c93x_reset(fdc37c93x_t *dev) +fdc37c93x_reset(void *priv) { + fdc37c93x_t *dev = (fdc37c93x_t *) priv; + memset(dev->regs, 0x00, sizeof(dev->regs)); dev->regs[0x03] = 0x03; @@ -786,10 +1664,12 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->regs[0x21] = 0x01; dev->regs[0x22] = 0x39; dev->regs[0x24] = 0x04; - dev->regs[0x26] = dev->port_370 ? 0x70 : 0xf0; + if (dev->chip_id >= FDC37C93X_FR) + dev->regs[0x26] = dev->port_370 ? 0x70 : 0xf0; dev->regs[0x27] = 0x03; - memset(dev->ld_regs, 0x00, sizeof(dev->ld_regs)); + for (uint8_t i = 0; i <= 0x0a; i++) + memset(dev->ld_regs[i], 0x00, 256); /* Logical device 0: FDD */ dev->ld_regs[0x00][0x30] = 0x00; @@ -807,7 +1687,8 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->ld_regs[0x01][0x62] = 0x03; dev->ld_regs[0x01][0x63] = 0xf6; dev->ld_regs[0x01][0x70] = 0x0e; - dev->ld_regs[0x01][0xf0] = 0x0c; + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[0x01][0xf0] = 0x0c; /* Logical device 2: IDE2 */ dev->ld_regs[0x02][0x30] = 0x00; @@ -840,7 +1721,8 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->ld_regs[0x05][0x70] = 0x03; dev->ld_regs[0x05][0x74] = 0x04; dev->ld_regs[0x05][0xf1] = 0x02; - dev->ld_regs[0x05][0xf2] = 0x03; + if (dev->chip_id >= FDC37C93X_FR) + dev->ld_regs[0x05][0xf2] = 0x03; serial_irq(dev->uart[1], dev->ld_regs[5][0x70]); /* Logical device 6: RTC */ @@ -853,21 +1735,40 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->ld_regs[0x07][0x30] = 0x00; dev->ld_regs[0x07][0x61] = 0x60; dev->ld_regs[0x07][0x70] = 0x01; + dev->ld_regs[0x07][0x72] = 0x0c; /* Logical device 8: Auxiliary I/O */ dev->ld_regs[0x08][0x30] = 0x00; dev->ld_regs[0x08][0x60] = 0x00; dev->ld_regs[0x08][0x61] = 0x00; + if (dev->chip_id >= FDC37C93X_FR) { + dev->ld_regs[0x08][0xb1] = 0x80; + dev->ld_regs[0x08][0xc0] = 0x01; + dev->ld_regs[0x08][0xc1] = 0x01; + dev->ld_regs[0x08][0xc5] = 0x01; + dev->ld_regs[0x08][0xc6] = 0x01; + dev->ld_regs[0x08][0xc7] = 0x01; + dev->ld_regs[0x08][0xc8] = 0x01; + dev->ld_regs[0x08][0xc9] = 0x80; + dev->ld_regs[0x08][0xcb] = 0x01; + dev->ld_regs[0x08][0xcc] = 0x01; + memset(&(dev->ld_regs[0x08][0xd0]), 0x01, 16); + } + memset(&(dev->ld_regs[0x08][0xe0]), 0x01, 14); /* Logical device 9: ACCESS.bus */ - dev->ld_regs[0x09][0x30] = 0x00; - dev->ld_regs[0x09][0x60] = 0x00; - dev->ld_regs[0x09][0x61] = 0x00; + if (dev->chip_id >= FDC37C93X_FR) { + dev->ld_regs[0x09][0x30] = 0x00; + dev->ld_regs[0x09][0x60] = 0x00; + dev->ld_regs[0x09][0x61] = 0x00; + } /* Logical device A: ACPI */ - dev->ld_regs[0x0a][0x30] = 0x00; - dev->ld_regs[0x0a][0x60] = 0x00; - dev->ld_regs[0x0a][0x61] = 0x00; + if (dev->chip_id == FDC37C93X_APM) { + dev->ld_regs[0x0a][0x30] = 0x00; + dev->ld_regs[0x0a][0x60] = 0x00; + dev->ld_regs[0x0a][0x61] = 0x00; + } fdc37c93x_gpio_handler(dev); fdc37c93x_lpt_handler(dev); @@ -879,7 +1780,9 @@ fdc37c93x_reset(fdc37c93x_t *dev) if (dev->is_apm) fdc37c93x_acpi_handler(dev); + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); fdc_reset(dev->fdc); + fdc37c93x_fdc_handler(dev); if (dev->has_nvr) { @@ -899,6 +1802,57 @@ fdc37c93x_reset(fdc37c93x_t *dev) if (dev->chip_id != 0x02) fdc37c93x_superio_handler(dev); + memset(dev->gpio_regs, 0xff, 256); + memset(dev->gpio_pulldn, 0xff, 8); + + /* Acer V62X requires bit 0 to be clear to not be stuck in "clear password" mode. */ + if (!strcmp(machine_get_internal_name(), "vectra54")) { + dev->gpio_pulldn[1] = 0x40; + + /* + HP Vectra VL/5 Series 4 GPIO + (TODO: Find how multipliers > 3.0 are defined): + + Bit 6: 1 = can boot, 0 = no; + Bit 7, 1 = multiplier (00 = 2.5, 01 = 2.0, + 10 = 3.0, 11 = 1.5); + Bit 5, 4 = bus speed (00 = 50 MHz, 01 = 66 MHz, + 10 = 60 MHz, 11 = ????): + Bit 7, 5, 4, 1: 0000 = 125 MHz, 0010 = 166 MHz, + 0100 = 150 MHz, 0110 = ??? MHz; + 0001 = 100 MHz, 0011 = 133 MHz, + 0101 = 120 MHz, 0111 = ??? MHz; + 1000 = 150 MHz, 1010 = 200 MHz, + 1100 = 180 MHz, 1110 = ??? MHz; + 1001 = 75 MHz, 1011 = 100 MHz, + 1101 = 90 MHz, 1111 = ??? MHz + */ + if (cpu_busspeed <= 40000000) + dev->gpio_pulldn[1] |= 0x30; + else if ((cpu_busspeed > 40000000) && (cpu_busspeed <= 50000000)) + dev->gpio_pulldn[1] |= 0x00; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + dev->gpio_pulldn[1] |= 0x20; + else if (cpu_busspeed > 60000000) + dev->gpio_pulldn[1] |= 0x10; + + if (cpu_dmulti <= 1.5) + dev->gpio_pulldn[1] |= 0x82; + else if ((cpu_dmulti > 1.5) && (cpu_dmulti <= 2.0)) + dev->gpio_pulldn[1] |= 0x02; + else if ((cpu_dmulti > 2.0) && (cpu_dmulti <= 2.5)) + dev->gpio_pulldn[1] |= 0x00; + else if (cpu_dmulti > 2.5) + dev->gpio_pulldn[1] |= 0x80; + } else if (!strcmp(machine_get_internal_name(), "acerv62x")) + dev->gpio_pulldn[1] = 0xfe; + else + dev->gpio_pulldn[1] = (dev->chip_id == 0x30) ? 0xff : 0xfd; + + if (strstr(machine_get_internal_name(), "acer") != NULL) + /* Bit 2 on the Acer V35N is the text/graphics toggle, bits 1 and 3 = ????. */ + dev->gpio_pulldn[2] = 0x10; + dev->locked = 0; } @@ -920,41 +1874,61 @@ fdc37c93x_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); - dev->chip_id = info->local & 0xff; - dev->is_apm = (info->local >> 8) & 0x01; - dev->is_compaq = (info->local >> 8) & 0x02; - dev->has_nvr = !((info->local >> 8) & 0x04); - dev->port_370 = ((info->local >> 8) & 0x08); + dev->lpt = device_add_inst(&lpt_port_device, 1); - dev->gpio_regs[0] = 0xff; -#if 0 - dev->gpio_regs[1] = (info->local == 0x0030) ? 0xff : 0xfd; -#endif - dev->gpio_regs[1] = (dev->chip_id == 0x30) ? 0xff : 0xfd; + dev->chip_id = info->local & FDC37C93X_CHIP_ID; + dev->kbc_type = info->local & FDC37XXXX_KBC; + + dev->is_apm = (dev->chip_id == FDC37C93X_APM); + dev->is_compaq = (dev->kbc_type == FDC37XXX1); + + dev->has_nvr = !(info->local & FDC37C93X_NO_NVR); + dev->port_370 = !!(info->local & FDC37XXXX_370); if (dev->has_nvr) { - dev->nvr = device_add(&at_nvr_device); + dev->nvr = device_add(&amstrad_megapc_nvr_device); nvr_bank_set(0, 0, dev->nvr); nvr_bank_set(1, 0xff, dev->nvr); } - if (dev->is_apm || (dev->chip_id == 0x03)) - dev->access_bus = device_add(&access_bus_device); + dev->max_ld = 8; - if (dev->is_apm) + if (dev->chip_id >= FDC37C93X_FR) { + dev->access_bus = device_add(&access_bus_device); + dev->max_ld++; + } + + if (dev->chip_id == FDC37C93X_APM) { dev->acpi = device_add(&acpi_smc_device); + dev->max_ld++; + } if (dev->is_compaq) { - io_sethandler(0x0ea, 0x0002, - fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); io_sethandler(0x0f9, 0x0001, fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); io_sethandler(0x0fb, 0x0001, fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); } - dev->kbc = device_add(&keyboard_ps2_ami_pci_device); + switch (dev->kbc_type) { + case FDC37XXX1: + dev->kbc = device_add(&kbc_ps2_compaq_device); + break; + case FDC37XXX2: + dev->kbc = device_add(&kbc_ps2_intel_ami_pci_device); + break; + case FDC37XXX3: + default: + dev->kbc = device_add(&kbc_ps2_pci_device); + break; + case FDC37XXX5: + dev->kbc = device_add(&kbc_ps2_phoenix_device); + break; + case FDC37XXX7: + dev->kbc = device_add(&kbc_ps2_phoenix_pci_device); + break; + } /* Set the defaults here so the ports can be removed by fdc37c93x_reset(). */ dev->fdc_base = 0x03f0; @@ -978,112 +1952,14 @@ fdc37c93x_init(const device_t *info) return dev; } -const device_t fdc37c931apm_device = { - .name = "SMC FDC37C931APM Super I/O", - .internal_name = "fdc37c931apm", +const device_t fdc37c93x_device = { + .name = "SMC FDC37C93x Super I/O", + .internal_name = "fdc37c93x", .flags = 0, - .local = 0x130, /* Share the same ID with the 932QF. */ + .local = 0, .init = fdc37c93x_init, .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c931apm_compaq_device = { - .name = "SMC FDC37C931APM Super I/O (Compaq Presario 4500)", - .internal_name = "fdc37c931apm_compaq", - .flags = 0, - .local = 0x330, /* Share the same ID with the 932QF. */ - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c932_device = { - .name = "SMC FDC37C932 Super I/O", - .internal_name = "fdc37c932", - .flags = 0, - .local = 0x02, - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c932fr_device = { - .name = "SMC FDC37C932FR Super I/O", - .internal_name = "fdc37c932fr", - .flags = 0, - .local = 0x03, - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c932qf_device = { - .name = "SMC FDC37C932QF Super I/O", - .internal_name = "fdc37c932qf", - .flags = 0, - .local = 0x30, - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c935_device = { - .name = "SMC FDC37C935 Super I/O", - .internal_name = "fdc37c935", - .flags = 0, - .local = 0x02, - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c935_370_device = { - .name = "SMC FDC37C935 Super I/O (Port 370h)", - .internal_name = "fdc37c935_370", - .flags = 0, - .local = 0x802, - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37c935_no_nvr_device = { - .name = "SMC FDC37C935 Super I/O", - .internal_name = "fdc37c935", - .flags = 0, - .local = 0x402, - .init = fdc37c93x_init, - .close = fdc37c93x_close, - .reset = NULL, + .reset = fdc37c93x_reset, .available = NULL, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/sio/sio_fdc37m60x.c b/src/sio/sio_fdc37m60x.c index 11d2f3349..8d18a1192 100644 --- a/src/sio/sio_fdc37m60x.c +++ b/src/sio/sio_fdc37m60x.c @@ -6,252 +6,531 @@ * * This file is part of the 86Box distribution. * - * Emulation of the SMSC FDC37M60x Super I/O + * Implementation of the SMC FDC37M60x Super I/O Chips. * + * Authors: Miran Grca, * - * - * Authors: Tiseno100 - * - * Copyright 2020 Tiseno100 + * Copyright 2025 Miran Grca. */ -#include -#include +#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/keyboard.h> +#include <86box/pci.h> +#include <86box/pic.h> #include <86box/lpt.h> #include <86box/serial.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/keyboard.h> +#include <86box/machine.h> +#include <86box/apm.h> +#include <86box/plat.h> +#include <86box/plat_unused.h> +#include <86box/video.h> #include <86box/sio.h> - -#define SIO_INDEX_PORT dev->sio_index_port -#define INDEX dev->index - -/* Current Logical Device Number */ -#define CURRENT_LOGICAL_DEVICE dev->regs[0x07] - -/* Global Device Configuration */ -#define ENABLED(ld) dev->device_regs[ld][0x30] -#define BASE_ADDRESS(ld) ((dev->device_regs[ld][0x60] << 8) | (dev->device_regs[ld][0x61])) -#define IRQ(ld) dev->device_regs[ld][0x70] -#define DMA(ld) dev->device_regs[ld][0x74] - -/* Miscellaneous Chip Functionality */ -#define SOFT_RESET (val & 0x01) -#define POWER_CONTROL dev->regs[0x22] - -#ifdef ENABLE_FDC37M60X_LOG -int fdc37m60x_do_log = ENABLE_FDC37M60X_LOG; - -static void -fdc37m60x_log(const char *fmt, ...) -{ - va_list ap; - - if (fdc37m60x_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define fdc37m60x_log(fmt, ...) -#endif +#include "cpu.h" typedef struct fdc37m60x_t { - uint8_t index; - uint8_t regs[256]; - uint8_t device_regs[10][256]; - uint8_t cfg_lock; - uint8_t ide_function; - uint16_t sio_index_port; - - fdc_t *fdc; - serial_t *uart[2]; - + uint8_t is_compaq; + uint8_t max_ld; + uint8_t tries; + uint8_t port_370; + uint8_t regs[48]; + uint8_t ld_regs[11][256]; + uint16_t kbc_type; + uint16_t superio_base; + uint16_t fdc_base; + uint16_t lpt_base; + uint16_t kbc_base; + uint16_t uart_base[2]; + int locked; + int cur_reg; + fdc_t *fdc; + void *kbc; + serial_t *uart[2]; + lpt_t *lpt; } fdc37m60x_t; -static void fdc37m60x_fdc_handler(fdc37m60x_t *dev); -static void fdc37m60x_uart_handler(uint8_t num, fdc37m60x_t *dev); -static void fdc37m60x_lpt_handler(fdc37m60x_t *dev); -static void fdc37m60x_logical_device_handler(fdc37m60x_t *dev); -static void fdc37m60x_reset(void *priv); +static void fdc37m60x_write(uint16_t port, uint8_t val, void *priv); +static uint8_t fdc37m60x_read(uint16_t port, void *priv); -static void -fdc37m60x_write(uint16_t addr, uint8_t val, void *priv) +static uint16_t +make_port_superio(const fdc37m60x_t *dev) { - fdc37m60x_t *dev = (fdc37m60x_t *) priv; + const uint16_t r0 = dev->regs[0x26]; + const uint16_t r1 = dev->regs[0x27]; - if (addr & 1) { - if (!dev->cfg_lock) { - switch (INDEX) { - /* Global Configuration */ - case 0x02: - dev->regs[INDEX] = val; - if (SOFT_RESET) - fdc37m60x_reset(dev); - break; + const uint16_t p = (r1 << 8) + r0; - case 0x07: - CURRENT_LOGICAL_DEVICE = val; - break; - - case 0x22: - POWER_CONTROL = val & 0x3f; - break; - - case 0x23: - dev->regs[INDEX] = val & 0x3f; - break; - - case 0x24: - dev->regs[INDEX] = val & 0x4e; - break; - - case 0x2b: - case 0x2c: - case 0x2d: - case 0x2e: - case 0x2f: - dev->regs[INDEX] = val; - break; - - /* Device Configuration */ - case 0x30: - case 0x60: - case 0x61: - case 0x70: - case 0x74: - case 0xf0: - case 0xf1: - case 0xf2: - case 0xf3: - case 0xf4: - case 0xf5: - case 0xf6: - case 0xf7: - if (CURRENT_LOGICAL_DEVICE <= 0x81) /* Avoid Overflow */ - dev->device_regs[CURRENT_LOGICAL_DEVICE][INDEX] = (INDEX == 0x30) ? (val & 1) : val; - fdc37m60x_logical_device_handler(dev); - break; - - default: - break; - } - } - } else { - /* Enter/Escape Configuration Mode */ - if (val == 0x55) - dev->cfg_lock = 0; - else if (!dev->cfg_lock && (val == 0xaa)) - dev->cfg_lock = 1; - else if (!dev->cfg_lock) - INDEX = val; - } + return p; } -static uint8_t -fdc37m60x_read(uint16_t addr, void *priv) +static uint16_t +make_port(const fdc37m60x_t *dev, const uint8_t ld) { - const fdc37m60x_t *dev = (fdc37m60x_t *) priv; - uint8_t ret = 0xff; + const uint16_t r0 = dev->ld_regs[ld][0x60]; + const uint16_t r1 = dev->ld_regs[ld][0x61]; - if (addr & 1) - ret = (INDEX >= 0x30) ? dev->device_regs[CURRENT_LOGICAL_DEVICE][INDEX] : dev->regs[INDEX]; + const uint16_t p = (r0 << 8) + r1; - return ret; + return p; +} + +static void +fdc37m60x_superio_handler(fdc37m60x_t *dev) +{ + if (!dev->is_compaq) { + if (dev->superio_base != 0x0000) + io_removehandler(dev->superio_base, 0x0002, + fdc37m60x_read, NULL, NULL, fdc37m60x_write, NULL, NULL, dev); + dev->superio_base = make_port_superio(dev); + if (dev->superio_base != 0x0000) + io_sethandler(dev->superio_base, 0x0002, + fdc37m60x_read, NULL, NULL, fdc37m60x_write, NULL, NULL, dev); + } } static void fdc37m60x_fdc_handler(fdc37m60x_t *dev) { - fdc_remove(dev->fdc); + const uint8_t global_enable = !!(dev->regs[0x22] & (1 << 0)); + const uint8_t local_enable = !!dev->ld_regs[0][0x30]; + const uint16_t old_base = dev->fdc_base; - if (ENABLED(0) || (POWER_CONTROL & 0x01)) { - fdc_set_base(dev->fdc, BASE_ADDRESS(0)); - fdc_set_irq(dev->fdc, IRQ(0) & 0xf); - fdc_set_dma_ch(dev->fdc, DMA(0) & 0x07); - fdc37m60x_log("SMC60x-FDC: BASE %04x IRQ %d DMA %d\n", BASE_ADDRESS(0), IRQ(0) & 0xf, DMA(0) & 0x07); + dev->fdc_base = 0x0000; + + if (global_enable && local_enable) + dev->fdc_base = make_port(dev, 0) & 0xfff8; + + if (dev->fdc_base != old_base) { + if ((old_base >= 0x0100) && (old_base <= 0x0ff8)) + fdc_remove(dev->fdc); + + if ((dev->fdc_base >= 0x0100) && (dev->fdc_base <= 0x0ff8)) + fdc_set_base(dev->fdc, dev->fdc_base); } - - fdc_update_enh_mode(dev->fdc, dev->device_regs[0][0xf0] & 0x01); - - fdc_update_densel_force(dev->fdc, (dev->device_regs[0][0xf1] & 0xc) >> 2); - - fdc_update_rwc(dev->fdc, 3, (dev->device_regs[0][0xf2] & 0xc0) >> 6); - fdc_update_rwc(dev->fdc, 2, (dev->device_regs[0][0xf2] & 0x30) >> 4); - fdc_update_rwc(dev->fdc, 1, (dev->device_regs[0][0xf2] & 0x0c) >> 2); - fdc_update_rwc(dev->fdc, 0, (dev->device_regs[0][0xf2] & 0x03)); - - fdc_update_drvrate(dev->fdc, 0, (dev->device_regs[0][0xf4] & 0x18) >> 3); - fdc_update_drvrate(dev->fdc, 1, (dev->device_regs[0][0xf5] & 0x18) >> 3); - fdc_update_drvrate(dev->fdc, 2, (dev->device_regs[0][0xf6] & 0x18) >> 3); - fdc_update_drvrate(dev->fdc, 3, (dev->device_regs[0][0xf7] & 0x18) >> 3); } static void -fdc37m60x_uart_handler(uint8_t num, fdc37m60x_t *dev) -{ - serial_remove(dev->uart[num & 1]); - - if (ENABLED(4 + (num & 1)) || (POWER_CONTROL & (1 << (4 + (num & 1))))) { - serial_setup(dev->uart[num & 1], BASE_ADDRESS(4 + (num & 1)), IRQ(4 + (num & 1)) & 0xf); - fdc37m60x_log("SMC60x-UART%d: BASE %04x IRQ %d\n", num & 1, BASE_ADDRESS(4 + (num & 1)), IRQ(4 + (num & 1)) & 0xf); - } -} - -void fdc37m60x_lpt_handler(fdc37m60x_t *dev) { - lpt1_remove(); + uint16_t ld_port = 0x0000; + uint16_t mask = 0xfffc; + uint8_t global_enable = !!(dev->regs[0x22] & (1 << 3)); + uint8_t local_enable = !!dev->ld_regs[3][0x30]; + uint8_t lpt_irq = dev->ld_regs[3][0x70]; + uint8_t lpt_dma = dev->ld_regs[3][0x74]; + uint8_t lpt_mode = dev->ld_regs[3][0xf0] & 0x07; - if (ENABLED(3) || (POWER_CONTROL & 0x08)) { - lpt1_setup(BASE_ADDRESS(3)); - lpt1_irq(IRQ(3) & 0xf); - fdc37m60x_log("SMC60x-LPT: BASE %04x IRQ %d\n", BASE_ADDRESS(3), IRQ(3) & 0xf); + if (lpt_irq > 15) + lpt_irq = 0xff; + + if (lpt_dma >= 4) + lpt_dma = 0xff; + + lpt_port_remove(dev->lpt); + lpt_set_fifo_threshold(dev->lpt, (dev->ld_regs[3][0xf0] & 0x78) >> 3); + switch (lpt_mode) { + default: + case 0x04: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x00: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 1); + break; + case 0x01: case 0x05: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x02: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + case 0x03: case 0x07: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; } + if (global_enable && local_enable) { + ld_port = (make_port(dev, 3) & 0xfffc) & mask; + if ((ld_port >= 0x0100) && (ld_port <= (0x0ffc & mask))) + lpt_port_setup(dev->lpt, ld_port); + } + lpt_port_irq(dev->lpt, lpt_irq); + lpt_port_dma(dev->lpt, lpt_dma); } -void -fdc37m60x_logical_device_handler(fdc37m60x_t *dev) +static void +fdc37m60x_serial_handler(fdc37m60x_t *dev, const int uart) { - /* Register 07h: - Device 0: FDC - Device 3: LPT - Device 4: UART1 - Device 5: UART2 - */ + const uint8_t uart_no = 4 + uart; + const uint8_t global_enable = !!(dev->regs[0x22] & (1 << uart_no)); + const uint8_t local_enable = !!dev->ld_regs[uart_no][0x30]; + const uint16_t old_base = dev->uart_base[uart]; + double clock_src = 24000000.0 / 13.0; - switch (CURRENT_LOGICAL_DEVICE) { + dev->uart_base[uart] = 0x0000; + + if (global_enable && local_enable) + dev->uart_base[uart] = make_port(dev, uart_no) & 0xfff8; + + if (dev->uart_base[uart] != old_base) { + if ((old_base >= 0x0100) && (old_base <= 0x0ff8)) + serial_remove(dev->uart[uart]); + + if ((dev->uart_base[uart] >= 0x0100) && (dev->uart_base[uart] <= 0x0ff8)) + serial_setup(dev->uart[uart], dev->uart_base[uart], dev->ld_regs[uart_no][0x70]); + } + + switch (dev->ld_regs[uart_no][0xf0] & 0x03) { case 0x00: - fdc37m60x_fdc_handler(dev); + clock_src = 24000000.0 / 13.0; + break; + case 0x01: + clock_src = 24000000.0 / 12.0; + break; + case 0x02: + clock_src = 24000000.0 / 1.0; break; - case 0x03: - fdc37m60x_lpt_handler(dev); - break; - - case 0x04: - fdc37m60x_uart_handler(0, dev); - break; - - case 0x05: - fdc37m60x_uart_handler(1, dev); + clock_src = 24000000.0 / 1.625; break; default: break; } + + serial_set_clock_src(dev->uart[uart], clock_src); + + /* + TODO: If UART 2's own IRQ pin is also enabled when shared, + it should also be asserted. + */ + if (dev->ld_regs[4][0xf0] & 0x80) { + serial_irq(dev->uart[0], dev->ld_regs[4][0x70]); + serial_irq(dev->uart[1], dev->ld_regs[4][0x70]); + } else + serial_irq(dev->uart[uart], dev->ld_regs[uart_no][0x70]); +} + +static void +fdc37m60x_kbc_handler(fdc37m60x_t *dev) +{ + const uint8_t local_enable = !!dev->ld_regs[7][0x30]; + const uint16_t old_base = dev->kbc_base; + + dev->kbc_base = local_enable ? 0x0060 : 0x0000; + + if (dev->kbc_base != old_base) + kbc_at_handler(local_enable, dev->kbc_base, dev->kbc); + + kbc_at_set_irq(0, dev->ld_regs[7][0x70], dev->kbc); + kbc_at_set_irq(1, dev->ld_regs[7][0x72], dev->kbc); +} + +static void +fdc37m60x_state_change(fdc37m60x_t *dev, const uint8_t locked) +{ + dev->locked = locked; + fdc_3f1_enable(dev->fdc, !locked); +} + +static void +fdc37m60x_write(uint16_t port, uint8_t val, void *priv) +{ + fdc37m60x_t *dev = (fdc37m60x_t *) priv; + uint8_t index = !(port & 1); + uint8_t valxor; + + if (port == 0x00fb) { + fdc37m60x_state_change(dev, 1); + dev->tries = 0; + } else if (port == 0x00f9) + fdc37m60x_state_change(dev, 0); + else if (index) { + if ((!dev->is_compaq) && (val == 0x55) && !dev->locked) { + fdc37m60x_state_change(dev, 1); + dev->tries = 0; + } else if (dev->locked) { + if ((!dev->is_compaq) && (val == 0xaa)) + fdc37m60x_state_change(dev, 0); + else + dev->cur_reg = val; + } else if ((!dev->is_compaq) && dev->tries) + dev->tries = 0; + } else if (dev->locked) { + if (dev->cur_reg < 0x30) { + valxor = val ^ dev->regs[dev->cur_reg]; + + switch (dev->cur_reg) { + case 0x02: + dev->regs[dev->cur_reg] = val; + if (val == 0x02) + fdc37m60x_state_change(dev, 0); + break; + case 0x07: case 0x26: + case 0x2b ... 0x2f: + dev->regs[dev->cur_reg] = val; + break; + case 0x22: + dev->regs[dev->cur_reg] = val & 0x39; + + if (valxor & 0x01) + fdc37m60x_fdc_handler(dev); + if (valxor & 0x08) + fdc37m60x_lpt_handler(dev); + if (valxor & 0x10) + fdc37m60x_serial_handler(dev, 0); + if (valxor & 0x20) + fdc37m60x_serial_handler(dev, 1); + break; + case 0x23: + dev->regs[dev->cur_reg] = val & 0x39; + break; + case 0x24: + dev->regs[dev->cur_reg] = val & 0x4e; + break; + case 0x27: + dev->regs[dev->cur_reg] = val; + fdc37m60x_superio_handler(dev); + break; + default: + break; + } + } else { + valxor = val ^ dev->ld_regs[dev->regs[7]][dev->cur_reg]; + + if (dev->regs[7] <= dev->max_ld) switch (dev->regs[7]) { + case 0x00: /* FDD */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + case 0x74: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x01; + if (valxor) + fdc37m60x_fdc_handler(dev); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xef; + + if (valxor & 0x01) + fdc_update_enh_mode(dev->fdc, val & 0x01); + if (valxor & 0x0c) { + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); + switch (val & 0x0c) { + case 0x00: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2); + break; + case 0x04: + fdc_set_flags(dev->fdc, FDC_FLAG_PS2_MCA); + break; + } + fdc_update_enh_mode(dev->fdc, val & 0x01); + } + if (valxor & 0x10) + fdc_set_swap(dev->fdc, (val & 0x10) >> 4); + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0xfc; + + if (valxor & 0x0c) + fdc_update_densel_force(dev->fdc, (val & 0xc) >> 2); + break; + case 0xf2: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor & 0xc0) + fdc_update_rwc(dev->fdc, 3, (val & 0xc0) >> 6); + if (valxor & 0x30) + fdc_update_rwc(dev->fdc, 2, (val & 0x30) >> 4); + if (valxor & 0x0c) + fdc_update_rwc(dev->fdc, 1, (val & 0x0c) >> 2); + if (valxor & 0x03) + fdc_update_rwc(dev->fdc, 0, (val & 0x03)); + break; + case 0xf4 ... 0xf7: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x5b; + + if (valxor & 0x18) + fdc_update_drvrate(dev->fdc, dev->cur_reg - 0xf4, + (val & 0x18) >> 3); + break; + } + break; + case 0x03: /* Parallel Port */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + case 0x74: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x08; + if (valxor) + fdc37m60x_lpt_handler(dev); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + if (valxor & 0x7f) + fdc37m60x_lpt_handler(dev); + break; + } + break; + case 0x04: /* Serial port 1 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x70: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x10; + if (valxor) + fdc37m60x_serial_handler(dev, 0); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x83; + + if (valxor & 0x83) { + fdc37m60x_serial_handler(dev, 0); + fdc37m60x_serial_handler(dev, 1); + } + break; + } + break; + case 0x05: /* Serial port 2 */ + switch (dev->cur_reg) { + case 0x30: + case 0x60: case 0x61: + case 0x62: case 0x63: + case 0x70: + case 0x74: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x20; + if (valxor) + fdc37m60x_serial_handler(dev, 1); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x03; + + if (valxor & 0x03) { + fdc37m60x_serial_handler(dev, 0); + fdc37m60x_serial_handler(dev, 1); + } + break; + case 0xf1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x7f; + break; + case 0xf2: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + } + break; + case 0x07: /* Keyboard */ + switch (dev->cur_reg) { + case 0x30: + case 0x70: case 0x72: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + + if (valxor) + fdc37m60x_kbc_handler(dev); + break; + case 0xf0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x84; + break; + } + break; + case 0x08: /* Aux. I/O */ + switch (dev->cur_reg) { + case 0x30: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xb8: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val; + break; + case 0xc0: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = (dev->ld_regs[dev->regs[7]][dev->cur_reg] & 0xe4) | (val & 0x1b); + break; + case 0xc1: + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val & 0x0f; + for (int i = 0; i < 4; i++) + fdc_set_fdd_changed(i, !!(val & (1 << i))); + break; + } + break; + } + } + } +} + +static uint8_t +fdc37m60x_read(uint16_t port, void *priv) +{ + fdc37m60x_t *dev = (fdc37m60x_t *) priv; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ret = 0xff; + + /* Compaq Presario 4500: Unlock at FB, Register at EA, Data at EB, Lock at F9. */ + if ((port == 0xea) || (port == 0xf9) || (port == 0xfb)) + index = 1; + else if (port == 0xeb) + index = 0; + + if (dev->locked) { + if (index) + ret = dev->cur_reg; + else { + if (dev->cur_reg < 0x30) { + if (dev->cur_reg == 0x20) + ret = 0x47; + else + ret = dev->regs[dev->cur_reg]; + } else if (dev->regs[7] <= dev->max_ld) { + if ((dev->regs[7] == 0x00) && (dev->cur_reg == 0xf2)) + ret = (fdc_get_rwc(dev->fdc, 0) | (fdc_get_rwc(dev->fdc, 1) << 2) | + (fdc_get_rwc(dev->fdc, 2) << 4) | (fdc_get_rwc(dev->fdc, 3) << 6)); + else if ((dev->regs[7] == 0x08) && (dev->cur_reg == 0xc1)) { + ret = dev->ld_regs[dev->regs[7]][dev->cur_reg] & 0xf0; + for (int i = 0; i < 4; i++) + ret |= (fdc_get_fdd_changed(i) << i); + } else if ((dev->regs[7] == 0x08) && (dev->cur_reg == 0xc2)) + ret = fdc_get_shadow(dev->fdc); + else if ((dev->regs[7] == 0x08) && (dev->cur_reg == 0xc3)) + ret = serial_get_shadow(dev->uart[0]); + else if ((dev->regs[7] == 0x08) && (dev->cur_reg == 0xc4)) + ret = serial_get_shadow(dev->uart[1]); + else if ((dev->regs[7] != 0x06) || (dev->cur_reg != 0xf3)) + ret = dev->ld_regs[dev->regs[7]][dev->cur_reg]; + } + } + } + + return ret; } static void @@ -259,40 +538,80 @@ fdc37m60x_reset(void *priv) { fdc37m60x_t *dev = (fdc37m60x_t *) priv; - memset(dev->regs, 0, sizeof(dev->regs)); - for (uint8_t i = 0; i < 10; i++) - memset(dev->device_regs[i], 0, sizeof(dev->device_regs[i])); + memset(dev->regs, 0x00, sizeof(dev->regs)); dev->regs[0x20] = 0x47; + dev->regs[0x22] = 0x39; dev->regs[0x24] = 0x04; - dev->regs[0x26] = SIO_INDEX_PORT & 0xf; - dev->regs[0x27] = (SIO_INDEX_PORT >> 4) & 0xf; + dev->regs[0x26] = dev->port_370 ? 0x70 : 0xf0; + dev->regs[0x27] = 0x03; - /* FDC Registers */ - dev->device_regs[0][0x60] = 0x03; /* Base Address */ - dev->device_regs[0][0x61] = 0xf0; - dev->device_regs[0][0x70] = 0x06; - dev->device_regs[0][0x74] = 0x02; - dev->device_regs[0][0xf0] = 0x0e; - dev->device_regs[0][0xf2] = 0xff; + for (uint8_t i = 0; i <= 0x0a; i++) + memset(dev->ld_regs[i], 0x00, 256); - /* LPT Port */ - dev->device_regs[3][0x74] = 0x04; - dev->device_regs[3][0xf0] = 0x3c; + /* Logical device 0: FDD */ + dev->ld_regs[0x00][0x30] = 0x00; + dev->ld_regs[0x00][0x60] = 0x03; + dev->ld_regs[0x00][0x61] = 0xf0; + dev->ld_regs[0x00][0x70] = 0x06; + dev->ld_regs[0x00][0x74] = 0x02; + dev->ld_regs[0x00][0xf0] = 0x0e; + dev->ld_regs[0x00][0xf2] = 0xff; - /* UART1 */ - dev->device_regs[4][0x74] = 0x04; - dev->device_regs[4][0xf1] = 0x02; - dev->device_regs[4][0xf2] = 0x03; + /* Logical device 3: Parallel Port */ + dev->ld_regs[0x03][0x30] = 0x00; + dev->ld_regs[0x03][0x60] = 0x03; + dev->ld_regs[0x03][0x61] = 0x78; + dev->ld_regs[0x03][0x70] = 0x07; + dev->ld_regs[0x03][0x74] = 0x04; + dev->ld_regs[0x03][0xf0] = 0x3c; - /* AUX */ - dev->device_regs[8][0xc0] = 0x06; - dev->device_regs[8][0xc1] = 0x03; + /* Logical device 4: Serial Port 1 */ + dev->ld_regs[0x04][0x30] = 0x00; + dev->ld_regs[0x04][0x60] = 0x03; + dev->ld_regs[0x04][0x61] = 0xf8; + dev->ld_regs[0x04][0x70] = 0x04; + serial_irq(dev->uart[0], dev->ld_regs[4][0x70]); + + /* Logical device 5: Serial Port 2 */ + dev->ld_regs[0x05][0x30] = 0x00; + dev->ld_regs[0x05][0x60] = 0x02; + dev->ld_regs[0x05][0x61] = 0xf8; + dev->ld_regs[0x05][0x70] = 0x03; + dev->ld_regs[0x05][0x74] = 0x04; + dev->ld_regs[0x05][0xf1] = 0x02; + dev->ld_regs[0x05][0xf2] = 0x03; + serial_irq(dev->uart[1], dev->ld_regs[5][0x70]); + + /* Logical device 7: Keyboard */ + dev->ld_regs[0x07][0x30] = 0x00; + dev->ld_regs[0x07][0x61] = 0x60; + dev->ld_regs[0x07][0x70] = 0x01; + + /* Logical device 8: Auxiliary I/O */ + dev->ld_regs[0x08][0x30] = 0x00; + dev->ld_regs[0x08][0x60] = 0x00; + dev->ld_regs[0x08][0x61] = 0x00; + dev->ld_regs[0x08][0xc0] = 0x06; + dev->ld_regs[0x08][0xc1] = 0x03; + + fdc37m60x_lpt_handler(dev); + fdc37m60x_serial_handler(dev, 0); + fdc37m60x_serial_handler(dev, 1); + + fdc_clear_flags(dev->fdc, FDC_FLAG_PS2 | FDC_FLAG_PS2_MCA); + fdc_reset(dev->fdc); fdc37m60x_fdc_handler(dev); - fdc37m60x_uart_handler(0, dev); - fdc37m60x_uart_handler(1, dev); - fdc37m60x_lpt_handler(dev); + + for (int i = 0; i < 4; i++) + fdc_set_fdd_changed(i, 1); + + fdc37m60x_kbc_handler(dev); + + fdc37m60x_superio_handler(dev); + + dev->locked = 0; } static void @@ -307,13 +626,54 @@ static void * fdc37m60x_init(const device_t *info) { fdc37m60x_t *dev = (fdc37m60x_t *) calloc(1, sizeof(fdc37m60x_t)); - SIO_INDEX_PORT = info->local; - 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->fdc = device_add(&fdc_at_smc_device); - io_sethandler(SIO_INDEX_PORT, 0x0002, fdc37m60x_read, NULL, NULL, fdc37m60x_write, NULL, NULL, dev); + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->lpt = device_add_inst(&lpt_port_device, 1); + + dev->kbc_type = info->local & FDC37XXXX_KBC; + + dev->is_compaq = (dev->kbc_type == FDC37XXX1); + + dev->port_370 = !!(info->local & FDC37XXXX_370); + + dev->max_ld = 8; + + if (dev->is_compaq) { + io_sethandler(0x0f9, 0x0001, + fdc37m60x_read, NULL, NULL, fdc37m60x_write, NULL, NULL, dev); + io_sethandler(0x0fb, 0x0001, + fdc37m60x_read, NULL, NULL, fdc37m60x_write, NULL, NULL, dev); + } + + switch (dev->kbc_type) { + case FDC37XXX1: + dev->kbc = device_add(&kbc_ps2_compaq_device); + break; + case FDC37XXX2: + dev->kbc = device_add(&kbc_ps2_intel_ami_pci_device); + break; + case FDC37XXX3: + default: + dev->kbc = device_add(&kbc_ps2_pci_device); + break; + case FDC37XXX5: + dev->kbc = device_add(&kbc_ps2_phoenix_device); + break; + case FDC37XXX7: + dev->kbc = device_add(&kbc_ps2_phoenix_pci_device); + break; + } + + /* Set the defaults here so the ports can be removed by fdc37m60x_reset(). */ + dev->fdc_base = 0x03f0; + dev->lpt_base = 0x0378; + dev->uart_base[0] = 0x03f8; + dev->uart_base[1] = 0x02f8; + dev->kbc_base = 0x0060; fdc37m60x_reset(dev); @@ -321,27 +681,13 @@ fdc37m60x_init(const device_t *info) } const device_t fdc37m60x_device = { - .name = "SMSC FDC37M60X", + .name = "SMC FDC37C93x Super I/O", .internal_name = "fdc37m60x", .flags = 0, - .local = FDC_PRIMARY_ADDR, + .local = 0, .init = fdc37m60x_init, .close = fdc37m60x_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc37m60x_370_device = { - .name = "SMSC FDC37M60X with 10K Pull Up Resistor", - .internal_name = "fdc37m60x_370", - .flags = 0, - .local = FDC_SECONDARY_ADDR, - .init = fdc37m60x_init, - .close = fdc37m60x_close, - .reset = NULL, + .reset = fdc37m60x_reset, .available = NULL, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/sio/sio_it86x1f.c b/src/sio/sio_it86x1f.c index b3553bf54..c11b0e6bd 100644 --- a/src/sio/sio_it86x1f.c +++ b/src/sio/sio_it86x1f.c @@ -243,6 +243,7 @@ typedef struct it86x1f_t { fdc_t *fdc; serial_t *uart[2]; + lpt_t *lpt; void *gameport; } it86x1f_t; @@ -290,11 +291,11 @@ it8661f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pri break; case 3: - lpt1_remove(); + lpt_port_remove(dev->lpt); 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_setup(config->io[0].base); + lpt_port_setup(dev->lpt, config->io[0].base); } else { it86x1f_log("IT86x1F: LPT disabled\n"); } @@ -777,7 +778,7 @@ it86x1f_reset(it86x1f_t *dev) serial_remove(dev->uart[1]); - lpt1_remove(); + lpt_port_remove(dev->lpt); isapnp_enable_card(dev->pnp_card, ISAPNP_CARD_DISABLE); @@ -822,6 +823,8 @@ it86x1f_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->lpt = device_add_inst(&lpt_port_device, 1); + dev->gameport = gameport_add(&gameport_sio_device); dev->instance = device_get_instance(); diff --git a/src/sio/sio_pc87306.c b/src/sio/sio_pc87306.c index 41d69b0cc..5b55907dd 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -23,6 +23,7 @@ #include <86box/io.h> #include <86box/timer.h> #include <86box/device.h> +#include <86box/keyboard.h> #include <86box/lpt.h> #include <86box/mem.h> #include <86box/nvr.h> @@ -42,9 +43,12 @@ typedef struct pc87306_t { uint8_t regs[29]; uint8_t gpio[2]; uint16_t gpioba; + uint16_t kbc_type; int cur_reg; fdc_t *fdc; + void *kbc; serial_t *uart[2]; + lpt_t *lpt; nvr_t *nvr; } pc87306_t; @@ -115,12 +119,18 @@ pc87306_gpio_handler(pc87306_t *dev) } static void -lpt1_handler(pc87306_t *dev) +lpt_handler(pc87306_t *dev) { int temp; uint16_t lptba; uint16_t lpt_port = LPT1_ADDR; uint8_t lpt_irq = LPT2_IRQ; + uint8_t lpt_dma = ((dev->regs[0x18] & 0x06) >> 1); + + lpt_port_remove(dev->lpt); + + if (lpt_dma == 0x00) + lpt_dma = 0xff; temp = dev->regs[0x01] & 3; lptba = ((uint16_t) dev->regs[0x19]) << 2; @@ -153,10 +163,17 @@ lpt1_handler(pc87306_t *dev) if (dev->regs[0x1b] & 0x10) lpt_irq = (dev->regs[0x1b] & 0x20) ? 7 : 5; - if (lpt_port) - lpt1_setup(lpt_port); + lpt_set_ext(dev->lpt, !!(dev->regs[0x02] & 0x80)); - lpt1_irq(lpt_irq); + lpt_set_epp(dev->lpt, !!(dev->regs[0x04] & 0x01)); + lpt_set_ecp(dev->lpt, !!(dev->regs[0x04] & 0x04)); + + if (lpt_port) + lpt_port_setup(dev->lpt, lpt_port); + + lpt_port_irq(dev->lpt, lpt_irq); + + lpt_port_dma(dev->lpt, lpt_dma); } static void @@ -169,7 +186,7 @@ serial_handler(pc87306_t *dev, int uart) uint8_t pnp_shift; uint8_t irq; - temp = (dev->regs[1] >> (2 << uart)) & 3; + temp = (dev->regs[0x01] >> (2 << uart)) & 3; fer_shift = 2 << uart; /* 2 for UART 1, 4 for UART 2 */ pnp_shift = 2 + (uart << 2); /* 2 for UART 1, 6 for UART 2 */ @@ -188,7 +205,7 @@ serial_handler(pc87306_t *dev, int uart) serial_setup(dev->uart[uart], COM2_ADDR, irq); break; case 2: - switch ((dev->regs[1] >> 6) & 3) { + switch ((dev->regs[0x01] >> 6) & 3) { case 0: serial_setup(dev->uart[uart], COM3_ADDR, irq); break; @@ -207,7 +224,7 @@ serial_handler(pc87306_t *dev, int uart) } break; case 3: - switch ((dev->regs[1] >> 6) & 3) { + switch ((dev->regs[0x01] >> 6) & 3) { case 0: serial_setup(dev->uart[uart], COM4_ADDR, irq); break; @@ -231,6 +248,15 @@ serial_handler(pc87306_t *dev, int uart) } } +static void +kbc_handler(pc87306_t *dev) +{ + kbc_at_handler(0, 0x0060, dev->kbc); + + if (dev->regs[0x05] & 0x01) + kbc_at_handler(1, 0x0060, dev->kbc); +} + static void pc87306_write(uint16_t port, uint8_t val, void *priv) { @@ -264,54 +290,54 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) switch (dev->cur_reg) { case 0x00: - if (valxor & 1) { - lpt1_remove(); - if ((val & 1) && !(dev->regs[2] & 1)) - lpt1_handler(dev); + if (valxor & 0x01) { + lpt_port_remove(dev->lpt); + if ((val & 1) && !(dev->regs[0x02] & 1)) + lpt_handler(dev); } - if (valxor & 2) { - serial_remove(dev->uart[0]); - if ((val & 2) && !(dev->regs[2] & 1)) + if (valxor & 0x02) { + serial_remove(dev->uart[0x00]); + if ((val & 2) && !(dev->regs[0x02] & 1)) serial_handler(dev, 0); } - if (valxor & 4) { - serial_remove(dev->uart[1]); - if ((val & 4) && !(dev->regs[2] & 1)) + if (valxor & 0x04) { + serial_remove(dev->uart[0x01]); + if ((val & 4) && !(dev->regs[0x02] & 1)) serial_handler(dev, 1); } if (valxor & 0x28) { fdc_remove(dev->fdc); - if ((val & 8) && !(dev->regs[2] & 1)) + if ((val & 8) && !(dev->regs[0x02] & 1)) fdc_set_base(dev->fdc, (val & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); } break; case 0x01: - if (valxor & 3) { - lpt1_remove(); - if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) - lpt1_handler(dev); + if (valxor & 0x03) { + lpt_port_remove(dev->lpt); + if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) + lpt_handler(dev); } if (valxor & 0xcc) { - serial_remove(dev->uart[0]); - if ((dev->regs[0] & 2) && !(dev->regs[2] & 1)) + serial_remove(dev->uart[0x00]); + if ((dev->regs[0x00] & 2) && !(dev->regs[0x02] & 1)) serial_handler(dev, 0); } if (valxor & 0xf0) { - serial_remove(dev->uart[1]); - if ((dev->regs[0] & 4) && !(dev->regs[2] & 1)) + serial_remove(dev->uart[0x01]); + if ((dev->regs[0x00] & 4) && !(dev->regs[0x02] & 1)) serial_handler(dev, 1); } break; case 0x02: if (valxor & 0x01) { - lpt1_remove(); + lpt_port_remove(dev->lpt); serial_remove(dev->uart[0x00]); serial_remove(dev->uart[0x01]); fdc_remove(dev->fdc); if (!(val & 1)) { if (dev->regs[0x00] & 0x01) - lpt1_handler(dev); + lpt_handler(dev); if (dev->regs[0x00] & 0x02) serial_handler(dev, 0); if (dev->regs[0x00] & 0x04) @@ -321,16 +347,23 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) } } if (valxor & 0x08) { - lpt1_remove(); + lpt_port_remove(dev->lpt); if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) - lpt1_handler(dev); + lpt_handler(dev); } break; case 0x04: + if (valxor & (0x05)) { + lpt_port_remove(dev->lpt); + if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01)) + lpt_handler(dev); + } if (valxor & 0x80) nvr_lock_set(0x00, 256, !!(val & 0x80), dev->nvr); break; case 0x05: + if (valxor & 0x01) + kbc_handler(dev); if (valxor & 0x08) nvr_at_handler(!!(val & 0x08), 0x0070, dev->nvr); if (valxor & 0x20) @@ -352,30 +385,37 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) if (valxor & 0x30) pc87306_gpio_handler(dev); break; + case 0x18: + if (valxor & (0x06)) { + lpt_port_remove(dev->lpt); + if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01)) + lpt_handler(dev); + } + break; case 0x19: if (valxor) { - lpt1_remove(); - if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) - lpt1_handler(dev); + lpt_port_remove(dev->lpt); + if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) + lpt_handler(dev); } break; case 0x1b: if (valxor & 0x70) { - lpt1_remove(); + lpt_port_remove(dev->lpt); if (!(val & 0x40)) - dev->regs[0x19] = 0xEF; - if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) - lpt1_handler(dev); + dev->regs[0x19] = 0xef; + if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) + lpt_handler(dev); } break; case 0x1c: if (valxor) { - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); + serial_remove(dev->uart[0x00]); + serial_remove(dev->uart[0x01]); - if ((dev->regs[0] & 2) && !(dev->regs[2] & 1)) + if ((dev->regs[0x00] & 2) && !(dev->regs[0x02] & 1)) serial_handler(dev, 0); - if ((dev->regs[0] & 4) && !(dev->regs[2] & 1)) + if ((dev->regs[0x00] & 4) && !(dev->regs[0x02] & 1)) serial_handler(dev, 1); } break; @@ -430,10 +470,10 @@ pc87306_reset_common(void *priv) 0 = 360 rpm @ 500 kbps for 3.5" 1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5" */ - lpt1_remove(); - lpt1_handler(dev); - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); + lpt_port_remove(dev->lpt); + lpt_handler(dev); + serial_remove(dev->uart[0x00]); + serial_remove(dev->uart[0x01]); serial_handler(dev, 0); serial_handler(dev, 1); fdc_reset(dev->fdc); @@ -469,13 +509,30 @@ pc87306_init(UNUSED(const device_t *info)) { pc87306_t *dev = (pc87306_t *) calloc(1, sizeof(pc87306_t)); + dev->kbc_type = info->local & PCX730X_KBC; + 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[0x00] = device_add_inst(&ns16550_device, 1); + dev->uart[0x01] = device_add_inst(&ns16550_device, 2); + + dev->lpt = device_add_inst(&lpt_port_device, 1); dev->nvr = device_add(&at_mb_nvr_device); + switch (dev->kbc_type) { + case PCX730X_AMI: + default: + dev->kbc = device_add(&kbc_ps2_intel_ami_pci_device); + break; + case PCX730X_PHOENIX_42: + dev->kbc = device_add(&kbc_ps2_phoenix_device); + break; + case PCX730X_PHOENIX_42I: + dev->kbc = device_add(&kbc_ps2_phoenix_pci_device); + break; + } + dev->gpio[0] = dev->gpio[1] = 0xff; pc87306_reset_common(dev); diff --git a/src/sio/sio_pc87307.c b/src/sio/sio_pc87307.c index ae21d34af..72086fb61 100644 --- a/src/sio/sio_pc87307.c +++ b/src/sio/sio_pc87307.c @@ -8,61 +8,106 @@ * * Emulation of the NatSemi PC87307 Super I/O chip. * - * - * * Authors: Miran Grca, * - * Copyright 2020 Miran Grca. + * Copyright 2020-2025 Miran Grca. */ +#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/machine.h> #include <86box/mem.h> #include <86box/nvr.h> #include <86box/pci.h> #include <86box/rom.h> #include <86box/serial.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/keyboard.h> #include <86box/sio.h> #include <86box/plat_fallthrough.h> +#include "cpu.h" typedef struct pc87307_t { uint8_t id; + uint8_t baddr; uint8_t pm_idx; uint8_t regs[48]; uint8_t ld_regs[256][208]; uint8_t pcregs[16]; - uint8_t gpio[2][4]; + uint8_t gpio[2][8]; uint8_t pm[8]; + uint16_t superio_base; uint16_t gpio_base; uint16_t gpio_base2; uint16_t pm_base; int cur_reg; + void *kbc; fdc_t *fdc; serial_t *uart[2]; + lpt_t *lpt; } pc87307_t; -static void fdc_handler(pc87307_t *dev); -static void lpt1_handler(pc87307_t *dev); -static void serial_handler(pc87307_t *dev, int uart); +enum { + LD_KBD = 0, + LD_MOUSE, + LD_RTC, + LD_FDC, + LD_LPT, + LD_UART2, + LD_UART1, + LD_GPIO, + LD_PM +} pc87307_ld_t; + +#define LD_MIN LD_KBD +#define LD_MAX LD_PM + +static void fdc_handler(pc87307_t *dev); +static void lpt_handler(pc87307_t *dev); +static void serial_handler(pc87307_t *dev, int uart); +static void kbc_handler(pc87307_t *dev); +static void pc87307_write(uint16_t port, uint8_t val, void *priv); +static uint8_t pc87307_read(uint16_t port, void *priv); + +#ifdef ENABLE_PC87307_LOG +int pc87307_do_log = ENABLE_PC87307_LOG; + +static void +pc87307_log(const char *fmt, ...) +{ + va_list ap; + + if (pc87307_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define pc87307_log(fmt, ...) +#endif static void pc87307_gpio_write(uint16_t port, uint8_t val, void *priv) { pc87307_t *dev = (pc87307_t *) priv; - uint8_t bank = ((port & 0xfffc) == dev->gpio_base2); + uint8_t bank = !!(dev->regs[0x22] & 0x80); - dev->gpio[bank][port & 3] = val; + /* Bit 7 of SCNF2 = bank. */ + pc87307_log("[%04X:%08X] [W] (%04X) Bank %i = %02X\n", + CS, cpu_state.pc, port, bank, val); + + dev->gpio[bank][port & 0x0007] = val; } uint8_t @@ -70,20 +115,36 @@ pc87307_gpio_read(uint16_t port, void *priv) { 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]; + uint8_t bank = !!(dev->regs[0x22] & 0x80); + uint8_t ret = dev->gpio[bank][port & 0x0007]; switch (port & 0x0003) { case 0x0000: - mask = dev->gpio[bank][0x0001]; - ret = (ret & mask) | (pins & ~mask); + if (bank == 0) { + uint8_t mask = dev->gpio[0][1]; + pins = 0x7f; + ret = (ret & mask) | (pins & ~mask); + } + break; + case 0x0004: + if (bank == 0) { + uint8_t mask = dev->gpio[0][5]; + pins = 0xfb; + ret = (ret & mask) | (pins & ~mask); + } else + ret = 0xff; break; default: + if (bank == 1) + ret = 0xff; break; } + /* Bit 7 of SCNF2 = bank. */ + pc87307_log("[%04X:%08X] [R] (%04X) Bank %i = %02X\n", + CS, cpu_state.pc, port, bank, ret); + return ret; } @@ -123,10 +184,11 @@ pc87307_pm_write(uint16_t port, uint8_t val, void *priv) dev->pm[dev->pm_idx] = val; else { dev->pm_idx = val & 0x07; + switch (dev->pm_idx) { case 0x00: fdc_handler(dev); - lpt1_handler(dev); + lpt_handler(dev); serial_handler(dev, 1); serial_handler(dev, 0); break; @@ -167,290 +229,456 @@ pc87307_pm_init(pc87307_t *dev, uint16_t addr) pc87307_pm_read, NULL, NULL, pc87307_pm_write, NULL, NULL, dev); } +static void +kbc_handler(pc87307_t *dev) +{ + uint8_t active = (dev->ld_regs[LD_KBD][0x00] & 0x01) && + (dev->pm[0x00] & 0x01); + uint8_t active_2 = dev->ld_regs[LD_MOUSE][0x00] & 0x01; + uint8_t irq = (dev->ld_regs[LD_KBD][0x40] & 0x0f); + uint8_t irq_2 = (dev->ld_regs[LD_MOUSE][0x40] & 0x0f); + uint16_t addr = (dev->ld_regs[LD_KBD][0x30] << 8) | + dev->ld_regs[LD_KBD][0x31]; + uint16_t addr_2 = (dev->ld_regs[LD_KBD][0x32] << 8) | + dev->ld_regs[LD_KBD][0x33]; + + pc87307_log("%02X, %02X, %02X, %02X, %04X, %04X\n", + active, active_2, irq, irq_2, addr, addr_2); + + if (addr <= 0xfff8) { + pc87307_log("Enabling KBC #1 on %04X...\n", addr); + kbc_at_port_handler(0, active, addr, dev->kbc); + } + + if (addr_2 <= 0xfff8) { + pc87307_log("Enabling KBC #2 on %04X...\n", addr_2); + kbc_at_port_handler(1, active, addr_2, dev->kbc); + } + + kbc_at_set_irq(0, active ? irq : 0xffff, dev->kbc); + kbc_at_set_irq(1, (active && active_2) ? irq_2 : 0xffff, dev->kbc); +} + static void fdc_handler(pc87307_t *dev) { - uint8_t irq; - uint8_t active; - uint16_t addr; - fdc_remove(dev->fdc); - active = (dev->ld_regs[0x03][0x00] & 0x01) && (dev->pm[0x00] & 0x08); - addr = ((dev->ld_regs[0x03][0x30] << 8) | dev->ld_regs[0x03][0x31]) - 0x0002; - irq = (dev->ld_regs[0x03][0x40] & 0x0f); + uint8_t active = (dev->ld_regs[LD_FDC][0x00] & 0x01) && + (dev->pm[0x00] & 0x08); + uint8_t irq = (dev->ld_regs[LD_FDC][0x40] & 0x0f); + uint16_t addr = ((dev->ld_regs[LD_FDC][0x30] << 8) | + dev->ld_regs[LD_FDC][0x31]) & 0xfff8; if (active && (addr <= 0xfff8)) { + pc87307_log("Enabling FDC on %04X, IRQ %i...\n", addr, irq); fdc_set_base(dev->fdc, addr); fdc_set_irq(dev->fdc, irq); } } static void -lpt1_handler(pc87307_t *dev) +lpt_handler(pc87307_t *dev) { - uint8_t irq; - uint8_t active; - uint16_t addr; - - lpt1_remove(); - - active = (dev->ld_regs[0x04][0x00] & 0x01) && (dev->pm[0x00] & 0x10); - addr = (dev->ld_regs[0x04][0x30] << 8) | dev->ld_regs[0x04][0x31]; - irq = (dev->ld_regs[0x04][0x40] & 0x0f); + uint8_t active = (dev->ld_regs[LD_LPT][0x00] & 0x01) && + (dev->pm[0x00] & 0x10); + uint8_t irq = (dev->ld_regs[LD_LPT][0x40] & 0x0f); + uint16_t addr = (dev->ld_regs[LD_LPT][0x30] << 8) | + dev->ld_regs[LD_LPT][0x31]; if (active && (addr <= 0xfffc)) { - lpt1_setup(addr); - lpt1_irq(irq); - } + pc87307_log("Enabling LPT1 on %04X...\n", addr); + lpt_port_setup(dev->lpt, addr); + } else + lpt_port_setup(dev->lpt, 0xffff); + + lpt_port_irq(dev->lpt, irq); } static void serial_handler(pc87307_t *dev, int uart) { - uint8_t irq; - uint8_t active; - uint16_t addr; - serial_remove(dev->uart[uart]); - active = (dev->ld_regs[0x06 - uart][0x00] & 0x01) && (dev->pm[0x00] & (1 << (6 - uart))); - addr = (dev->ld_regs[0x06 - uart][0x30] << 8) | dev->ld_regs[0x06 - uart][0x31]; - irq = (dev->ld_regs[0x06 - uart][0x40] & 0x0f); + uint8_t active = (dev->ld_regs[LD_UART1 - uart][0x00] & 0x01) && + (dev->pm[0x00] & (1 << (6 - uart))); + uint8_t irq = (dev->ld_regs[LD_UART1 - uart][0x40] & 0x0f); + uint16_t addr = (dev->ld_regs[LD_UART1 - uart][0x30] << 8) | + dev->ld_regs[LD_UART1 - uart][0x31]; - if (active && (addr <= 0xfff8)) + if (active && (addr <= 0xfff8)) { + pc87307_log("Enabling COM%i on %04X...\n", uart + 1, addr); serial_setup(dev->uart[uart], addr, irq); + } else + serial_setup(dev->uart[uart], 0x0000, irq); } static void gpio_handler(pc87307_t *dev) { - uint8_t active; - uint16_t addr; - pc87307_gpio_remove(dev); - active = (dev->ld_regs[0x07][0x00] & 0x01); - addr = (dev->ld_regs[0x07][0x30] << 8) | dev->ld_regs[0x07][0x31]; + uint8_t active = (dev->ld_regs[LD_GPIO][0x00] & 0x01); + uint16_t addr = (dev->ld_regs[LD_GPIO][0x30] << 8) | + dev->ld_regs[LD_GPIO][0x31]; + uint16_t addr_2 = (dev->ld_regs[LD_GPIO][0x32] << 8) | + dev->ld_regs[LD_GPIO][0x33]; - if (active) + if (active) { + pc87307_log("Enabling GPIO #1 on %04X...\n", addr); pc87307_gpio_init(dev, 0, addr); - - addr = (dev->ld_regs[0x07][0x32] << 8) | dev->ld_regs[0x07][0x33]; - - if (active) - pc87307_gpio_init(dev, 1, addr); + pc87307_log("Enabling GPIO #2 on %04X...\n", addr_2); + pc87307_gpio_init(dev, 1, addr_2); + } } static void pm_handler(pc87307_t *dev) { - uint8_t active; - uint16_t addr; - pc87307_pm_remove(dev); - active = (dev->ld_regs[0x08][0x00] & 0x01); - addr = (dev->ld_regs[0x08][0x30] << 8) | dev->ld_regs[0x08][0x31]; + uint8_t active = (dev->ld_regs[LD_PM][0x00] & 0x01); + uint16_t addr = (dev->ld_regs[LD_PM][0x30] << 8) | + dev->ld_regs[LD_PM][0x31]; - if (active) + if (active) { + pc87307_log("Enabling power management on %04X...\n", addr); pc87307_pm_init(dev, addr); + } +} + +static void +superio_handler(pc87307_t *dev) +{ + if (dev->superio_base != 0x0000) + io_removehandler(dev->superio_base, 0x0002, + pc87307_read, NULL, NULL, + pc87307_write, NULL, NULL, dev); + + switch (dev->regs[0x22] & 0x03) { + default: + dev->superio_base = 0x0000; + break; case 0x02: + dev->superio_base = 0x015c; + break; + case 0x03: + dev->superio_base = 0x002e; + break; + } + + if (dev->superio_base != 0x0000) { + pc87307_log("Enabling Super I/O on %04X...\n", dev->superio_base); + io_sethandler(dev->superio_base, 0x0002, + pc87307_read, NULL, NULL, + pc87307_write, NULL, NULL, dev); + } } static void pc87307_write(uint16_t port, uint8_t val, void *priv) { - pc87307_t *dev = (pc87307_t *) priv; - uint8_t index; - - index = (port & 1) ? 0 : 1; + pc87307_t *dev = (pc87307_t *) priv; + uint8_t ld = dev->regs[0x07]; + uint8_t reg = dev->cur_reg - 0x30; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t old = dev->regs[dev->cur_reg]; if (index) { dev->cur_reg = val; return; } else { +#ifdef ENABLE_PC87307_LOG + if (dev->cur_reg >= 0x30) + pc87307_log("[%04X:%08X] [W] (%04X) %02X:%02X = %02X\n", + CS, cpu_state.pc, port, ld, dev->cur_reg, val); + else + pc87307_log("[%04X:%08X] [W] (%04X) %02X = %02X\n", + CS, cpu_state.pc, port, dev->cur_reg, val); +#endif switch (dev->cur_reg) { case 0x00: - case 0x02: - case 0x03: - case 0x06: - case 0x07: - case 0x21: + case 0x02: case 0x03: + case 0x06: case 0x07: dev->regs[dev->cur_reg] = val; break; + case 0x21: + dev->regs[dev->cur_reg] = val; + fdc_toggle_flag(dev->fdc, FDC_FLAG_PS2_MCA, !(val & 0x04)); + break; case 0x22: - dev->regs[dev->cur_reg] = val & 0x7f; + dev->regs[dev->cur_reg] = val; + superio_handler(dev); break; case 0x23: - dev->regs[dev->cur_reg] = val & 0x0f; + dev->regs[dev->cur_reg] = (old & 0xf0) | (val & 0x0f); break; case 0x24: dev->pcregs[dev->regs[0x23]] = val; break; default: - if (dev->cur_reg >= 0x30) { - if ((dev->regs[0x07] != 0x06) || !(dev->regs[0x21] & 0x10)) - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val; - } + if (dev->cur_reg >= 0x30) + old = dev->ld_regs[ld][reg]; break; } } switch (dev->cur_reg) { case 0x30: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x01; - switch (dev->regs[0x07]) { - case 0x03: + switch (ld) { + default: + break; + case LD_KBD: case LD_MOUSE: + dev->ld_regs[ld][reg] = val; + kbc_handler(dev); + break; + case LD_RTC: + dev->ld_regs[ld][reg] = val; + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; fdc_handler(dev); break; - case 0x04: - lpt1_handler(dev); + case LD_LPT: + dev->ld_regs[ld][reg] = val; + lpt_handler(dev); break; - case 0x05: + case LD_UART2: + dev->ld_regs[ld][reg] = val; serial_handler(dev, 1); break; - case 0x06: + case LD_UART1: + dev->ld_regs[ld][reg] = val; serial_handler(dev, 0); break; - case 0x07: + case LD_GPIO: + dev->ld_regs[ld][reg] = val; gpio_handler(dev); break; - case 0x08: + case LD_PM: + dev->ld_regs[ld][reg] = val; pm_handler(dev); break; - - default: - break; } break; + /* I/O Range Check. */ + case 0x31: + switch (ld) { + default: + break; + case LD_MIN ... LD_MAX: + if (ld != LD_MOUSE) + dev->ld_regs[ld][reg] = val; + break; + } + break; + /* Base Address 0 MSB. */ case 0x60: - if (dev->regs[0x07] == 0x04) { - val &= 0x03; - } - fallthrough; - case 0x62: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val; - if ((dev->cur_reg == 0x62) && (dev->regs[0x07] != 0x07)) - break; - switch (dev->regs[0x07]) { - case 0x03: + switch (ld) { + default: + break; + case LD_KBD: + dev->ld_regs[ld][reg] = val; + kbc_handler(dev); + break; + case LD_RTC: + dev->ld_regs[ld][reg] = val; + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; fdc_handler(dev); break; - case 0x04: - lpt1_handler(dev); + case LD_LPT: + dev->ld_regs[ld][reg] = (old & 0xfc) | (val & 0x03); + lpt_handler(dev); break; - case 0x05: + case LD_UART2: + dev->ld_regs[ld][reg] = val; serial_handler(dev, 1); break; - case 0x06: + case LD_UART1: + dev->ld_regs[ld][reg] = val; serial_handler(dev, 0); break; - case 0x07: + case LD_GPIO: + dev->ld_regs[ld][reg] = val; gpio_handler(dev); break; - case 0x08: + case LD_PM: + dev->ld_regs[ld][reg] = val; pm_handler(dev); break; - - default: - break; } break; + /* Base Address 0 LSB. */ case 0x61: - switch (dev->regs[0x07]) { - case 0x00: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfb; + switch (ld) { + default: break; - case 0x03: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = (val & 0xfa) | 0x02; + case LD_KBD: + dev->ld_regs[ld][reg] = (old & 0x04) | (val & 0xfb); + kbc_handler(dev); + break; + case LD_RTC: + dev->ld_regs[ld][reg] = (old & 0x01) | (val & 0xfe); + break; + case LD_FDC: + dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); fdc_handler(dev); break; - case 0x04: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfc; - lpt1_handler(dev); + case LD_LPT: + dev->ld_regs[ld][reg] = (old & 0x03) | (val & 0xfc); + lpt_handler(dev); break; - case 0x05: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8; + case LD_UART2: + dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); serial_handler(dev, 1); break; - case 0x06: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8; + case LD_UART1: + dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); serial_handler(dev, 0); break; - case 0x07: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8; + case LD_GPIO: + dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); gpio_handler(dev); break; - case 0x08: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfe; + case LD_PM: + dev->ld_regs[ld][reg] = (old & 0x01) | (val & 0xfe); pm_handler(dev); break; - - default: - break; } break; + /* Base Address 1 MSB (undocumented for Logical Device 7). */ + case 0x62: + switch (ld) { + default: + break; + case LD_KBD: + dev->ld_regs[ld][reg] = val; + kbc_handler(dev); + break; + case LD_GPIO: + dev->ld_regs[ld][reg] = val; + gpio_handler(dev); + break; + } + break; + /* Base Address 1 LSB (undocumented for Logical Device 7). */ case 0x63: - if (dev->regs[0x07] == 0x00) - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = (val & 0xfb) | 0x04; - else if (dev->regs[0x07] == 0x07) { - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfe; - gpio_handler(dev); - } - break; - case 0x70: - case 0x74: - case 0x75: - switch (dev->regs[0x07]) { - case 0x03: - fdc_handler(dev); - break; - case 0x04: - lpt1_handler(dev); - break; - case 0x05: - serial_handler(dev, 1); - break; - case 0x06: - serial_handler(dev, 0); - break; - case 0x07: - gpio_handler(dev); - break; - case 0x08: - pm_handler(dev); - break; - + switch (ld) { default: break; + case LD_KBD: + dev->ld_regs[ld][reg] = (old & 0x04) | (val & 0xfb); + kbc_handler(dev); + break; + case LD_GPIO: + dev->ld_regs[ld][reg] = (old & 0x01) | (val & 0xfe); + gpio_handler(dev); + break; } break; - case 0xf0: - switch (dev->regs[0x07]) { - case 0x00: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xc1; + /* Interrupt Select. */ + case 0x70: + switch (ld) { + default: break; - case 0x03: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xe1; + case LD_KBD: case LD_MOUSE: + dev->ld_regs[ld][reg] = val; + kbc_handler(dev); + break; + case LD_RTC: + dev->ld_regs[ld][reg] = val; + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; + fdc_handler(dev); + break; + case LD_LPT: + dev->ld_regs[ld][reg] = val; + lpt_handler(dev); + break; + case LD_UART2: + dev->ld_regs[ld][reg] = val; + serial_handler(dev, 1); + break; + case LD_UART1: + dev->ld_regs[ld][reg] = val; + serial_handler(dev, 0); + break; + } + break; + /* Interrupt Type. */ + case 0x71: + switch (ld) { + default: + break; + case LD_MIN ... LD_MAX: + if ((ld == LD_KBD) || (ld == LD_MOUSE)) + dev->ld_regs[ld][reg] = (old & 0xfc) | (val & 0x03); + else + dev->ld_regs[ld][reg] = (old & 0xfd) | (val & 0x02); + break; + } + break; + /* DMA Channel Select 0. */ + case 0x74: + switch (ld) { + default: + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; + fdc_handler(dev); + break; + case LD_LPT: + dev->ld_regs[ld][reg] = val; + lpt_handler(dev); + break; + case LD_UART2: + dev->ld_regs[ld][reg] = val; + break; + } + break; + /* DMA Channel Select 1. */ + case 0x75: + switch (ld) { + default: + break; + case LD_UART2: + dev->ld_regs[ld][reg] = val; + break; + } + break; + /* Configuration Register 0. */ + case 0xf0: + switch (ld) { + default: + break; + case LD_KBD: + dev->ld_regs[ld][reg] = val; + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; fdc_update_densel_polarity(dev->fdc, (val & 0x20) ? 1 : 0); fdc_update_enh_mode(dev->fdc, (val & 0x40) ? 1 : 0); break; - case 0x04: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf3; - lpt1_handler(dev); + case LD_LPT: + dev->ld_regs[ld][reg] = val; + lpt_handler(dev); break; - case 0x05: - case 0x06: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x87; - break; - - default: + case LD_UART2: case LD_UART1: + dev->ld_regs[ld][reg] = val; break; } break; + /* Configuration Register 1. */ case 0xf1: - if (dev->regs[0x07] == 0x03) - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x0f; + switch (ld) { + default: + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; + break; + } break; default: @@ -458,32 +686,46 @@ pc87307_write(uint16_t port, uint8_t val, void *priv) } } -uint8_t +static uint8_t pc87307_read(uint16_t port, void *priv) { - const pc87307_t *dev = (pc87307_t *) priv; - uint8_t ret = 0xff; - uint8_t index; - - index = (port & 1) ? 0 : 1; + const pc87307_t *dev = (pc87307_t *) priv; + uint8_t ld = dev->regs[0x07]; + uint8_t reg = dev->cur_reg - 0x30; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ret = 0xff; if (index) ret = dev->cur_reg; else { if (dev->cur_reg >= 0x30) - ret = dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30]; + ret = dev->ld_regs[ld][reg]; else if (dev->cur_reg == 0x24) ret = dev->pcregs[dev->regs[0x23]]; + /* Write-only registers. */ + else if ((dev->cur_reg == 0x00) || + (dev->cur_reg == 0x02) || (dev->cur_reg == 0x03)) + ret = 0x00; else ret = dev->regs[dev->cur_reg]; +#ifdef EANBLE_PC87307_LOG + if (dev->cur_reg >= 0x30) + pc87307_log("[%04X:%08X] [R] (%04X) %02X:%02X = %02X\n", + CS, cpu_state.pc, port, ld, dev->cur_reg, ret); + else + pc87307_log("[%04X:%08X] [R] (%04X) %02X = %02X\n", + CS, cpu_state.pc, port, dev->cur_reg, ret); +#endif } return ret; } void -pc87307_reset(pc87307_t *dev) +pc87307_reset(void *priv) { + pc87307_t *dev = (pc87307_t *) priv; + memset(dev->regs, 0x00, 0x30); for (uint16_t i = 0; i < 256; i++) memset(dev->ld_regs[i], 0x00, 0xd0); @@ -493,77 +735,77 @@ pc87307_reset(pc87307_t *dev) dev->regs[0x20] = dev->id; dev->regs[0x21] = 0x04; + dev->regs[0x22] = dev->baddr; - dev->ld_regs[0x00][0x01] = 0x01; - dev->ld_regs[0x00][0x31] = 0x60; - dev->ld_regs[0x00][0x33] = 0x64; - dev->ld_regs[0x00][0x40] = 0x01; - dev->ld_regs[0x00][0x41] = 0x02; - dev->ld_regs[0x00][0x44] = 0x04; - dev->ld_regs[0x00][0x45] = 0x04; - dev->ld_regs[0x00][0xc0] = 0x40; + dev->ld_regs[LD_KBD ][0x00] = 0x01; + dev->ld_regs[LD_KBD ][0x31] = 0x60; + dev->ld_regs[LD_KBD ][0x33] = 0x64; + dev->ld_regs[LD_KBD ][0x40] = 0x01; + dev->ld_regs[LD_KBD ][0x41] = 0x02; + dev->ld_regs[LD_KBD ][0x44] = 0x04; + dev->ld_regs[LD_KBD ][0x45] = 0x04; + dev->ld_regs[LD_KBD ][0xc0] = 0x40; - dev->ld_regs[0x01][0x40] = 0x0c; - dev->ld_regs[0x01][0x41] = 0x02; - dev->ld_regs[0x01][0x44] = 0x04; - dev->ld_regs[0x01][0x45] = 0x04; + dev->ld_regs[LD_MOUSE][0x40] = 0x0c; + dev->ld_regs[LD_MOUSE][0x41] = 0x02; + dev->ld_regs[LD_MOUSE][0x44] = 0x04; + dev->ld_regs[LD_MOUSE][0x45] = 0x04; - dev->ld_regs[0x02][0x00] = 0x01; - dev->ld_regs[0x02][0x31] = 0x70; - dev->ld_regs[0x02][0x40] = 0x08; - dev->ld_regs[0x02][0x44] = 0x04; - dev->ld_regs[0x02][0x45] = 0x04; + dev->ld_regs[LD_RTC ][0x00] = 0x01; + dev->ld_regs[LD_RTC ][0x31] = 0x70; + dev->ld_regs[LD_RTC ][0x40] = 0x08; + dev->ld_regs[LD_RTC ][0x44] = 0x04; + dev->ld_regs[LD_RTC ][0x45] = 0x04; - dev->ld_regs[0x03][0x01] = 0x01; - dev->ld_regs[0x03][0x30] = 0x03; - dev->ld_regs[0x03][0x31] = 0xf2; - dev->ld_regs[0x03][0x40] = 0x06; - dev->ld_regs[0x03][0x41] = 0x03; - dev->ld_regs[0x03][0x44] = 0x02; - dev->ld_regs[0x03][0x45] = 0x04; - dev->ld_regs[0x03][0xc0] = 0x02; + dev->ld_regs[LD_FDC ][0x01] = 0x01; + dev->ld_regs[LD_FDC ][0x30] = 0x03; + dev->ld_regs[LD_FDC ][0x31] = 0xf0; + dev->ld_regs[LD_FDC ][0x32] = 0x03; + dev->ld_regs[LD_FDC ][0x33] = 0xf7; + dev->ld_regs[LD_FDC ][0x40] = 0x06; + dev->ld_regs[LD_FDC ][0x41] = 0x03; + dev->ld_regs[LD_FDC ][0x44] = 0x02; + dev->ld_regs[LD_FDC ][0x45] = 0x04; + dev->ld_regs[LD_FDC ][0xc0] = 0x02; - dev->ld_regs[0x04][0x30] = 0x02; - dev->ld_regs[0x04][0x31] = 0x78; - dev->ld_regs[0x04][0x40] = 0x07; - dev->ld_regs[0x04][0x44] = 0x04; - dev->ld_regs[0x04][0x45] = 0x04; - dev->ld_regs[0x04][0xc0] = 0xf2; + dev->ld_regs[LD_LPT ][0x30] = 0x02; + dev->ld_regs[LD_LPT ][0x31] = 0x78; + dev->ld_regs[LD_LPT ][0x40] = 0x07; + dev->ld_regs[LD_LPT ][0x44] = 0x04; + dev->ld_regs[LD_LPT ][0x45] = 0x04; + dev->ld_regs[LD_LPT ][0xc0] = 0xf2; - dev->ld_regs[0x05][0x30] = 0x02; - dev->ld_regs[0x05][0x31] = 0xf8; - dev->ld_regs[0x05][0x40] = 0x03; - dev->ld_regs[0x05][0x41] = 0x03; - dev->ld_regs[0x05][0x44] = 0x04; - dev->ld_regs[0x05][0x45] = 0x04; - dev->ld_regs[0x05][0xc0] = 0x02; + dev->ld_regs[LD_UART2][0x30] = 0x02; + dev->ld_regs[LD_UART2][0x31] = 0xf8; + dev->ld_regs[LD_UART2][0x40] = 0x03; + dev->ld_regs[LD_UART2][0x41] = 0x03; + dev->ld_regs[LD_UART2][0x44] = 0x04; + dev->ld_regs[LD_UART2][0x45] = 0x04; + dev->ld_regs[LD_UART2][0xc0] = 0x02; - dev->ld_regs[0x06][0x30] = 0x03; - dev->ld_regs[0x06][0x31] = 0xf8; - dev->ld_regs[0x06][0x40] = 0x04; - dev->ld_regs[0x06][0x41] = 0x03; - dev->ld_regs[0x06][0x44] = 0x04; - dev->ld_regs[0x06][0x45] = 0x04; - dev->ld_regs[0x06][0xc0] = 0x02; + dev->ld_regs[LD_UART1][0x30] = 0x03; + dev->ld_regs[LD_UART1][0x31] = 0xf8; + dev->ld_regs[LD_UART1][0x40] = 0x04; + dev->ld_regs[LD_UART1][0x41] = 0x03; + dev->ld_regs[LD_UART1][0x44] = 0x04; + dev->ld_regs[LD_UART1][0x45] = 0x04; + dev->ld_regs[LD_UART1][0xc0] = 0x02; - dev->ld_regs[0x07][0x44] = 0x04; - dev->ld_regs[0x07][0x45] = 0x04; + dev->ld_regs[LD_GPIO ][0x44] = 0x04; + dev->ld_regs[LD_GPIO ][0x45] = 0x04; - dev->ld_regs[0x08][0x44] = 0x04; - dev->ld_regs[0x08][0x45] = 0x04; + dev->ld_regs[LD_PM ][0x44] = 0x04; + dev->ld_regs[LD_PM ][0x45] = 0x04; -#if 0 - dev->gpio[0] = 0xff; - dev->gpio[1] = 0xfb; -#endif dev->gpio[0][0] = 0xff; dev->gpio[0][1] = 0x00; dev->gpio[0][2] = 0x00; dev->gpio[0][3] = 0xff; - dev->gpio[1][0] = 0xff; + dev->gpio[0][4] = 0xff; + dev->gpio[0][5] = 0x00; + dev->gpio[0][6] = 0x00; + dev->gpio[0][7] = 0xff; dev->gpio[1][1] = 0x00; - dev->gpio[1][2] = 0x00; - dev->gpio[1][3] = 0xff; dev->pm[0] = 0xff; dev->pm[1] = 0xff; @@ -576,10 +818,17 @@ pc87307_reset(pc87307_t *dev) 0 = 360 rpm @ 500 kbps for 3.5" 1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5" */ - lpt1_remove(); - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); + fdc_toggle_flag(dev->fdc, FDC_FLAG_PS2_MCA, 0); fdc_reset(dev->fdc); + + kbc_handler(dev); + fdc_handler(dev); + lpt_handler(dev); + serial_handler(dev, 0); + serial_handler(dev, 1); + gpio_handler(dev); + pm_handler(dev); + superio_handler(dev); } static void @@ -602,17 +851,29 @@ pc87307_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); - pc87307_reset(dev); + dev->lpt = device_add_inst(&lpt_port_device, 1); - if (info->local & 0x100) { - io_sethandler(0x02e, 0x0002, - pc87307_read, NULL, NULL, pc87307_write, NULL, NULL, dev); - } - if (info->local & 0x200) { - io_sethandler(0x15c, 0x0002, - pc87307_read, NULL, NULL, pc87307_write, NULL, NULL, dev); + switch (info->local & PCX730X_KBC) { + default: + case PCX730X_AMI: + dev->kbc = device_add(&kbc_ps2_intel_ami_pci_device); + break; + /* Optiplex! */ + case PCX730X_PHOENIX_42: + dev->kbc = device_add(&kbc_ps2_phoenix_device); + break; + case PCX730X_PHOENIX_42I: + dev->kbc = device_add(&kbc_ps2_phoenix_pci_device); + break; } + if (info->local & PCX730X_15C) + dev->baddr = 0x02; + else + dev->baddr = 0x03; + + pc87307_reset(dev); + return dev; } @@ -623,7 +884,7 @@ const device_t pc87307_device = { .local = 0x1c0, .init = pc87307_init, .close = pc87307_close, - .reset = NULL, + .reset = pc87307_reset, .available = NULL, .speed_changed = NULL, .force_redraw = NULL, @@ -637,7 +898,7 @@ const device_t pc87307_15c_device = { .local = 0x2c0, .init = pc87307_init, .close = pc87307_close, - .reset = NULL, + .reset = pc87307_reset, .available = NULL, .speed_changed = NULL, .force_redraw = NULL, @@ -651,7 +912,7 @@ const device_t pc87307_both_device = { .local = 0x3c0, .init = pc87307_init, .close = pc87307_close, - .reset = NULL, + .reset = pc87307_reset, .available = NULL, .speed_changed = NULL, .force_redraw = NULL, @@ -665,7 +926,7 @@ const device_t pc97307_device = { .local = 0x1cf, .init = pc87307_init, .close = pc87307_close, - .reset = NULL, + .reset = pc87307_reset, .available = NULL, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/sio/sio_pc87309.c b/src/sio/sio_pc87309.c index da53802c1..19a18af81 100644 --- a/src/sio/sio_pc87309.c +++ b/src/sio/sio_pc87309.c @@ -8,61 +8,103 @@ * * Emulation of the NatSemi PC87309 Super I/O chip. * - * - * * Authors: Miran Grca, * - * Copyright 2020 Miran Grca. + * Copyright 2020-2025 Miran Grca. */ +#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/machine.h> #include <86box/mem.h> #include <86box/nvr.h> #include <86box/pci.h> #include <86box/rom.h> #include <86box/serial.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/keyboard.h> #include <86box/sio.h> +#include <86box/plat_fallthrough.h> +#include "cpu.h" typedef struct pc87309_t { uint8_t id; + uint8_t baddr; uint8_t pm_idx; uint8_t regs[48]; uint8_t ld_regs[256][208]; uint8_t pm[8]; + uint16_t superio_base; uint16_t pm_base; int cur_reg; + void *kbc; fdc_t *fdc; serial_t *uart[2]; + lpt_t *lpt; } pc87309_t; -static void fdc_handler(pc87309_t *dev); -static void lpt1_handler(pc87309_t *dev); -static void serial_handler(pc87309_t *dev, int uart); +enum { + LD_FDC = 0, + LD_LPT, + LD_UART2, + LD_UART1, + LD_PM, + LD_MOUSE, + LD_KBD +} pc87309_ld_t; + +#define LD_MIN LD_FDC +#define LD_MAX LD_MOUSE + +static void fdc_handler(pc87309_t *dev); +static void lpt_handler(pc87309_t *dev); +static void serial_handler(pc87309_t *dev, int uart); +static void kbc_handler(pc87309_t *dev); +static void pc87309_write(uint16_t port, uint8_t val, void *priv); +static uint8_t pc87309_read(uint16_t port, void *priv); + +#ifdef ENABLE_PC87309_LOG +int pc87309_do_log = ENABLE_PC87309_LOG; + +static void +pc87309_log(const char *fmt, ...) +{ + va_list ap; + + if (pc87309_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define pc87309_log(fmt, ...) +#endif static void pc87309_pm_write(uint16_t port, uint8_t val, void *priv) { pc87309_t *dev = (pc87309_t *) priv; - if (port & 1) { + if (port & 1) dev->pm[dev->pm_idx] = val; + else { + dev->pm_idx = val & 0x07; switch (dev->pm_idx) { case 0x00: fdc_handler(dev); - lpt1_handler(dev); + lpt_handler(dev); serial_handler(dev, 1); serial_handler(dev, 0); break; @@ -70,8 +112,7 @@ pc87309_pm_write(uint16_t port, uint8_t val, void *priv) default: break; } - } else - dev->pm_idx = val & 0x07; + } } uint8_t @@ -104,243 +145,402 @@ pc87309_pm_init(pc87309_t *dev, uint16_t addr) pc87309_pm_read, NULL, NULL, pc87309_pm_write, NULL, NULL, dev); } +static void +kbc_handler(pc87309_t *dev) +{ + uint8_t active = (dev->ld_regs[LD_KBD][0x00] & 0x01) && + (dev->pm[0x00] & 0x01); + uint8_t active_2 = dev->ld_regs[LD_MOUSE][0x00] & 0x01; + uint8_t irq = (dev->ld_regs[LD_KBD][0x40] & 0x0f); + uint8_t irq_2 = (dev->ld_regs[LD_MOUSE][0x40] & 0x0f); + uint16_t addr = (dev->ld_regs[LD_KBD][0x30] << 8) | + dev->ld_regs[LD_KBD][0x31]; + uint16_t addr_2 = (dev->ld_regs[LD_KBD][0x32] << 8) | + dev->ld_regs[LD_KBD][0x33]; + + pc87309_log("%02X, %02X, %02X, %02X, %04X, %04X\n", + active, active_2, irq, irq_2, addr, addr_2); + + if (addr <= 0xfff8) { + pc87309_log("Enabling KBC #1 on %04X...\n", addr); + kbc_at_port_handler(0, active, addr, dev->kbc); + } + + if (addr_2 <= 0xfff8) { + pc87309_log("Enabling KBC #2 on %04X...\n", addr_2); + kbc_at_port_handler(1, active, addr_2, dev->kbc); + } + + kbc_at_set_irq(0, active ? irq : 0xffff, dev->kbc); + kbc_at_set_irq(1, (active && active_2) ? irq_2 : 0xffff, dev->kbc); +} + static void fdc_handler(pc87309_t *dev) { - uint8_t irq; - uint8_t active; - uint16_t addr; - fdc_remove(dev->fdc); - active = (dev->ld_regs[0x00][0x00] & 0x01) && (dev->pm[0x00] & 0x08); - addr = ((dev->ld_regs[0x00][0x30] << 8) | dev->ld_regs[0x00][0x31]) - 0x0002; - irq = (dev->ld_regs[0x00][0x40] & 0x0f); + uint8_t active = (dev->ld_regs[LD_FDC][0x00] & 0x01) && + (dev->pm[0x00] & 0x08); + uint8_t irq = (dev->ld_regs[LD_FDC][0x40] & 0x0f); + uint16_t addr = ((dev->ld_regs[LD_FDC][0x30] << 8) | + dev->ld_regs[LD_FDC][0x31]) & 0xfff8; - if (active) { + if (active && (addr <= 0xfff8)) { + pc87309_log("Enabling FDC on %04X, IRQ %i...\n", addr, irq); fdc_set_base(dev->fdc, addr); fdc_set_irq(dev->fdc, irq); } } static void -lpt1_handler(pc87309_t *dev) +lpt_handler(pc87309_t *dev) { - uint8_t irq; - uint8_t active; - uint16_t addr; + uint8_t active = (dev->ld_regs[LD_LPT][0x00] & 0x01) && + (dev->pm[0x00] & 0x10); + uint8_t irq = (dev->ld_regs[LD_LPT][0x40] & 0x0f); + uint16_t addr = (dev->ld_regs[LD_LPT][0x30] << 8) | + dev->ld_regs[LD_LPT][0x31]; - lpt1_remove(); + if (active && (addr <= 0xfffc)) { + pc87309_log("Enabling LPT1 on %04X...\n", addr); + lpt_port_setup(dev->lpt, addr); + } else + lpt_port_setup(dev->lpt, 0xffff); - active = (dev->ld_regs[0x01][0x00] & 0x01) && (dev->pm[0x00] & 0x10); - addr = (dev->ld_regs[0x01][0x30] << 8) | dev->ld_regs[0x01][0x31]; - irq = (dev->ld_regs[0x01][0x40] & 0x0f); - - if (active) { - lpt1_setup(addr); - lpt1_irq(irq); - } + lpt_port_irq(dev->lpt, irq); } static void serial_handler(pc87309_t *dev, int uart) { - uint8_t irq; - uint8_t active; - uint16_t addr; - serial_remove(dev->uart[uart]); - active = (dev->ld_regs[0x03 - uart][0x00] & 0x01) && (dev->pm[0x00] & (1 << (6 - uart))); - addr = (dev->ld_regs[0x03 - uart][0x30] << 8) | dev->ld_regs[0x03 - uart][0x31]; - irq = (dev->ld_regs[0x03 - uart][0x40] & 0x0f); + uint8_t active = (dev->ld_regs[LD_UART1 - uart][0x00] & 0x01) && + (dev->pm[0x00] & (1 << (6 - uart))); + uint8_t irq = (dev->ld_regs[LD_UART1 - uart][0x40] & 0x0f); + uint16_t addr = (dev->ld_regs[LD_UART1 - uart][0x30] << 8) | + dev->ld_regs[LD_UART1 - uart][0x31]; - if (active) + if (active && (addr <= 0xfff8)) { + pc87309_log("Enabling COM%i on %04X...\n", uart + 1, addr); serial_setup(dev->uart[uart], addr, irq); + } else + serial_setup(dev->uart[uart], 0x0000, irq); } static void pm_handler(pc87309_t *dev) { - uint8_t active; - uint16_t addr; - pc87309_pm_remove(dev); - active = (dev->ld_regs[0x04][0x00] & 0x01); - addr = (dev->ld_regs[0x04][0x30] << 8) | dev->ld_regs[0x04][0x31]; + uint8_t active = (dev->ld_regs[LD_PM][0x00] & 0x01); + uint16_t addr = (dev->ld_regs[LD_PM][0x30] << 8) | + dev->ld_regs[LD_PM][0x31]; - if (active) + if (active) { + pc87309_log("Enabling power management on %04X...\n", addr); pc87309_pm_init(dev, addr); + } +} + +static void +superio_handler(pc87309_t *dev) +{ + if (dev->superio_base != 0x0000) + io_removehandler(dev->superio_base, 0x0002, + pc87309_read, NULL, NULL, + pc87309_write, NULL, NULL, dev); + + switch (dev->regs[0x21] & 0x0b) { + default: + dev->superio_base = 0x0000; + break; + case 0x02: + case 0x08: case 0x0a: + dev->superio_base = 0x015c; + break; + case 0x03: + case 0x09: case 0x0b: + dev->superio_base = 0x002e; + break; + } + + if (dev->superio_base != 0x0000) { + pc87309_log("Enabling Super I/O on %04X...\n", dev->superio_base); + io_sethandler(dev->superio_base, 0x0002, + pc87309_read, NULL, NULL, + pc87309_write, NULL, NULL, dev); + } } static void pc87309_write(uint16_t port, uint8_t val, void *priv) { - pc87309_t *dev = (pc87309_t *) priv; - uint8_t index; - - index = (port & 1) ? 0 : 1; + pc87309_t *dev = (pc87309_t *) priv; + uint8_t ld = dev->regs[0x07]; + uint8_t reg = dev->cur_reg - 0x30; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t old = dev->regs[dev->cur_reg]; if (index) { dev->cur_reg = val; return; } else { +#ifdef ENABLE_PC87309_LOG + if (dev->cur_reg >= 0x30) + pc87309_log("[%04X:%08X] [W] (%04X) %02X:%02X = %02X\n", + CS, cpu_state.pc, port, ld, dev->cur_reg, val); + else + pc87309_log("[%04X:%08X] [W] (%04X) %02X = %02X\n", + CS, cpu_state.pc, port, dev->cur_reg, val); +#endif switch (dev->cur_reg) { case 0x00: - case 0x02: - case 0x03: - case 0x06: - case 0x07: - case 0x21: + case 0x02: case 0x03: + case 0x06: case 0x07: dev->regs[dev->cur_reg] = val; break; + case 0x21: + dev->regs[dev->cur_reg] = val; + fdc_toggle_flag(dev->fdc, FDC_FLAG_PS2_MCA, !(val & 0x04)); + superio_handler(dev); + break; case 0x22: - dev->regs[dev->cur_reg] = val & 0x7f; + dev->regs[dev->cur_reg] = val; break; default: - if (dev->cur_reg >= 0x30) { - if ((dev->regs[0x07] != 0x06) || !(dev->regs[0x21] & 0x10)) - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val; - } + if (dev->cur_reg >= 0x30) + old = dev->ld_regs[ld][reg]; break; } } switch (dev->cur_reg) { case 0x30: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x01; - switch (dev->regs[0x07]) { - case 0x00: + switch (ld) { + default: + break; + case LD_KBD: case LD_MOUSE: + dev->ld_regs[ld][reg] = val; + kbc_handler(dev); + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; fdc_handler(dev); break; - case 0x01: - lpt1_handler(dev); + case LD_LPT: + dev->ld_regs[ld][reg] = val; + lpt_handler(dev); break; - case 0x02: + case LD_UART2: + dev->ld_regs[ld][reg] = val; serial_handler(dev, 1); break; - case 0x03: + case LD_UART1: + dev->ld_regs[ld][reg] = val; serial_handler(dev, 0); break; - case 0x04: + case LD_PM: + dev->ld_regs[ld][reg] = val; pm_handler(dev); break; - - default: - break; } break; + /* I/O Range Check. */ + case 0x31: + switch (ld) { + default: + break; + case LD_MIN ... LD_MAX: + if (ld != LD_MOUSE) + dev->ld_regs[ld][reg] = val; + break; + } + break; + /* Base Address 0 MSB. */ case 0x60: - case 0x62: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x07; - if (dev->cur_reg == 0x62) - break; - switch (dev->regs[0x07]) { - case 0x00: + switch (ld) { + default: + break; + case LD_KBD: + dev->ld_regs[ld][reg] = val; + kbc_handler(dev); + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; fdc_handler(dev); break; - case 0x01: - lpt1_handler(dev); + case LD_LPT: + dev->ld_regs[ld][reg] = (old & 0xfc) | (val & 0x03); + lpt_handler(dev); break; - case 0x02: + case LD_UART2: + dev->ld_regs[ld][reg] = val; serial_handler(dev, 1); break; - case 0x03: + case LD_UART1: + dev->ld_regs[ld][reg] = val; serial_handler(dev, 0); break; - case 0x04: + case LD_PM: + dev->ld_regs[ld][reg] = val; pm_handler(dev); break; - - default: - break; } break; - case 0x63: - if (dev->regs[0x07] == 0x06) - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = (val & 0xf8) | 0x04; - break; + /* Base Address 0 LSB. */ case 0x61: - switch (dev->regs[0x07]) { - case 0x00: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = (val & 0xfa) | 0x02; + switch (ld) { + default: + break; + case LD_KBD: + dev->ld_regs[ld][reg] = (old & 0x04) | (val & 0xfb); + kbc_handler(dev); + break; + case LD_FDC: + dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); fdc_handler(dev); break; - case 0x01: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfc; - lpt1_handler(dev); + case LD_LPT: + dev->ld_regs[ld][reg] = (old & 0x03) | (val & 0xfc); + lpt_handler(dev); break; - case 0x02: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8; + case LD_UART2: + dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); serial_handler(dev, 1); break; - case 0x03: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8; + case LD_UART1: + dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); serial_handler(dev, 0); break; - case 0x04: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xfe; + case LD_PM: + dev->ld_regs[ld][reg] = (old & 0x01) | (val & 0xfe); pm_handler(dev); break; - case 0x06: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf8; - break; - - default: - break; } break; + /* Base Address 1 MSB (undocumented for Logical Device 7). */ + case 0x62: + switch (ld) { + default: + break; + case LD_KBD: + dev->ld_regs[ld][reg] = val; + kbc_handler(dev); + break; + } + break; + /* Base Address 1 LSB (undocumented for Logical Device 7). */ + case 0x63: + switch (ld) { + default: + break; + case LD_KBD: + dev->ld_regs[ld][reg] = (old & 0x04) | (val & 0xfb); + kbc_handler(dev); + break; + } + break; + /* Interrupt Select. */ case 0x70: - case 0x74: - case 0x75: - switch (dev->regs[0x07]) { - case 0x00: + switch (ld) { + default: + break; + case LD_KBD: case LD_MOUSE: + dev->ld_regs[ld][reg] = val; + kbc_handler(dev); + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; fdc_handler(dev); break; - case 0x01: - lpt1_handler(dev); + case LD_LPT: + dev->ld_regs[ld][reg] = val; + lpt_handler(dev); break; - case 0x02: + case LD_UART2: + dev->ld_regs[ld][reg] = val; serial_handler(dev, 1); break; - case 0x03: + case LD_UART1: + dev->ld_regs[ld][reg] = val; serial_handler(dev, 0); break; - case 0x04: - pm_handler(dev); - break; - - default: - break; } break; + /* Interrupt Type. */ + case 0x71: + switch (ld) { + default: + break; + case LD_MIN ... LD_MAX: + if ((ld == LD_KBD) || (ld == LD_MOUSE)) + dev->ld_regs[ld][reg] = (old & 0xfc) | (val & 0x03); + else + dev->ld_regs[ld][reg] = (old & 0xfd) | (val & 0x02); + break; + } + break; + /* DMA Channel Select 0. */ + case 0x74: + switch (ld) { + default: + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; + fdc_handler(dev); + break; + case LD_LPT: + dev->ld_regs[ld][reg] = val; + lpt_handler(dev); + break; + case LD_UART2: + dev->ld_regs[ld][reg] = val; + break; + } + break; + /* DMA Channel Select 1. */ + case 0x75: + switch (ld) { + default: + break; + case LD_UART2: + dev->ld_regs[ld][reg] = val; + break; + } + break; + /* Configuration Register 0. */ case 0xf0: - switch (dev->regs[0x07]) { - case 0x00: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xe1; + switch (ld) { + default: + break; + case LD_KBD: + dev->ld_regs[ld][reg] = val; + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; fdc_update_densel_polarity(dev->fdc, (val & 0x20) ? 1 : 0); fdc_update_enh_mode(dev->fdc, (val & 0x40) ? 1 : 0); break; - case 0x01: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xf3; - lpt1_handler(dev); + case LD_LPT: + dev->ld_regs[ld][reg] = val; + lpt_handler(dev); break; - case 0x02: - case 0x03: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x87; - break; - case 0x06: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0xc1; - break; - - default: + case LD_UART2: case LD_UART1: + dev->ld_regs[ld][reg] = val; break; } break; + /* Configuration Register 1. */ case 0xf1: - if (dev->regs[0x07] == 0x00) - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x0f; + switch (ld) { + default: + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; + break; + } break; default: @@ -348,97 +548,102 @@ pc87309_write(uint16_t port, uint8_t val, void *priv) } } -uint8_t +static uint8_t pc87309_read(uint16_t port, void *priv) { - const pc87309_t *dev = (pc87309_t *) priv; - uint8_t ret = 0xff; - uint8_t index; - - index = (port & 1) ? 0 : 1; + const pc87309_t *dev = (pc87309_t *) priv; + uint8_t ld = dev->regs[0x07]; + uint8_t reg = dev->cur_reg - 0x30; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ret = 0xff; if (index) - ret = dev->cur_reg & 0x1f; + ret = dev->cur_reg; else { if (dev->cur_reg >= 0x30) - ret = dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30]; + ret = dev->ld_regs[ld][reg]; + /* Write-only registers. */ + else if ((dev->cur_reg == 0x00) || + (dev->cur_reg == 0x02) || (dev->cur_reg == 0x03)) + ret = 0x00; else ret = dev->regs[dev->cur_reg]; +#ifdef ENABLE_PC87309_LOG + if (dev->cur_reg >= 0x30) + pc87309_log("[%04X:%08X] [R] (%04X) %02X:%02X = %02X\n", + CS, cpu_state.pc, port, ld, dev->cur_reg, ret); + else + pc87309_log("[%04X:%08X] [R] (%04X) %02X = %02X\n", + CS, cpu_state.pc, port, dev->cur_reg, ret); +#endif } return ret; } void -pc87309_reset(pc87309_t *dev) +pc87309_reset(void *priv) { + pc87309_t *dev = (pc87309_t *) priv; + memset(dev->regs, 0x00, 0x30); for (uint16_t i = 0; i < 256; i++) memset(dev->ld_regs[i], 0x00, 0xd0); memset(dev->pm, 0x00, 0x08); dev->regs[0x20] = dev->id; - dev->regs[0x21] = 0x04; + dev->regs[0x21] = 0x04 | dev->baddr; - dev->ld_regs[0x00][0x01] = 0x01; - dev->ld_regs[0x00][0x30] = 0x03; - dev->ld_regs[0x00][0x31] = 0xf2; - dev->ld_regs[0x00][0x40] = 0x06; - dev->ld_regs[0x00][0x41] = 0x03; - dev->ld_regs[0x00][0x44] = 0x02; - dev->ld_regs[0x00][0x45] = 0x04; - dev->ld_regs[0x00][0xc0] = 0x02; + dev->ld_regs[LD_KBD ][0x00] = 0x01; + dev->ld_regs[LD_KBD ][0x31] = 0x60; + dev->ld_regs[LD_KBD ][0x33] = 0x64; + dev->ld_regs[LD_KBD ][0x40] = 0x01; + dev->ld_regs[LD_KBD ][0x41] = 0x02; + dev->ld_regs[LD_KBD ][0x44] = 0x04; + dev->ld_regs[LD_KBD ][0x45] = 0x04; + dev->ld_regs[LD_KBD ][0xc0] = 0x40; - dev->ld_regs[0x01][0x30] = 0x02; - dev->ld_regs[0x01][0x31] = 0x78; - dev->ld_regs[0x01][0x40] = 0x07; - dev->ld_regs[0x01][0x44] = 0x04; - dev->ld_regs[0x01][0x45] = 0x04; - dev->ld_regs[0x01][0xc0] = 0xf2; + dev->ld_regs[LD_MOUSE][0x40] = 0x0c; + dev->ld_regs[LD_MOUSE][0x41] = 0x02; + dev->ld_regs[LD_MOUSE][0x44] = 0x04; + dev->ld_regs[LD_MOUSE][0x45] = 0x04; - dev->ld_regs[0x02][0x30] = 0x02; - dev->ld_regs[0x02][0x31] = 0xf8; - dev->ld_regs[0x02][0x40] = 0x03; - dev->ld_regs[0x02][0x41] = 0x03; - dev->ld_regs[0x02][0x44] = 0x04; - dev->ld_regs[0x02][0x45] = 0x04; - dev->ld_regs[0x02][0xc0] = 0x02; + dev->ld_regs[LD_FDC ][0x01] = 0x01; + dev->ld_regs[LD_FDC ][0x30] = 0x03; + dev->ld_regs[LD_FDC ][0x31] = 0xf0; + dev->ld_regs[LD_FDC ][0x32] = 0x03; + dev->ld_regs[LD_FDC ][0x33] = 0xf7; + dev->ld_regs[LD_FDC ][0x40] = 0x06; + dev->ld_regs[LD_FDC ][0x41] = 0x03; + dev->ld_regs[LD_FDC ][0x44] = 0x02; + dev->ld_regs[LD_FDC ][0x45] = 0x04; + dev->ld_regs[LD_FDC ][0xc0] = 0x02; - dev->ld_regs[0x03][0x30] = 0x03; - dev->ld_regs[0x03][0x31] = 0xf8; - dev->ld_regs[0x03][0x40] = 0x04; - dev->ld_regs[0x03][0x41] = 0x03; - dev->ld_regs[0x03][0x44] = 0x04; - dev->ld_regs[0x03][0x45] = 0x04; - dev->ld_regs[0x03][0xc0] = 0x02; + dev->ld_regs[LD_LPT ][0x30] = 0x02; + dev->ld_regs[LD_LPT ][0x31] = 0x78; + dev->ld_regs[LD_LPT ][0x40] = 0x07; + dev->ld_regs[LD_LPT ][0x44] = 0x04; + dev->ld_regs[LD_LPT ][0x45] = 0x04; + dev->ld_regs[LD_LPT ][0xc0] = 0xf2; - dev->ld_regs[0x04][0x44] = 0x04; - dev->ld_regs[0x04][0x45] = 0x04; + dev->ld_regs[LD_UART2][0x30] = 0x02; + dev->ld_regs[LD_UART2][0x31] = 0xf8; + dev->ld_regs[LD_UART2][0x40] = 0x03; + dev->ld_regs[LD_UART2][0x41] = 0x03; + dev->ld_regs[LD_UART2][0x44] = 0x04; + dev->ld_regs[LD_UART2][0x45] = 0x04; + dev->ld_regs[LD_UART2][0xc0] = 0x02; - dev->ld_regs[0x05][0x40] = 0x0c; - dev->ld_regs[0x05][0x41] = 0x02; - dev->ld_regs[0x05][0x44] = 0x04; - dev->ld_regs[0x05][0x45] = 0x04; + dev->ld_regs[LD_UART1][0x30] = 0x03; + dev->ld_regs[LD_UART1][0x31] = 0xf8; + dev->ld_regs[LD_UART1][0x40] = 0x04; + dev->ld_regs[LD_UART1][0x41] = 0x03; + dev->ld_regs[LD_UART1][0x44] = 0x04; + dev->ld_regs[LD_UART1][0x45] = 0x04; + dev->ld_regs[LD_UART1][0xc0] = 0x02; - dev->ld_regs[0x06][0x01] = 0x01; - dev->ld_regs[0x06][0x31] = 0x60; - dev->ld_regs[0x06][0x33] = 0x64; - dev->ld_regs[0x06][0x40] = 0x01; - dev->ld_regs[0x06][0x41] = 0x02; - dev->ld_regs[0x06][0x44] = 0x04; - dev->ld_regs[0x06][0x45] = 0x04; - dev->ld_regs[0x06][0xc0] = 0x40; - - dev->regs[0x00] = 0x0B; - dev->regs[0x01] = 0x01; - dev->regs[0x03] = 0x01; - dev->regs[0x05] = 0x0D; - dev->regs[0x08] = 0x70; - dev->regs[0x09] = 0xC0; - dev->regs[0x0b] = 0x80; - dev->regs[0x0f] = 0x1E; - dev->regs[0x12] = 0x30; - dev->regs[0x19] = 0xEF; + dev->ld_regs[LD_PM ][0x44] = 0x04; + dev->ld_regs[LD_PM ][0x45] = 0x04; dev->pm[0] = 0x79; dev->pm[4] = 0x0e; @@ -449,10 +654,16 @@ pc87309_reset(pc87309_t *dev) 0 = 360 rpm @ 500 kbps for 3.5" 1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5" */ - lpt1_remove(); - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); + fdc_toggle_flag(dev->fdc, FDC_FLAG_PS2_MCA, 0); fdc_reset(dev->fdc); + + kbc_handler(dev); + fdc_handler(dev); + lpt_handler(dev); + serial_handler(dev, 0); + serial_handler(dev, 1); + pm_handler(dev); + superio_handler(dev); } static void @@ -475,16 +686,29 @@ pc87309_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); - pc87309_reset(dev); + dev->lpt = device_add_inst(&lpt_port_device, 1); - if (info->local & 0x100) { - io_sethandler(0x15c, 0x0002, - pc87309_read, NULL, NULL, pc87309_write, NULL, NULL, dev); - } else { - io_sethandler(0x02e, 0x0002, - pc87309_read, NULL, NULL, pc87309_write, NULL, NULL, dev); + switch (info->local & PCX730X_KBC) { + default: + case PCX730X_AMI: + dev->kbc = device_add(&kbc_ps2_intel_ami_pci_device); + break; + /* Optiplex! */ + case PCX730X_PHOENIX_42: + dev->kbc = device_add(&kbc_ps2_phoenix_device); + break; + case PCX730X_PHOENIX_42I: + dev->kbc = device_add(&kbc_ps2_phoenix_pci_device); + break; } + if (info->local & PCX730X_15C) + dev->baddr = 0x0a; + else + dev->baddr = 0x0b; + + pc87309_reset(dev); + return dev; } @@ -492,24 +716,10 @@ const device_t pc87309_device = { .name = "National Semiconductor PC87309 Super I/O", .internal_name = "pc87309", .flags = 0, - .local = 0xe0, + .local = 0, .init = pc87309_init, .close = pc87309_close, - .reset = NULL, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t pc87309_15c_device = { - .name = "National Semiconductor PC87309 Super I/O (Port 15Ch)", - .internal_name = "pc87309_15c", - .flags = 0, - .local = 0x1e0, - .init = pc87309_init, - .close = pc87309_close, - .reset = NULL, + .reset = pc87309_reset, .available = NULL, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/sio/sio_pc87310.c b/src/sio/sio_pc87310.c index 5bd595f05..cf6b10bab 100644 --- a/src/sio/sio_pc87310.c +++ b/src/sio/sio_pc87310.c @@ -40,9 +40,6 @@ #include <86box/sio.h> #include <86box/plat_unused.h> -#define FLAG_IDE 0x00000001 -#define FLAG_ALI 0x00000002 - #ifdef ENABLE_PC87310_LOG int pc87310_do_log = ENABLE_PC87310_LOG; @@ -67,10 +64,11 @@ typedef struct pc87310_t { uint8_t regs[2]; fdc_t *fdc; serial_t *uart[2]; + lpt_t *lpt; } pc87310_t; static void -lpt1_handler(pc87310_t *dev) +lpt_handler(pc87310_t *dev) { int temp; uint16_t lpt_port = LPT1_ADDR; @@ -84,7 +82,7 @@ lpt1_handler(pc87310_t *dev) */ temp = dev->regs[1] & 0x03; - lpt1_remove(); + lpt_port_remove(dev->lpt); switch (temp) { case 0: @@ -106,9 +104,9 @@ lpt1_handler(pc87310_t *dev) } if (lpt_port) - lpt1_setup(lpt_port); + lpt_port_setup(dev->lpt, lpt_port); - lpt1_irq(lpt_irq); + lpt_port_irq(dev->lpt, lpt_irq); } static void @@ -137,7 +135,7 @@ serial_handler(pc87310_t *dev) * Then they become simple toggle bits. * Therefore, we do this for easier operation. */ - if (dev->flags & FLAG_ALI) { + if (dev->flags & PC87310_ALI) { temp2 = dev->regs[0] & 0x03; temp2 ^= ((temp2 & 0x02) >> 1); } @@ -190,14 +188,14 @@ pc87310_write(UNUSED(uint16_t port), uint8_t val, void *priv) /* Reconfigure parallel port. */ if (valxor & 0x03) /* Bits 1, 0: 1, 1 = Disable parallel port. */ - lpt1_handler(dev); + lpt_handler(dev); /* Reconfigure serial ports. */ if (valxor & 0x1c) serial_handler(dev); /* Reconfigure IDE controller. */ - if ((dev->flags & FLAG_IDE) && (valxor & 0x20)) { + if ((dev->flags & PC87310_IDE) && (valxor & 0x20)) { pc87310_log("SIO: HDC disabled\n"); ide_pri_disable(); /* Bit 5: 1 = Disable IDE controller. */ @@ -256,9 +254,9 @@ pc87310_reset(pc87310_t *dev) dev->tries = 0; - lpt1_handler(dev); + lpt_handler(dev); serial_handler(dev); - if (dev->flags & FLAG_IDE) { + if (dev->flags & PC87310_IDE) { ide_pri_disable(); ide_pri_enable(); } @@ -286,21 +284,24 @@ pc87310_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16450_device, 1); dev->uart[1] = device_add_inst(&ns16450_device, 2); - if (dev->flags & FLAG_IDE) - device_add((dev->flags & FLAG_ALI) ? &ide_vlb_device : &ide_isa_device); + dev->lpt = device_add_inst(&lpt_port_device, 1); + + if (dev->flags & PC87310_IDE) + device_add((dev->flags & PC87310_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) + if (dev->flags & PC87310_ALI) io_sethandler(0x3f1, 0x0001, pc87310_read, NULL, NULL, pc87310_write, NULL, NULL, dev); return dev; } +/* The ALi M5105 is an extended clone of this. */ const device_t pc87310_device = { .name = "National Semiconductor PC87310 Super I/O", .internal_name = "pc87310", @@ -314,31 +315,3 @@ const device_t pc87310_device = { .force_redraw = NULL, .config = NULL }; - -const device_t pc87310_ide_device = { - .name = "National Semiconductor PC87310 Super I/O with IDE functionality", - .internal_name = "pc87310_ide", - .flags = 0, - .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, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; diff --git a/src/sio/sio_pc87311.c b/src/sio/sio_pc87311.c index b560ef425..0b59324d6 100644 --- a/src/sio/sio_pc87311.c +++ b/src/sio/sio_pc87311.c @@ -74,7 +74,7 @@ typedef struct pc87311_t { uint16_t irq; fdc_t *fdc_controller; serial_t *uart[2]; - + lpt_t *lpt; } pc87311_t; void pc87311_fdc_handler(pc87311_t *dev); @@ -202,7 +202,7 @@ pc87311_uart_handler(uint8_t num, pc87311_t *dev) void pc87311_lpt_handler(pc87311_t *dev) { - lpt1_remove(); + lpt_port_remove(dev->lpt); switch (LPT_BA) { case 0: dev->base = LPT1_ADDR; @@ -220,8 +220,8 @@ pc87311_lpt_handler(pc87311_t *dev) default: break; } - lpt1_setup(dev->base); - lpt1_irq(dev->irq); + lpt_port_setup(dev->lpt, dev->base); + lpt_port_irq(dev->lpt, dev->irq); pc87311_log("PC87311-LPT: BASE %04x IRQ %01x\n", dev->base, dev->irq); } @@ -246,7 +246,7 @@ pc87311_ide_handler(pc87311_t *dev) void pc87311_enable(pc87311_t *dev) { - (FUNCTION_ENABLE & 0x01) ? pc87311_lpt_handler(dev) : lpt1_remove(); + (FUNCTION_ENABLE & 0x01) ? pc87311_lpt_handler(dev) : lpt_port_remove(dev->lpt); (FUNCTION_ENABLE & 0x02) ? pc87311_uart_handler(0, dev) : serial_remove(dev->uart[0]); (FUNCTION_ENABLE & 0x04) ? pc87311_uart_handler(1, dev) : serial_remove(dev->uart[1]); (FUNCTION_ENABLE & 0x08) ? pc87311_fdc_handler(dev) : fdc_remove(dev->fdc_controller); @@ -277,6 +277,7 @@ pc87311_init(const device_t *info) dev->fdc_controller = device_add(&fdc_at_nsc_device); dev->uart[0] = device_add_inst(&ns16450_device, 1); dev->uart[1] = device_add_inst(&ns16450_device, 2); + dev->lpt = device_add_inst(&lpt_port_device, 1); if (HAS_IDE_FUNCTIONALITY) device_add(&ide_isa_2ch_device); diff --git a/src/sio/sio_pc87332.c b/src/sio/sio_pc87332.c index d9fb0b211..9e57bf74b 100644 --- a/src/sio/sio_pc87332.c +++ b/src/sio/sio_pc87332.c @@ -43,10 +43,11 @@ typedef struct pc87332_t { int cur_reg; fdc_t *fdc; serial_t *uart[2]; + lpt_t *lpt; } pc87332_t; static void -lpt1_handler(pc87332_t *dev) +lpt_handler(pc87332_t *dev) { int temp; uint16_t lpt_port = LPT1_ADDR; @@ -77,9 +78,9 @@ lpt1_handler(pc87332_t *dev) } if (lpt_port) - lpt1_setup(lpt_port); + lpt_port_setup(dev->lpt, lpt_port); - lpt1_irq(lpt_irq); + lpt_port_irq(dev->lpt, lpt_irq); } static void @@ -189,9 +190,9 @@ pc87332_write(uint16_t port, uint8_t val, void *priv) switch (dev->cur_reg) { case 0: if (valxor & 1) { - lpt1_remove(); + lpt_port_remove(dev->lpt); if ((val & 1) && !(dev->regs[2] & 1)) - lpt1_handler(dev); + lpt_handler(dev); } if (valxor & 2) { serial_remove(dev->uart[0]); @@ -213,9 +214,9 @@ pc87332_write(uint16_t port, uint8_t val, void *priv) break; case 1: if (valxor & 3) { - lpt1_remove(); + lpt_port_remove(dev->lpt); if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) - lpt1_handler(dev); + lpt_handler(dev); } if (valxor & 0xcc) { serial_remove(dev->uart[0]); @@ -230,14 +231,14 @@ pc87332_write(uint16_t port, uint8_t val, void *priv) break; case 2: if (valxor & 1) { - lpt1_remove(); + lpt_port_remove(dev->lpt); serial_remove(dev->uart[0]); serial_remove(dev->uart[1]); fdc_remove(dev->fdc); if (!(val & 1)) { if (dev->regs[0] & 1) - lpt1_handler(dev); + lpt_handler(dev); if (dev->regs[0] & 2) serial_handler(dev, 0); if (dev->regs[0] & 4) @@ -247,9 +248,9 @@ pc87332_write(uint16_t port, uint8_t val, void *priv) } } if (valxor & 8) { - lpt1_remove(); + lpt_port_remove(dev->lpt); if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) - lpt1_handler(dev); + lpt_handler(dev); } break; @@ -298,8 +299,8 @@ pc87332_reset(pc87332_t *dev) 0 = 360 rpm @ 500 kbps for 3.5" 1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5" */ - lpt1_remove(); - lpt1_handler(dev); + lpt_port_remove(dev->lpt); + lpt_handler(dev); serial_remove(dev->uart[0]); serial_remove(dev->uart[1]); serial_handler(dev, 0); @@ -330,6 +331,8 @@ pc87332_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->lpt = device_add_inst(&lpt_port_device, 1); + dev->has_ide = (info->local >> 8) & 0xff; dev->fdc_on = (info->local >> 16) & 0xff; pc87332_reset(dev); diff --git a/src/sio/sio_prime3b.c b/src/sio/sio_prime3b.c index 1cc0be3aa..338f8ee90 100644 --- a/src/sio/sio_prime3b.c +++ b/src/sio/sio_prime3b.c @@ -66,8 +66,9 @@ typedef struct prime3b_t { uint16_t com4_addr; fdc_t *fdc_controller; - serial_t *uart[2]; + serial_t *uart[2]; + lpt_t *lpt; } prime3b_t; void prime3b_fdc_handler(prime3b_t *dev); @@ -175,9 +176,9 @@ void prime3b_lpt_handler(prime3b_t *dev) { uint16_t lpt_base = (ASR & 2) ? LPT_MDA_ADDR : (!(ASR & 1) ? LPT1_ADDR : LPT2_ADDR); - lpt1_remove(); - lpt1_setup(lpt_base); - lpt1_irq(LPT1_IRQ); + lpt_port_remove(dev->lpt); + lpt_port_setup(dev->lpt, lpt_base); + lpt_port_irq(dev->lpt, LPT1_IRQ); prime3b_log("Prime3B-LPT: Enabled with base %03x\n", lpt_base); } @@ -210,7 +211,7 @@ prime3b_enable(prime3b_t *dev) Note: 86Box LPT is simplistic and can't do ECP or EPP. */ - !(FSR & 3) ? prime3b_lpt_handler(dev) : lpt1_remove(); + !(FSR & 3) ? prime3b_lpt_handler(dev) : lpt_port_remove(dev->lpt); (FSR & 4) ? prime3b_uart_handler(0, dev) : serial_remove(dev->uart[0]); (FSR & 8) ? prime3b_uart_handler(1, dev) : serial_remove(dev->uart[1]); (FSR & 0x10) ? prime3b_fdc_handler(dev) : fdc_remove(dev->fdc_controller); @@ -240,7 +241,7 @@ prime3b_powerdown(prime3b_t *dev) serial_remove(dev->uart[1]); if (PDR & 0x10) - lpt1_remove(); + lpt_port_remove(dev->lpt); if (PDR & 1) PDR = old_base; @@ -267,6 +268,7 @@ prime3b_init(const device_t *info) dev->fdc_controller = device_add(&fdc_at_device); dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->lpt = device_add_inst(&lpt_port_device, 1); if (HAS_IDE_FUNCTIONALITY) device_add(&ide_isa_device); diff --git a/src/sio/sio_prime3c.c b/src/sio/sio_prime3c.c index f70f9f372..3b06d8789 100644 --- a/src/sio/sio_prime3c.c +++ b/src/sio/sio_prime3c.c @@ -83,8 +83,9 @@ typedef struct prime3c_t { uint8_t ide_function; fdc_t *fdc_controller; - serial_t *uart[2]; + serial_t *uart[2]; + lpt_t *lpt; } prime3c_t; void prime3c_fdc_handler(prime3c_t *dev); @@ -238,11 +239,12 @@ prime3c_uart_handler(uint8_t num, prime3c_t *dev) void prime3c_lpt_handler(prime3c_t *dev) { - lpt1_remove(); - if (!(FUNCTION_SELECT & 0x03)) { + lpt_port_remove(dev->lpt); + + if (!(FUNCTION_SELECT & 0x03)) { + lpt_port_setup(dev->lpt, LPT_BASE_ADDRESS << 2); + lpt_port_irq(dev->lpt, FDC_LPT_IRQ & 0xf); - lpt1_setup(LPT_BASE_ADDRESS << 2); - lpt1_irq(FDC_LPT_IRQ & 0xf); prime3c_log("Prime3C-LPT: BASE %04x IRQ %02x\n", LPT_BASE_ADDRESS << 2, FDC_LPT_IRQ & 0xf); } } @@ -277,7 +279,7 @@ prime3c_enable(prime3c_t *dev) Note: 86Box LPT is simplistic and can't do ECP or EPP. */ - !(FUNCTION_SELECT & 0x03) ? prime3c_lpt_handler(dev) : lpt1_remove(); + !(FUNCTION_SELECT & 0x03) ? prime3c_lpt_handler(dev) : lpt_port_remove(dev->lpt); (FUNCTION_SELECT & 0x04) ? prime3c_uart_handler(0, dev) : serial_remove(dev->uart[0]); (FUNCTION_SELECT & 0x08) ? prime3c_uart_handler(1, dev) : serial_remove(dev->uart[1]); (FUNCTION_SELECT & 0x10) ? prime3c_fdc_handler(dev) : fdc_remove(dev->fdc_controller); @@ -311,6 +313,7 @@ prime3c_init(const device_t *info) dev->fdc_controller = device_add(&fdc_at_device); dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->lpt = device_add_inst(&lpt_port_device, 1); if (HAS_IDE_FUNCTIONALITY) device_add(&ide_isa_device); diff --git a/src/sio/sio_um8663f.c b/src/sio/sio_um8663f.c index 54f12dda6..f51810972 100644 --- a/src/sio/sio_um8663f.c +++ b/src/sio/sio_um8663f.c @@ -61,7 +61,9 @@ typedef struct um8663f_t { uint8_t regs[5]; fdc_t *fdc; + serial_t *uart[2]; + lpt_t * lpt; } um8663f_t; static void @@ -102,16 +104,16 @@ um8663f_uart_handler(um8663f_t *dev, int port) static void um8663f_lpt_handler(um8663f_t *dev) { - lpt1_remove(); + lpt_port_remove(dev->lpt); if (dev->regs[0] & 0x08) { switch ((dev->regs[1] >> 3) & 0x01) { case 0x01: - lpt1_setup(LPT1_ADDR); - lpt1_irq(LPT1_IRQ); + lpt_port_setup(dev->lpt, LPT1_ADDR); + lpt_port_irq(dev->lpt, LPT1_IRQ); break; case 0x00: - lpt1_setup(LPT2_ADDR); - lpt1_irq(LPT2_IRQ); + lpt_port_setup(dev->lpt, LPT2_ADDR); + lpt_port_irq(dev->lpt, LPT2_IRQ); break; default: @@ -230,8 +232,8 @@ um8663f_reset(void *priv) serial_remove(dev->uart[1]); serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); - lpt1_remove(); - lpt1_setup(LPT1_ADDR); + lpt_port_remove(dev->lpt); + lpt_port_setup(dev->lpt, LPT1_ADDR); fdc_reset(dev->fdc); fdc_remove(dev->fdc); @@ -268,19 +270,78 @@ um8663f_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->lpt = device_add_inst(&lpt_port_device, 1); + dev->ide = info->local & 0xff; if (dev->ide < IDE_BUS_MAX) device_add(&ide_isa_device); dev->max_reg = info->local >> 8; - io_sethandler(0x0108, 0x0002, um8663f_read, NULL, NULL, um8663f_write, NULL, NULL, dev); + if (dev->max_reg != 0x00) + io_sethandler(0x0108, 0x0002, um8663f_read, NULL, NULL, um8663f_write, NULL, NULL, dev); um8663f_reset(dev); return dev; } +const device_t um82c862f_device = { + .name = "UMC UM82C862F Super I/O", + .internal_name = "um82c862f", + .flags = 0, + .local = 0x0000, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um82c862f_ide_device = { + .name = "UMC UM82C862F Super I/O (With IDE)", + .internal_name = "um82c862f_ide", + .flags = 0, + .local = 0x0001, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um82c863f_device = { + .name = "UMC UM82C863F Super I/O", + .internal_name = "um82c863f", + .flags = 0, + .local = 0xc100, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t um82c863f_ide_device = { + .name = "UMC UM82C863F Super I/O (With IDE)", + .internal_name = "um82c863f_ide", + .flags = 0, + .local = 0xc101, + .init = um8663f_init, + .close = um8663f_close, + .reset = um8663f_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t um8663af_device = { .name = "UMC UM8663AF Super I/O", .internal_name = "um8663af", diff --git a/src/sio/sio_um8669f.c b/src/sio/sio_um8669f.c index 6da9ef6e9..2ec934465 100644 --- a/src/sio/sio_um8669f.c +++ b/src/sio/sio_um8669f.c @@ -157,6 +157,7 @@ typedef struct um8669f_t { fdc_t *fdc; serial_t *uart[2]; + lpt_t * lpt; uint8_t ide; void *gameport; } um8669f_t; @@ -203,11 +204,11 @@ um8669f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pri break; case 3: - lpt1_remove(); + lpt_port_remove(dev->lpt); if (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) { um8669f_log("UM8669F: LPT enabled at port %04X IRQ %d\n", config->io[0].base, config->irq[0].irq); - lpt1_setup(config->io[0].base); + lpt_port_setup(dev->lpt, config->io[0].base); } else { um8669f_log("UM8669F: LPT disabled\n"); } @@ -301,7 +302,7 @@ um8669f_reset(um8669f_t *dev) serial_remove(dev->uart[1]); - lpt1_remove(); + lpt_port_remove(dev->lpt); if (dev->ide < IDE_BUS_MAX) ide_remove_handlers(dev->ide); @@ -339,6 +340,8 @@ um8669f_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->lpt = device_add_inst(&lpt_port_device, 1); + dev->ide = info->local; if (dev->ide < IDE_BUS_MAX) device_add(&ide_isa_device); diff --git a/src/sio/sio_vl82c113.c b/src/sio/sio_vl82c113.c index ee18b1893..bf63e9023 100644 --- a/src/sio/sio_vl82c113.c +++ b/src/sio/sio_vl82c113.c @@ -22,6 +22,7 @@ #include <86box/timer.h> #include <86box/device.h> #include <86box/keyboard.h> +#include <86box/machine.h> #include <86box/nvr.h> #include <86box/sio.h> #include <86box/plat_unused.h> @@ -133,13 +134,16 @@ vl82c113_init(UNUSED(const device_t *info)) { vl82c113_t *dev = (vl82c113_t *) calloc(1, sizeof(vl82c113_t)); - dev->nvr = device_add(&at_nvr_device); + if (!strcmp(machine_get_internal_name(), "martin")) + dev->nvr = device_add(&martin_nvr_device); + else + dev->nvr = device_add(&amstrad_megapc_nvr_device); dev->nvr_enabled = 1; dev->nvr_base = 0x0070; /* Commands are standard. */ - dev->kbc = device_add(&keyboard_at_device); + dev->kbc = device_add(&kbc_at_device); vl82c113_reset(dev); diff --git a/src/sio/sio_vt82c686.c b/src/sio/sio_vt82c686.c index 0e874210d..ec6c5d203 100644 --- a/src/sio/sio_vt82c686.c +++ b/src/sio/sio_vt82c686.c @@ -44,6 +44,7 @@ typedef struct vt82c686_t { uint8_t lpt_irq; fdc_t *fdc; serial_t *uart[2]; + lpt_t *lpt; } vt82c686_t; static uint8_t @@ -83,15 +84,15 @@ vt82c686_lpt_handler(vt82c686_t *dev) if (io_len == 8) io_mask = 0x3f8; /* EPP */ - lpt1_remove(); + lpt_port_remove(dev->lpt); if (((dev->regs[0x02] & 0x03) != 0x03) && !(dev->regs[0x0f] & 0x11) && (io_base >= 0x100) && (io_base <= io_mask)) - lpt1_setup(io_base); + lpt_port_setup(dev->lpt, io_base); if (dev->lpt_irq) { - lpt1_irq(dev->lpt_irq); + lpt_port_irq(dev->lpt, dev->lpt_irq); } else { - lpt1_irq(0xff); + lpt_port_irq(dev->lpt, 0xff); } } @@ -295,6 +296,7 @@ vt82c686_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->lpt = device_add_inst(&lpt_port_device, 1); dev->lpt_dma = 3; vt82c686_reset(dev); diff --git a/src/sio/sio_w83787f.c b/src/sio/sio_w83787f.c index f4971ddce..285d88232 100644 --- a/src/sio/sio_w83787f.c +++ b/src/sio/sio_w83787f.c @@ -86,6 +86,7 @@ typedef struct w83787f_t { int ide_start; fdc_t *fdc; serial_t *uart[2]; + lpt_t *lpt; void *gameport; } w83787f_t; @@ -195,10 +196,10 @@ w83787f_lpt_handler(w83787f_t *dev) if (dev->regs[4] & 0x80) enable = 0; - lpt1_remove(); + lpt_port_remove(dev->lpt); if (enable) { - lpt1_setup(addr); - lpt1_irq(irq); + lpt_port_setup(dev->lpt, addr); + lpt_port_irq(dev->lpt, irq); } } @@ -377,9 +378,9 @@ w83787f_reset(w83787f_t *dev) { uint16_t hefere = dev->reg_init & 0x0100; - lpt1_remove(); - lpt1_setup(LPT1_ADDR); - lpt1_irq(LPT1_IRQ); + lpt_port_remove(dev->lpt); + lpt_port_setup(dev->lpt, LPT1_ADDR); + lpt_port_irq(dev->lpt, LPT1_IRQ); memset(dev->regs, 0, 0x2A); @@ -452,6 +453,8 @@ w83787f_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->lpt = device_add_inst(&lpt_port_device, 1); + dev->gameport = gameport_add(&gameport_sio_1io_device); if ((dev->ide_function & 0x30) == 0x10) diff --git a/src/sio/sio_w83877f.c b/src/sio/sio_w83877f.c index 7c92d6e71..ef5ccc284 100644 --- a/src/sio/sio_w83877f.c +++ b/src/sio/sio_w83877f.c @@ -68,6 +68,7 @@ typedef struct w83877f_t { int key_times; fdc_t *fdc; serial_t *uart[2]; + lpt_t *lpt; } w83877f_t; static void w83877f_write(uint16_t port, uint8_t val, void *priv); @@ -166,9 +167,9 @@ w83877f_lpt_handler(w83877f_t *dev) uint8_t lpt_irq; uint8_t lpt_irqs[8] = { 0, 7, 9, 10, 11, 14, 15, 5 }; - lpt1_remove(); + lpt_port_remove(dev->lpt); if (!(dev->regs[4] & 0x80) && (dev->regs[0x23] & 0xc0)) - lpt1_setup(make_port(dev, 0x23)); + lpt_port_setup(dev->lpt, make_port(dev, 0x23)); lpt_irq = 0xff; @@ -176,7 +177,7 @@ w83877f_lpt_handler(w83877f_t *dev) if (lpt_irq == 0) lpt_irq = PRTIQS; - lpt1_irq(lpt_irq); + lpt_port_irq(dev->lpt, lpt_irq); } static void @@ -451,6 +452,8 @@ w83877f_init(const device_t *info) dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->lpt = device_add_inst(&lpt_port_device, 1); + dev->reg_init = info->local; w83877f_reset(dev); diff --git a/src/sio/sio_w83977f.c b/src/sio/sio_w83977f.c index fd177bc19..3b03dfc4d 100644 --- a/src/sio/sio_w83977f.c +++ b/src/sio/sio_w83977f.c @@ -48,6 +48,7 @@ typedef struct w83977f_t { int type; int hefras; fdc_t *fdc; + lpt_t *lpt; serial_t *uart[2]; } w83977f_t; @@ -108,21 +109,12 @@ w83977f_lpt_handler(w83977f_t *dev) if (io_len == 8) io_mask = 0xff8; - if (dev->id == 1) { - lpt2_remove(); + lpt_port_remove(dev->lpt); - if ((dev->dev_regs[1][0x00] & 0x01) && (dev->regs[0x22] & 0x08) && (io_base >= 0x100) && (io_base <= io_mask)) - lpt2_setup(io_base); + if ((dev->dev_regs[1][0x00] & 0x01) && (dev->regs[0x22] & 0x08) && (io_base >= 0x100) && (io_base <= io_mask)) + lpt_port_setup(dev->lpt, io_base); - lpt2_irq(dev->dev_regs[1][0x40] & 0x0f); - } else { - lpt1_remove(); - - if ((dev->dev_regs[1][0x00] & 0x01) && (dev->regs[0x22] & 0x08) && (io_base >= 0x100) && (io_base <= io_mask)) - lpt1_setup(io_base); - - lpt1_irq(dev->dev_regs[1][0x40] & 0x0f); - } + lpt_port_irq(dev->lpt, dev->dev_regs[1][0x40] & 0x0f); } static void @@ -608,6 +600,8 @@ w83977f_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); + dev->lpt = device_add_inst(&lpt_port_device, next_id + 1); + w83977f_reset(dev); next_id++; diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index d575717a0..9e2a75198 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -36,11 +36,13 @@ add_library(snd OBJECT snd_azt2316a.c snd_cms.c snd_cmi8x38.c + snd_covox.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c + snd_mmb.c snd_mpu401.c snd_pas16.c snd_sn76489.c @@ -48,8 +50,6 @@ add_library(snd OBJECT snd_wss.c snd_ym7128.c snd_optimc.c - esfmu/esfm.c - esfmu/esfm_registers.c snd_opl_esfm.c ) @@ -177,23 +177,22 @@ if(MUNT) endif() endif() +add_subdirectory(ayumi) +target_link_libraries(86Box ayumi) + +add_subdirectory(esfmu) +target_link_libraries(86Box esfmu) + add_subdirectory(ymfm) target_link_libraries(86Box ymfm) -add_subdirectory(saasound) -target_link_libraries(86Box saasound) - -if(GUSMAX) - target_compile_definitions(snd PRIVATE USE_GUSMAX) -endif() - if(OPL4ML) target_compile_definitions(snd PRIVATE USE_OPL4ML) target_sources(snd PRIVATE midi_opl4.c midi_opl4_yrw801.c) endif() -find_package(PkgConfig ) -pkg_check_modules(SERIALPORT libserialport) +find_package(PkgConfig) +pkg_check_modules(SERIALPORT libserialport) if(SERIALPORT_FOUND OR DEFINED LIBSERIALPORT_ROOT) add_compile_definitions(USE_LIBSERIALPORT=1) diff --git a/src/sound/ayumi/CMakeLists.txt b/src/sound/ayumi/CMakeLists.txt new file mode 100644 index 000000000..f3e4b18c7 --- /dev/null +++ b/src/sound/ayumi/CMakeLists.txt @@ -0,0 +1,14 @@ +# +# 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. +# + +add_library(ayumi STATIC + ayumi.c +) diff --git a/src/sound/ayumi/LICENSE b/src/sound/ayumi/LICENSE new file mode 100644 index 000000000..25371edc6 --- /dev/null +++ b/src/sound/ayumi/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) Peter Sovietov, http://sovietov.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/src/sound/ayumi/ayumi.c b/src/sound/ayumi/ayumi.c new file mode 100644 index 000000000..861b0fd45 --- /dev/null +++ b/src/sound/ayumi/ayumi.c @@ -0,0 +1,338 @@ +/* Author: Peter Sovietov */ + +#include +#include +#include "ayumi.h" + +static const double AY_dac_table[] = { + 0.0, 0.0, + 0.00999465934234, 0.00999465934234, + 0.0144502937362, 0.0144502937362, + 0.0210574502174, 0.0210574502174, + 0.0307011520562, 0.0307011520562, + 0.0455481803616, 0.0455481803616, + 0.0644998855573, 0.0644998855573, + 0.107362478065, 0.107362478065, + 0.126588845655, 0.126588845655, + 0.20498970016, 0.20498970016, + 0.292210269322, 0.292210269322, + 0.372838941024, 0.372838941024, + 0.492530708782, 0.492530708782, + 0.635324635691, 0.635324635691, + 0.805584802014, 0.805584802014, + 1.0, 1.0 +}; + +static const double YM_dac_table[] = { + 0.0, 0.0, + 0.00465400167849, 0.00772106507973, + 0.0109559777218, 0.0139620050355, + 0.0169985503929, 0.0200198367285, + 0.024368657969, 0.029694056611, + 0.0350652323186, 0.0403906309606, + 0.0485389486534, 0.0583352407111, + 0.0680552376593, 0.0777752346075, + 0.0925154497597, 0.111085679408, + 0.129747463188, 0.148485542077, + 0.17666895552, 0.211551079576, + 0.246387426566, 0.281101701381, + 0.333730067903, 0.400427252613, + 0.467383840696, 0.53443198291, + 0.635172045472, 0.75800717174, + 0.879926756695, 1.0 +}; + +static void reset_segment(struct ayumi* ay); + +static int update_tone(struct ayumi* ay, int index) { + struct tone_channel* ch = &ay->channels[index]; + ch->tone_counter += 1; + if (ch->tone_counter >= ch->tone_period) { + ch->tone_counter = 0; + ch->tone ^= 1; + } + return ch->tone; +} + +static int update_noise(struct ayumi* ay) { + int bit0x3; + ay->noise_counter += 1; + if (ay->noise_counter >= (ay->noise_period << 1)) { + ay->noise_counter = 0; + bit0x3 = ((ay->noise ^ (ay->noise >> 3)) & 1); + ay->noise = (ay->noise >> 1) | (bit0x3 << 16); + } + return ay->noise & 1; +} + +static void slide_up(struct ayumi* ay) { + ay->envelope += 1; + if (ay->envelope > 31) { + ay->envelope_segment ^= 1; + reset_segment(ay); + } +} + +static void slide_down(struct ayumi* ay) { + ay->envelope -= 1; + if (ay->envelope < 0) { + ay->envelope_segment ^= 1; + reset_segment(ay); + } +} + +static void hold_top(struct ayumi* ay) { + (void) ay; +} + +static void hold_bottom(struct ayumi* ay) { + (void) ay; +} + +static void (* const Envelopes[][2])(struct ayumi*) = { + {slide_down, hold_bottom}, + {slide_down, hold_bottom}, + {slide_down, hold_bottom}, + {slide_down, hold_bottom}, + {slide_up, hold_bottom}, + {slide_up, hold_bottom}, + {slide_up, hold_bottom}, + {slide_up, hold_bottom}, + {slide_down, slide_down}, + {slide_down, hold_bottom}, + {slide_down, slide_up}, + {slide_down, hold_top}, + {slide_up, slide_up}, + {slide_up, hold_top}, + {slide_up, slide_down}, + {slide_up, hold_bottom} +}; + +static void reset_segment(struct ayumi* ay) { + if (Envelopes[ay->envelope_shape][ay->envelope_segment] == slide_down + || Envelopes[ay->envelope_shape][ay->envelope_segment] == hold_top) { + ay->envelope = 31; + return; + } + ay->envelope = 0; +} + +int update_envelope(struct ayumi* ay) { + ay->envelope_counter += 1; + if (ay->envelope_counter >= ay->envelope_period) { + ay->envelope_counter = 0; + Envelopes[ay->envelope_shape][ay->envelope_segment](ay); + } + return ay->envelope; +} + +static void update_mixer(struct ayumi* ay) { + int i; + int out; + int noise = update_noise(ay); + int envelope = update_envelope(ay); + ay->left = 0; + ay->right = 0; + for (i = 0; i < TONE_CHANNELS; i += 1) { + out = (update_tone(ay, i) | ay->channels[i].t_off) & (noise | ay->channels[i].n_off); + out *= ay->channels[i].e_on ? envelope : ay->channels[i].volume * 2 + 1; + ay->left += ay->dac_table[out] * ay->channels[i].pan_left; + ay->right += ay->dac_table[out] * ay->channels[i].pan_right; + } +} + +int ayumi_configure(struct ayumi* ay, int is_ym, double clock_rate, int sr) { + int i; + memset(ay, 0, sizeof(struct ayumi)); + ay->step = clock_rate / (sr * 8 * DECIMATE_FACTOR); + ay->dac_table = is_ym ? YM_dac_table : AY_dac_table; + ay->noise = 1; + ayumi_set_envelope(ay, 1); + for (i = 0; i < TONE_CHANNELS; i += 1) { + ayumi_set_tone(ay, i, 1); + } + return ay->step < 1; +} + +void ayumi_set_pan(struct ayumi* ay, int index, double pan, int is_eqp) { + if (is_eqp) { + ay->channels[index].pan_left = sqrt(1 - pan); + ay->channels[index].pan_right = sqrt(pan); + } else { + ay->channels[index].pan_left = 1 - pan; + ay->channels[index].pan_right = pan; + } +} + +void ayumi_set_tone(struct ayumi* ay, int index, int period) { + period &= 0xfff; + ay->channels[index].tone_period = (period == 0) | period; +} + +void ayumi_set_noise(struct ayumi* ay, int period) { + period &= 0x1f; + ay->noise_period = (period == 0) | period; +} + +void ayumi_set_mixer(struct ayumi* ay, int index, int t_off, int n_off, int e_on) { + ay->channels[index].t_off = t_off & 1; + ay->channels[index].n_off = n_off & 1; + ay->channels[index].e_on = e_on; +} + +void ayumi_set_volume(struct ayumi* ay, int index, int volume) { + ay->channels[index].volume = volume & 0xf; +} + +void ayumi_set_envelope(struct ayumi* ay, int period) { + period &= 0xffff; + ay->envelope_period = (period == 0) | period; +} + +void ayumi_set_envelope_shape(struct ayumi* ay, int shape) { + ay->envelope_shape = shape & 0xf; + ay->envelope_counter = 0; + ay->envelope_segment = 0; + reset_segment(ay); +} + +static double decimate(double* x) { + double y = -0.0000046183113992051936 * (x[1] + x[191]) + + -0.00001117761640887225 * (x[2] + x[190]) + + -0.000018610264502005432 * (x[3] + x[189]) + + -0.000025134586135631012 * (x[4] + x[188]) + + -0.000028494281690666197 * (x[5] + x[187]) + + -0.000026396828793275159 * (x[6] + x[186]) + + -0.000017094212558802156 * (x[7] + x[185]) + + 0.000023798193576966866 * (x[9] + x[183]) + + 0.000051281160242202183 * (x[10] + x[182]) + + 0.00007762197826243427 * (x[11] + x[181]) + + 0.000096759426664120416 * (x[12] + x[180]) + + 0.00010240229300393402 * (x[13] + x[179]) + + 0.000089344614218077106 * (x[14] + x[178]) + + 0.000054875700118949183 * (x[15] + x[177]) + + -0.000069839082210680165 * (x[17] + x[175]) + + -0.0001447966132360757 * (x[18] + x[174]) + + -0.00021158452917708308 * (x[19] + x[173]) + + -0.00025535069106550544 * (x[20] + x[172]) + + -0.00026228714374322104 * (x[21] + x[171]) + + -0.00022258805927027799 * (x[22] + x[170]) + + -0.00013323230495695704 * (x[23] + x[169]) + + 0.00016182578767055206 * (x[25] + x[167]) + + 0.00032846175385096581 * (x[26] + x[166]) + + 0.00047045611576184863 * (x[27] + x[165]) + + 0.00055713851457530944 * (x[28] + x[164]) + + 0.00056212565121518726 * (x[29] + x[163]) + + 0.00046901918553962478 * (x[30] + x[162]) + + 0.00027624866838952986 * (x[31] + x[161]) + + -0.00032564179486838622 * (x[33] + x[159]) + + -0.00065182310286710388 * (x[34] + x[158]) + + -0.00092127787309319298 * (x[35] + x[157]) + + -0.0010772534348943575 * (x[36] + x[156]) + + -0.0010737727700273478 * (x[37] + x[155]) + + -0.00088556645390392634 * (x[38] + x[154]) + + -0.00051581896090765534 * (x[39] + x[153]) + + 0.00059548767193795277 * (x[41] + x[151]) + + 0.0011803558710661009 * (x[42] + x[150]) + + 0.0016527320270369871 * (x[43] + x[149]) + + 0.0019152679330965555 * (x[44] + x[148]) + + 0.0018927324805381538 * (x[45] + x[147]) + + 0.0015481870327877937 * (x[46] + x[146]) + + 0.00089470695834941306 * (x[47] + x[145]) + + -0.0010178225878206125 * (x[49] + x[143]) + + -0.0020037400552054292 * (x[50] + x[142]) + + -0.0027874356824117317 * (x[51] + x[141]) + + -0.003210329988021943 * (x[52] + x[140]) + + -0.0031540624117984395 * (x[53] + x[139]) + + -0.0025657163651900345 * (x[54] + x[138]) + + -0.0014750752642111449 * (x[55] + x[137]) + + 0.0016624165446378462 * (x[57] + x[135]) + + 0.0032591192839069179 * (x[58] + x[134]) + + 0.0045165685815867747 * (x[59] + x[133]) + + 0.0051838984346123896 * (x[60] + x[132]) + + 0.0050774264697459933 * (x[61] + x[131]) + + 0.0041192521414141585 * (x[62] + x[130]) + + 0.0023628575417966491 * (x[63] + x[129]) + + -0.0026543507866759182 * (x[65] + x[127]) + + -0.0051990251084333425 * (x[66] + x[126]) + + -0.0072020238234656924 * (x[67] + x[125]) + + -0.0082672928192007358 * (x[68] + x[124]) + + -0.0081033739572956287 * (x[69] + x[123]) + + -0.006583111539570221 * (x[70] + x[122]) + + -0.0037839040415292386 * (x[71] + x[121]) + + 0.0042781252851152507 * (x[73] + x[119]) + + 0.0084176358598320178 * (x[74] + x[118]) + + 0.01172566057463055 * (x[75] + x[117]) + + 0.013550476647788672 * (x[76] + x[116]) + + 0.013388189369997496 * (x[77] + x[115]) + + 0.010979501242341259 * (x[78] + x[114]) + + 0.006381274941685413 * (x[79] + x[113]) + + -0.007421229604153888 * (x[81] + x[111]) + + -0.01486456304340213 * (x[82] + x[110]) + + -0.021143584622178104 * (x[83] + x[109]) + + -0.02504275058758609 * (x[84] + x[108]) + + -0.025473530942547201 * (x[85] + x[107]) + + -0.021627310017882196 * (x[86] + x[106]) + + -0.013104323383225543 * (x[87] + x[105]) + + 0.017065133989980476 * (x[89] + x[103]) + + 0.036978919264451952 * (x[90] + x[102]) + + 0.05823318062093958 * (x[91] + x[101]) + + 0.079072012081405949 * (x[92] + x[100]) + + 0.097675998716952317 * (x[93] + x[99]) + + 0.11236045936950932 * (x[94] + x[98]) + + 0.12176343577287731 * (x[95] + x[97]) + + 0.125 * x[96]; + memcpy(&x[FIR_SIZE - DECIMATE_FACTOR], x, DECIMATE_FACTOR * sizeof(double)); + return y; +} + +void ayumi_process(struct ayumi* ay) { + int i; + double y1; + double* c_left = ay->interpolator_left.c; + double* y_left = ay->interpolator_left.y; + double* c_right = ay->interpolator_right.c; + double* y_right = ay->interpolator_right.y; + double* fir_left = &ay->fir_left[FIR_SIZE - ay->fir_index * DECIMATE_FACTOR]; + double* fir_right = &ay->fir_right[FIR_SIZE - ay->fir_index * DECIMATE_FACTOR]; + ay->fir_index = (ay->fir_index + 1) % (FIR_SIZE / DECIMATE_FACTOR - 1); + for (i = DECIMATE_FACTOR - 1; i >= 0; i -= 1) { + ay->x += ay->step; + if (ay->x >= 1) { + ay->x -= 1; + y_left[0] = y_left[1]; + y_left[1] = y_left[2]; + y_left[2] = y_left[3]; + y_right[0] = y_right[1]; + y_right[1] = y_right[2]; + y_right[2] = y_right[3]; + update_mixer(ay); + y_left[3] = ay->left; + y_right[3] = ay->right; + y1 = y_left[2] - y_left[0]; + c_left[0] = 0.5 * y_left[1] + 0.25 * (y_left[0] + y_left[2]); + c_left[1] = 0.5 * y1; + c_left[2] = 0.25 * (y_left[3] - y_left[1] - y1); + y1 = y_right[2] - y_right[0]; + c_right[0] = 0.5 * y_right[1] + 0.25 * (y_right[0] + y_right[2]); + c_right[1] = 0.5 * y1; + c_right[2] = 0.25 * (y_right[3] - y_right[1] - y1); + } + fir_left[i] = (c_left[2] * ay->x + c_left[1]) * ay->x + c_left[0]; + fir_right[i] = (c_right[2] * ay->x + c_right[1]) * ay->x + c_right[0]; + } + ay->left = decimate(fir_left); + ay->right = decimate(fir_right); +} + +static double dc_filter(struct dc_filter* dc, int index, double x) { + dc->sum += -dc->delay[index] + x; + dc->delay[index] = x; + return x - dc->sum / DC_FILTER_SIZE; +} + +void ayumi_remove_dc(struct ayumi* ay) { + ay->left = dc_filter(&ay->dc_left, ay->dc_index, ay->left); + ay->right = dc_filter(&ay->dc_right, ay->dc_index, ay->right); + ay->dc_index = (ay->dc_index + 1) & (DC_FILTER_SIZE - 1); +} diff --git a/src/sound/ayumi/ayumi.h b/src/sound/ayumi/ayumi.h new file mode 100644 index 000000000..f15939514 --- /dev/null +++ b/src/sound/ayumi/ayumi.h @@ -0,0 +1,71 @@ +/* Author: Peter Sovietov */ + +#ifndef AYUMI_H +#define AYUMI_H + +enum { + TONE_CHANNELS = 3, + DECIMATE_FACTOR = 8, + FIR_SIZE = 192, + DC_FILTER_SIZE = 1024 +}; + +struct tone_channel { + int tone_period; + int tone_counter; + int tone; + int t_off; + int n_off; + int e_on; + int volume; + double pan_left; + double pan_right; +}; + +struct interpolator { + double c[4]; + double y[4]; +}; + +struct dc_filter { + double sum; + double delay[DC_FILTER_SIZE]; +}; + +struct ayumi { + struct tone_channel channels[TONE_CHANNELS]; + int noise_period; + int noise_counter; + int noise; + int envelope_counter; + int envelope_period; + int envelope_shape; + int envelope_segment; + int envelope; + const double* dac_table; + double step; + double x; + struct interpolator interpolator_left; + struct interpolator interpolator_right; + double fir_left[FIR_SIZE * 2]; + double fir_right[FIR_SIZE * 2]; + int fir_index; + struct dc_filter dc_left; + struct dc_filter dc_right; + int dc_index; + double left; + double right; +}; + +int ayumi_configure(struct ayumi* ay, int is_ym, double clock_rate, int sr); +void ayumi_set_pan(struct ayumi* ay, int index, double pan, int is_eqp); +void ayumi_set_tone(struct ayumi* ay, int index, int period); +void ayumi_set_noise(struct ayumi* ay, int period); +void ayumi_set_mixer(struct ayumi* ay, int index, int t_off, int n_off, int e_on); +void ayumi_set_volume(struct ayumi* ay, int index, int volume); +void ayumi_set_envelope(struct ayumi* ay, int period); +void ayumi_set_envelope_shape(struct ayumi* ay, int shape); +void ayumi_process(struct ayumi* ay); +void ayumi_remove_dc(struct ayumi* ay); + +#endif diff --git a/src/sound/esfmu/CMakeLists.txt b/src/sound/esfmu/CMakeLists.txt new file mode 100644 index 000000000..2505038f1 --- /dev/null +++ b/src/sound/esfmu/CMakeLists.txt @@ -0,0 +1,15 @@ +# +# 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. +# + +add_library(esfmu STATIC + esfm.c + esfm_registers.c +) diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index 027c85b79..1afefd905 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -161,6 +161,7 @@ fluidsynth_init(UNUSED(const device_t *info)) fluid_settings_setnum(data->settings, "synth.sample-rate", 44100); fluid_settings_setnum(data->settings, "synth.gain", device_get_config_int("output_gain") / 100.0f); + fluid_settings_setint(data->settings, "synth.dynamic-sample-loading", device_get_config_int("dynamic_sample_loading")); data->synth = new_fluid_synth(data->settings); @@ -324,7 +325,7 @@ static const device_config_t fluidsynth_config[] = { .type = CONFIG_FNAME, .default_string = NULL, .default_int = 0, - .file_filter = "SF2 Sound Fonts (*.sf2)|*.sf2", + .file_filter = "SoundFont files (*.sf2 *.sf3)|*.sf2,*.sf3", .spinner = { 0 }, .selection = { { 0 } }, .bios = { { 0 } } @@ -509,6 +510,17 @@ static const device_config_t fluidsynth_config[] = { }, .bios = { { 0 } } }, + { + .name = "dynamic_sample_loading", + .description = "Dynamic Sample Loading", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; diff --git a/src/sound/midi_opl4.c b/src/sound/midi_opl4.c index 5ec15cc7c..25f44c9e7 100644 --- a/src/sound/midi_opl4.c +++ b/src/sound/midi_opl4.c @@ -436,7 +436,8 @@ note_on(uint8_t note, uint8_t velocity, MIDI_CHANNEL_DATA *midi_channel, opl4_mi 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; + int i = 0; + uint8_t voices = 0; while (opl4_midi->gen_in_progress) { } diff --git a/src/sound/saasound/CMakeLists.txt b/src/sound/saasound/CMakeLists.txt deleted file mode 100644 index 2db75493e..000000000 --- a/src/sound/saasound/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -add_library(saasound OBJECT - SAAAmp.cpp - SAAAmp.h - SAADevice.cpp - SAADevice.h - SAAEnv.cpp - SAAEnv.h - SAAFreq.cpp - SAAFreq.h - SAAImpl.cpp - SAAImpl.h - SAANoise.cpp - SAANoise.h - SAASndC.cpp - SAASndC.h - SAASound.cpp) \ No newline at end of file diff --git a/src/sound/saasound/SAAAmp.cpp b/src/sound/saasound/SAAAmp.cpp deleted file mode 100755 index 8f2473fb1..000000000 --- a/src/sound/saasound/SAAAmp.cpp +++ /dev/null @@ -1,203 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// SAAAmp.cpp: implementation of the CSAAAmp class. -// This class handles Tone/Noise mixing, Envelope application and -// amplification. -// -////////////////////////////////////////////////////////////////////// - -#include "SAASound.h" -#include "types.h" -#include "SAANoise.h" -#include "SAAEnv.h" -#include "SAAFreq.h" -#include "SAAAmp.h" -#include "defns.h" - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -CSAAAmp::CSAAAmp(CSAAFreq * const ToneGenerator, const CSAANoise * const NoiseGenerator, const CSAAEnv * const EnvGenerator) -: -m_pcConnectedToneGenerator(ToneGenerator), -m_pcConnectedNoiseGenerator(NoiseGenerator), -m_pcConnectedEnvGenerator(EnvGenerator), -m_bUseEnvelope(EnvGenerator != NULL) -{ - leftlevel = 0; - leftlevela0x0e = 0; - rightlevel = 0; - rightlevela0x0e = 0; - m_nMixMode = 0; - m_bMute=true; - m_bSync = false; - m_nOutputIntermediate=0; - last_level_byte=0; - SetAmpLevel(0x00); - -} - -CSAAAmp::~CSAAAmp() -{ - // Nothing to do -} - -void CSAAAmp::SetAmpLevel(BYTE level_byte) -{ - // if level unchanged since last call then do nothing - if (level_byte != last_level_byte) - { - last_level_byte = level_byte; - leftlevel = level_byte & 0x0f; - leftlevela0x0e = leftlevel & 0x0e; - - rightlevel = (level_byte >> 4) & 0x0f; - rightlevela0x0e = rightlevel & 0x0e; - } - -} - -void CSAAAmp::SetToneMixer(BYTE bEnabled) -{ - if (bEnabled == 0) - { - // clear mixer bit - m_nMixMode &= ~(0x01); - } - else - { - // set mixer bit - m_nMixMode |= 0x01; - } -} - -void CSAAAmp::SetNoiseMixer(BYTE bEnabled) -{ - if (bEnabled == 0) - { - m_nMixMode &= ~(0x02); - } - else - { - m_nMixMode |= 0x02; - } -} - -void CSAAAmp::Mute(bool bMute) -{ - // m_bMute refers to the GLOBAL mute setting (register 28 bit 0) - // NOT the per-channel mixer settings !! - m_bMute = bMute; -} - -void CSAAAmp::Sync(bool bSync) -{ - // m_bSync refers to the GLOBAL sync setting (register 28 bit 1) - m_bSync = bSync; -} - -void CSAAAmp::Tick(void) -{ - // updates m_nOutputIntermediate to 0, 1 or 2 - // - - // connected oscillator always ticks (this isn't really connected to the amp) - int level = m_pcConnectedToneGenerator->Tick(); - - switch (m_nMixMode) - { - case 0: - // no tone or noise for this channel - m_nOutputIntermediate = 0; - break; - case 1: - // tone only for this channel - m_nOutputIntermediate = level * 2; - // NOTE: ConnectedToneGenerator returns either 0 or 1 - break; - case 2: - // noise only for this channel - m_nOutputIntermediate = m_pcConnectedNoiseGenerator->Level() * 2; - // NOTE: ConnectedNoiseGenerator()->Level() returns either 0 or 1 - break; - case 3: - // tone+noise for this channel ... mixing algorithm : - // tone noise output - // 0 0 0 - // 1 0 2 - // 0 1 0 - // 1 1 1 - // = 2 * tone - 1 * (tone & noise) - // = tone * (2 - noise) - m_nOutputIntermediate = level * (2 - m_pcConnectedNoiseGenerator->Level()); - break; - } - // intermediate is between 0 and 2 -} - -inline int CSAAAmp::EffectiveAmplitude(int amp, int env) const -{ - // Return the effective amplitude of the low-pass-filtered result of the logical - // AND of the amplitude PDM and envelope PDM patterns. This is a more accurate - // evaluation of the SAA than simply returning amp * env , based on how the SAA - // implements pulse-density modulation. - static const int pdm[16][16] = { - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,2,2,2,2,2,2,2,2,4,4,4,4}, - {0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8}, - {0,1,1,2,4,5,5,6,6,7,7,8,10,11,11,12}, - {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}, - {0,1,2,3,6,7,8,9,10,11,12,13,16,17,18,19}, - {0,2,3,5,6,8,9,11,12,14,15,17,18,20,21,23}, - {0,2,3,5,8,10,11,13,14,16,17,19,22,24,25,27}, - {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30}, - {0,2,4,6,10,12,14,16,18,20,22,24,28,30,32,34}, - {0,3,5,8,10,13,15,18,20,23,25,28,30,33,35,38}, - {0,3,5,8,12,15,17,20,22,25,27,30,34,37,39,42}, - {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, - {0,3,6,9,14,17,20,23,26,29,32,35,40,43,46,49}, - {0,4,7,11,14,18,21,25,28,32,35,39,42,46,49,53}, - {0,4,7,11,16,20,23,27,30,34,37,41,46,50,53,57} - }; - - return(pdm[amp][env] * 4); -} - -void CSAAAmp::TickAndOutputStereo(unsigned int & left, unsigned int & right) -{ - // This returns a value between 0 and 480 inclusive. - // This represents the full dynamic range of one output mixer (tone, or noise+tone, at full volume, - // without envelopes enabled). Note that, with envelopes enabled, the actual dynamic range - // is reduced on-chip to just over 88% of this (424), so the "loudest" output requires disabling envs. - // NB for 6 channels at full volume, with simple additive mixing, you would see a combined - // output of 2880, and a multiplier of 11 (=31680) fits comfortably within 16-bit signed output range. - - if (m_bSync) - { - // TODO check this - left = right = 0; - return; - } - - // first, do the Tick: - Tick(); - - // now calculate the returned amplitude for this sample: - //////////////////////////////////////////////////////// - - if (m_bMute) - { - left = right = 0; - } - else if (m_bUseEnvelope && m_pcConnectedEnvGenerator->IsActive()) - { - left = EffectiveAmplitude(m_pcConnectedEnvGenerator->LeftLevel(), leftlevela0x0e) * (2 - m_nOutputIntermediate); - right = EffectiveAmplitude(m_pcConnectedEnvGenerator->RightLevel(), rightlevela0x0e) * (2 - m_nOutputIntermediate); - } - else - { - left = leftlevel * m_nOutputIntermediate * 16; - right = rightlevel * m_nOutputIntermediate * 16; - } -} diff --git a/src/sound/saasound/SAAAmp.h b/src/sound/saasound/SAAAmp.h deleted file mode 100755 index 4a6761f21..000000000 --- a/src/sound/saasound/SAAAmp.h +++ /dev/null @@ -1,44 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// SAAAmp.h: interface for the CSAAAmp class. -// This class handles Tone/Noise mixing, Envelope application and -// amplification. -// -////////////////////////////////////////////////////////////////////// - -#ifndef SAAAMP_H_INCLUDED -#define SAAAMP_H_INCLUDED - -class CSAAAmp -{ -private: - int leftlevel; - int leftlevela0x0e; - int rightlevel; - int rightlevela0x0e; - int m_nOutputIntermediate; - unsigned int m_nMixMode; - CSAAFreq * const m_pcConnectedToneGenerator; // not const because amp calls ->Tick() - const CSAANoise * const m_pcConnectedNoiseGenerator; - const CSAAEnv * const m_pcConnectedEnvGenerator; - const bool m_bUseEnvelope; - mutable bool m_bMute; - mutable bool m_bSync; - mutable BYTE last_level_byte; - int EffectiveAmplitude(int amp, int env) const; - -public: - CSAAAmp(CSAAFreq * const ToneGenerator, const CSAANoise * const NoiseGenerator, const CSAAEnv * const EnvGenerator); - ~CSAAAmp(); - - void SetAmpLevel(BYTE level_byte); // really just a BYTE - void SetToneMixer(BYTE bEnabled); - void SetNoiseMixer(BYTE bEnabled); - void Mute(bool bMute); - void Sync(bool bSync); - void Tick(void); - void TickAndOutputStereo(unsigned int & left, unsigned int & right); - -}; - -#endif // SAAAMP_H_INCLUDED diff --git a/src/sound/saasound/SAAConfig.h b/src/sound/saasound/SAAConfig.h deleted file mode 100644 index a655ec59f..000000000 --- a/src/sound/saasound/SAAConfig.h +++ /dev/null @@ -1,41 +0,0 @@ -// Part of SAASound copyright 2020 Dave Hooper -// -// SAAConfig.h: configuration file handler class -// -////////////////////////////////////////////////////////////////////// - -#include "defns.h" -#ifdef USE_CONFIG_FILE - -#ifndef SAA_CONFIG_H_INCLUDED -#define SAA_CONFIG_H_INCLUDED - -#define INI_READONLY -#define INI_ANSIONLY /*nb not really 'ANSI', this just forces all read/write to use 8-bit char*/ -#include "minIni/minIni.h" - -class SAAConfig -{ -private: - minIni m_minIni; - bool m_bHasReadConfig; - -public: - bool m_bGenerateRegisterLogs; - bool m_bGeneratePcmLogs; - bool m_bGeneratePcmSeparateChannels; - t_string m_strRegisterLogPath; - t_string m_strPcmOutputPath; - unsigned int m_nOversample; - bool m_bHighpass; - double m_nBoost; - - SAAConfig(); - void ReadConfig(); - - t_string getChannelPcmOutputPath(int); -}; - -#endif // SAA_CONFIG_H_INCLUDED - -#endif // USE_CONFIG_FILE \ No newline at end of file diff --git a/src/sound/saasound/SAADevice.cpp b/src/sound/saasound/SAADevice.cpp deleted file mode 100644 index 718b05a95..000000000 --- a/src/sound/saasound/SAADevice.cpp +++ /dev/null @@ -1,392 +0,0 @@ -// Part of SAASound copyright 2020 Dave Hooper -// -// SAADevice.cpp: connecting the subcomponents of the SAA1099 together. -// This class handles device inputs and outputs (clocking, data and -// address bus, and simulated output) -// -////////////////////////////////////////////////////////////////////// - -#include "SAASound.h" -#include "types.h" -#include "SAAEnv.h" -#include "SAANoise.h" -#include "SAAFreq.h" -#include "SAAAmp.h" -#include "SAASound.h" -#include "SAAImpl.h" -#include "defns.h" - - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -CSAADevice::CSAADevice() - : - m_nCurrentSaaReg(0), - m_bOutputEnabled(false), - m_bSync(false), - m_bHighpass(true), - m_nOversample(0), - m_Noise0(0xffffffff), - m_Noise1(0xffffffff), - m_Env0(), - m_Env1(), - m_Osc0(&m_Noise0, NULL), - m_Osc1(NULL, &m_Env0), - m_Osc2(NULL, NULL), - m_Osc3(&m_Noise1, NULL), - m_Osc4(NULL, &m_Env1), - m_Osc5(NULL, NULL), - m_Amp0(&m_Osc0, &m_Noise0, NULL), - m_Amp1(&m_Osc1, &m_Noise0, NULL), - m_Amp2(&m_Osc2, &m_Noise0, &m_Env0), - m_Amp3(&m_Osc3, &m_Noise1, NULL), - m_Amp4(&m_Osc4, &m_Noise1, NULL), - m_Amp5(&m_Osc5, &m_Noise1, &m_Env1) -{ - // Create and link up the objects that make up the emulator - Noise[0] = &m_Noise0; - Noise[1] = &m_Noise1; - Env[0] = &m_Env0; - Env[1] = &m_Env1; - - // Create oscillators (tone generators) and link to noise generators and - // envelope controllers - Osc[0] = &m_Osc0; - Osc[1] = &m_Osc1; - Osc[2] = &m_Osc2; - Osc[3] = &m_Osc3; - Osc[4] = &m_Osc4; - Osc[5] = &m_Osc5; - - // Create amplification/mixing stages and link to appropriate oscillators, - // noise generators and envelope controllers - Amp[0] = &m_Amp0; - Amp[1] = &m_Amp1; - Amp[2] = &m_Amp2; - Amp[3] = &m_Amp3; - Amp[4] = &m_Amp4; - Amp[5] = &m_Amp5; - - _SetClockRate(EXTERNAL_CLK_HZ); - _SetOversample(DEFAULT_OVERSAMPLE); -} - -CSAADevice::~CSAADevice() -{ -} - -////////////////////////////////////////////////////////////////////// -// CSAASound members -////////////////////////////////////////////////////////////////////// - -void CSAADevice::_SetClockRate(unsigned int nClockRate) -{ - m_Osc0._SetClockRate(nClockRate); - m_Osc1._SetClockRate(nClockRate); - m_Osc2._SetClockRate(nClockRate); - m_Osc3._SetClockRate(nClockRate); - m_Osc4._SetClockRate(nClockRate); - m_Osc5._SetClockRate(nClockRate); - m_Noise0._SetClockRate(nClockRate); - m_Noise1._SetClockRate(nClockRate); -} - -void CSAADevice::_SetSampleRate(unsigned int nSampleRate) -{ - m_Osc0._SetSampleRate(nSampleRate); - m_Osc1._SetSampleRate(nSampleRate); - m_Osc2._SetSampleRate(nSampleRate); - m_Osc3._SetSampleRate(nSampleRate); - m_Osc4._SetSampleRate(nSampleRate); - m_Osc5._SetSampleRate(nSampleRate); - m_Noise0._SetSampleRate(nSampleRate); - m_Noise1._SetSampleRate(nSampleRate); -} - -void CSAADevice::_SetOversample(unsigned int nOversample) -{ - if (((int) nOversample) != m_nOversample) - { - m_nOversample = nOversample; - m_Osc0._SetOversample(nOversample); - m_Osc1._SetOversample(nOversample); - m_Osc2._SetOversample(nOversample); - m_Osc3._SetOversample(nOversample); - m_Osc4._SetOversample(nOversample); - m_Osc5._SetOversample(nOversample); - m_Noise0._SetOversample(nOversample); - m_Noise1._SetOversample(nOversample); - } -} - -void CSAADevice::_WriteData(BYTE nData) -{ -#if defined(DEBUG) || defined(DEBUGSAA) - m_Reg[m_nCurrentSaaReg] = nData; -#endif - - // route nData to the appropriate place - switch (m_nCurrentSaaReg) - { - // Amplitude data (==> Amp) - case 0: - m_Amp0.SetAmpLevel(nData); - break; - case 1: - m_Amp1.SetAmpLevel(nData); - break; - case 2: - m_Amp2.SetAmpLevel(nData); - break; - case 3: - m_Amp3.SetAmpLevel(nData); - break; - case 4: - m_Amp4.SetAmpLevel(nData); - break; - case 5: - m_Amp5.SetAmpLevel(nData); - break; - - // Freq data (==> Osc) - case 8: - m_Osc0.SetFreqOffset(nData); - break; - case 9: - m_Osc1.SetFreqOffset(nData); - break; - case 10: - m_Osc2.SetFreqOffset(nData); - break; - case 11: - m_Osc3.SetFreqOffset(nData); - break; - case 12: - m_Osc4.SetFreqOffset(nData); - break; - case 13: - m_Osc5.SetFreqOffset(nData); - break; - - // Freq octave data (==> Osc) for channels 0,1 - case 16: - m_Osc0.SetFreqOctave(nData & 0x07); - m_Osc1.SetFreqOctave((nData >> 4) & 0x07); - break; - - // Freq octave data (==> Osc) for channels 2,3 - case 17: - m_Osc2.SetFreqOctave(nData & 0x07); - m_Osc3.SetFreqOctave((nData >> 4) & 0x07); - break; - - // Freq octave data (==> Osc) for channels 4,5 - case 18: - m_Osc4.SetFreqOctave(nData & 0x07); - m_Osc5.SetFreqOctave((nData >> 4) & 0x07); - break; - - // Tone mixer control (==> Amp) - case 20: - m_Amp0.SetToneMixer(nData & 0x01); - m_Amp1.SetToneMixer(nData & 0x02); - m_Amp2.SetToneMixer(nData & 0x04); - m_Amp3.SetToneMixer(nData & 0x08); - m_Amp4.SetToneMixer(nData & 0x10); - m_Amp5.SetToneMixer(nData & 0x20); - break; - - // Noise mixer control (==> Amp) - case 21: - m_Amp0.SetNoiseMixer(nData & 0x01); - m_Amp1.SetNoiseMixer(nData & 0x02); - m_Amp2.SetNoiseMixer(nData & 0x04); - m_Amp3.SetNoiseMixer(nData & 0x08); - m_Amp4.SetNoiseMixer(nData & 0x10); - m_Amp5.SetNoiseMixer(nData & 0x20); - break; - - // Noise frequency/source control (==> Noise) - case 22: - m_Noise0.SetSource(nData & 0x03); - m_Noise1.SetSource((nData >> 4) & 0x03); - break; - - // Envelope control data (==> Env) for envelope controller #0 - case 24: - m_Env0.SetEnvControl(nData); - break; - - // Envelope control data (==> Env) for envelope controller #1 - case 25: - m_Env1.SetEnvControl(nData); - break; - - // Global enable and reset (sync) controls - case 28: - { - // Reset (sync) bit - bool bSync = bool(nData & 0x02); - if (bSync != m_bSync) - { - // Sync all devices - // This amounts to telling them all to reset to a - // known state, which is also a state that doesn't change - // (i.e. no audio output, although there are some exceptions) - // bSync=true => all devices are sync (aka reset); - // bSync=false => all devices are allowed to run and generate changing output - m_Osc0.Sync(bSync); - m_Osc1.Sync(bSync); - m_Osc2.Sync(bSync); - m_Osc3.Sync(bSync); - m_Osc4.Sync(bSync); - m_Osc5.Sync(bSync); - m_Noise0.Sync(bSync); - m_Noise1.Sync(bSync); - m_Amp0.Sync(bSync); - m_Amp1.Sync(bSync); - m_Amp2.Sync(bSync); - m_Amp3.Sync(bSync); - m_Amp4.Sync(bSync); - m_Amp5.Sync(bSync); - m_bSync = bSync; - } - - // Global mute bit - bool bOutputEnabled = bool(nData & 0x01); - if (bOutputEnabled != m_bOutputEnabled) - { - // unmute all amps - sound 'enabled' - m_Amp0.Mute(!bOutputEnabled); - m_Amp1.Mute(!bOutputEnabled); - m_Amp2.Mute(!bOutputEnabled); - m_Amp3.Mute(!bOutputEnabled); - m_Amp4.Mute(!bOutputEnabled); - m_Amp5.Mute(!bOutputEnabled); - m_bOutputEnabled = bOutputEnabled; - } - } - break; - - default: - // anything else means data is being written to a register - // that is not used within the SAA-1099 architecture - // hence, we ignore it. - {} - } -} - -void CSAADevice::_WriteAddress(BYTE nReg) -{ - m_nCurrentSaaReg = nReg & 31; - if (m_nCurrentSaaReg == 24) - { - m_Env0.ExternalClock(); - } - else if (m_nCurrentSaaReg == 25) - { - m_Env1.ExternalClock(); - } -} - -#if 1 -BYTE CSAADevice::_ReadAddress(void) -{ - // Not a real hardware function of the SAA-1099, which is write-only - // However, this is used by SAAImpl to generate debug logs (if enabled) - return(m_nCurrentSaaReg); -} -#endif -#if defined(DEBUG) -BYTE CSAADevice::_ReadData(void) -{ - // Not a real hardware function of the SAA-1099, which is write-only - // This is only compiled for Debug builds - return(m_Reg[m_nCurrentSaaReg]); -} -#endif - -void CSAADevice::_TickAndOutputStereo(unsigned int& left_mixed, unsigned int& right_mixed) -{ - unsigned int temp_left, temp_right; - unsigned int accum_left = 0, accum_right = 0; - for (int i = 1 << m_nOversample; i > 0; i--) - { - m_Noise0.Tick(); - m_Noise1.Tick(); - m_Amp0.TickAndOutputStereo(temp_left, temp_right); - accum_left += temp_left; - accum_right += temp_right; - m_Amp1.TickAndOutputStereo(temp_left, temp_right); - accum_left += temp_left; - accum_right += temp_right; - m_Amp2.TickAndOutputStereo(temp_left, temp_right); - accum_left += temp_left; - accum_right += temp_right; - m_Amp3.TickAndOutputStereo(temp_left, temp_right); - accum_left += temp_left; - accum_right += temp_right; - m_Amp4.TickAndOutputStereo(temp_left, temp_right); - accum_left += temp_left; - accum_right += temp_right; - m_Amp5.TickAndOutputStereo(temp_left, temp_right); - accum_left += temp_left; - accum_right += temp_right; - } - left_mixed = accum_left; - right_mixed = accum_right; -} - -void CSAADevice::_TickAndOutputSeparate(unsigned int& left_mixed, unsigned int& right_mixed, - unsigned int& left0, unsigned int& right0, - unsigned int& left1, unsigned int& right1, - unsigned int& left2, unsigned int& right2, - unsigned int& left3, unsigned int& right3, - unsigned int& left4, unsigned int& right4, - unsigned int& left5, unsigned int& right5 -) -{ - unsigned int temp_left, temp_right; - unsigned int accum_left = 0, accum_right = 0; - left0 = left1 = left2 = left3 = left4 = left5 = 0; - right0 = right1 = right2 = right3 = right4 = right5 = 0; - for (int i = 1 << m_nOversample; i > 0; i--) - { - m_Noise0.Tick(); - m_Noise1.Tick(); - m_Amp0.TickAndOutputStereo(temp_left, temp_right); - left0 += temp_left; - right0 += temp_right; - accum_left += temp_left; - accum_right += temp_right; - m_Amp1.TickAndOutputStereo(temp_left, temp_right); - left1 += temp_left; - right1 += temp_right; - accum_left += temp_left; - accum_right += temp_right; - m_Amp2.TickAndOutputStereo(temp_left, temp_right); - left2 += temp_left; - right2 += temp_right; - accum_left += temp_left; - accum_right += temp_right; - m_Amp3.TickAndOutputStereo(temp_left, temp_right); - left3 += temp_left; - right3 += temp_right; - accum_left += temp_left; - accum_right += temp_right; - m_Amp4.TickAndOutputStereo(temp_left, temp_right); - left4 += temp_left; - right4 += temp_right; - accum_left += temp_left; - accum_right += temp_right; - m_Amp5.TickAndOutputStereo(temp_left, temp_right); - left5 += temp_left; - right5 += temp_right; - accum_left += temp_left; - accum_right += temp_right; - } - left_mixed = accum_left; - right_mixed = accum_right; -} \ No newline at end of file diff --git a/src/sound/saasound/SAADevice.h b/src/sound/saasound/SAADevice.h deleted file mode 100644 index 7b697821f..000000000 --- a/src/sound/saasound/SAADevice.h +++ /dev/null @@ -1,69 +0,0 @@ -// Part of SAASound copyright 2020 Dave Hooper -// -// SAADevice.h: connecting the subcomponents of the SAA1099 together. -// This class handles device inputs and outputs (clocking, data and -// address bus, and simulated output) -// -////////////////////////////////////////////////////////////////////// - -#ifndef SAADEVICE_H_INCLUDED -#define SAADEVICE_H_INCLUDED - -#include "SAASound.h" -#include "SAANoise.h" -#include "SAAEnv.h" -#include "SAAFreq.h" -#include "SAAAmp.h" - -class CSAADevice -{ -private: - int m_nCurrentSaaReg; - bool m_bOutputEnabled; - bool m_bSync; - bool m_bHighpass; - int m_nOversample; - - CSAANoise m_Noise0, m_Noise1; - CSAAEnv m_Env0, m_Env1; - CSAAFreq m_Osc0, m_Osc1, m_Osc2, m_Osc3, m_Osc4, m_Osc5; - CSAAAmp m_Amp0, m_Amp1, m_Amp2, m_Amp3, m_Amp4, m_Amp5; - - CSAANoise* Noise[2]; - CSAAEnv* Env[2]; - CSAAFreq* Osc[6]; - CSAAAmp* Amp[6]; - -#if defined(DEBUG) || defined(DEBUGSAA) - BYTE m_Reg[32]; -#endif - -public: - CSAADevice(); - ~CSAADevice(); - - void _WriteAddress(BYTE nReg); - void _WriteData(BYTE nData); -#if 1 - BYTE _ReadAddress(void); -#endif -#if defined(DEBUG) - BYTE _ReadData(void); -#endif - - void _SetClockRate(unsigned int nClockRate); - void _SetSampleRate(unsigned int nSampleRate); - void _SetOversample(unsigned int nOversample); - void _TickAndOutputStereo(unsigned int& left_mixed, unsigned int& right_mixed); - void _TickAndOutputSeparate(unsigned int& left_mixed, unsigned int& right_mixed, - unsigned int& left0, unsigned int& right0, - unsigned int& left1, unsigned int& right1, - unsigned int& left2, unsigned int& right2, - unsigned int& left3, unsigned int& right3, - unsigned int& left4, unsigned int& right4, - unsigned int& left5, unsigned int& right5 - ); - -}; - -#endif // SAADEVICE_H_INCLUDED \ No newline at end of file diff --git a/src/sound/saasound/SAAEnv.cpp b/src/sound/saasound/SAAEnv.cpp deleted file mode 100755 index 049f51f96..000000000 --- a/src/sound/saasound/SAAEnv.cpp +++ /dev/null @@ -1,380 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// SAAEnv.cpp: implementation of the CSAAEnv class. -// -////////////////////////////////////////////////////////////////////// - -#include "SAASound.h" -#include "types.h" -#include "SAAEnv.h" - - -////////////////////////////////////////////////////////////////////// -// Static member initialisation -////////////////////////////////////////////////////////////////////// - -const ENVDATA CSAAEnv::cs_EnvData[8] = -{ - {1,false, { {{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,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,0,0,0,0,0,0,0,0}}}}, - {1,true, { {{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,15,15,15,15,15}}, - {{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,14,14,14,14,14}}}}, - {1,false, { {{15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}, - {{14,14,12,12,10,10,8,8,6,6,4,4,2,2,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}}, - {1,true, { {{15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}, - {{14,14,12,12,10,10,8,8,6,6,4,4,2,2,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}}, - {2,false, { {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}, {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}}, - {{0,0,2,2,4,4,6,6,8,8,10,10,12,12,14,14}, {14,14,12,12,10,10,8,8,6,6,4,4,2,2,0,0}}}}, - {2,true, { {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}, {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}}, - {{0,0,2,2,4,4,6,6,8,8,10,10,12,12,14,14}, {14,14,12,12,10,10,8,8,6,6,4,4,2,2,0,0}}}}, - {1,false, { {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}, - {{0,0,2,2,4,4,6,6,8,8,10,10,12,12,14,14}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}}, - {1,true, { {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}, - {{0,0,2,2,4,4,6,6,8,8,10,10,12,12,14,14}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}}} -}; - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -CSAAEnv::CSAAEnv() -: -m_bEnabled(false), -m_nPhase(0), -m_nPhasePosition(0), -m_bEnvelopeEnded(true), -m_nResolution(1), -m_bNewData(false), -m_nNextData(0) -{ - // initialise itself with the value 'zero' - SetEnvControl(0); -} - -CSAAEnv::~CSAAEnv() -{ - // Nothing to do -} - -void CSAAEnv::InternalClock(void) -{ - // will only do something if envelope clock mode is set to internal - // and the env control is enabled - if (m_bEnabled && (!m_bClockExternally)) Tick(); -} - -void CSAAEnv::ExternalClock(void) -{ - // will only do something if envelope clock mode is set to external - // and the env control is enabled - if (m_bClockExternally && m_bEnabled) Tick(); -} - -void CSAAEnv::SetEnvControl(int nData) -{ - // process immediate stuff first: - // start with the Enabled flag. if env is disabled, - // there's not much to do - bool bEnabled = ((nData & 0x80)==0x80); - if (!bEnabled && !m_bEnabled) - return; - m_bEnabled = bEnabled; - if (!m_bEnabled) - { - // env control was enabled, and now disabled - // Any subsequent env control changes are immediate. - m_bEnvelopeEnded = true; - return; - } - - // Resolution (3bit/4bit) is also immediately processed - int new_resolution = ((nData & 0x10) == 0x10) ? 2 : 1; - // NOTE: undocumented behaviour when changing resolution mid-waveform - // Empirically, the following matches observations: - // * When ticking the env generator with 4-bit resolution, the position += 1 - // * When ticking the env generator with 3-bit resolution, the position += 2 - // * When changing between 4-bit resolution and 3-bit resolution - // without ticking the env generator, the position is unchanged - // (although, effectively, the LSB is ignored. Purely as an implementation - // detail, I'm implementing this as clearing the LSB ie LSB=0; see next point) - // * When changing between 3-bit resolution and 4-bit resolution - // without ticking the env generator, the position LSB is set to 1 - // See test case: envext_34b - // - if (m_nResolution == 1 && new_resolution == 2) - { - // change from 4-bit to 3-bit - m_nPhasePosition &= 0xe; - } - else if (m_nResolution == 2 && new_resolution == 1) - { - // change from 3-bit to 4-bit - m_nPhasePosition |= 0x1; - } - m_nResolution = new_resolution; - - // now buffered stuff: but only if it's ok to, and only if the - // envgenerator is not disabled. otherwise it just stays buffered until - // the Tick() function sets m_bEnvelopeEnded to true and realises there is - // already some new data waiting - if (m_bEnvelopeEnded) - { - SetNewEnvData(nData); // also does the SetLevels() call for us. - m_bNewData=false; - } - else - { - // since the 'next resolution' changes arrive unbuffered, we - // may need to change the current level because of this: - SetLevels(); - - // store current new data, and set the newdata flag: - m_bNewData = true; - m_nNextData = nData; - } - -} - -int CSAAEnv::LeftLevel(void) const -{ - return m_nLeftLevel; -} - -int CSAAEnv::RightLevel(void) const -{ - return m_nRightLevel; -} - -inline void CSAAEnv::Tick(void) -{ - // if disabled, do nothing - if (!m_bEnabled) // m_bEnabled is set directly, not buffered, so this is ok - { - // for sanity, reset stuff: - m_bEnvelopeEnded = true; - m_nPhase = 0; - m_nPhasePosition = 0; - return; - } - - // else : m_bEnabled - - - if (m_bEnvelopeEnded) - { - // do nothing - // (specifically, don't change the values of m_bEnvelopeEnded, - // m_nPhase and m_nPhasePosition, as these will still be needed - // by SetLevels() should it be called again) - - return; - } - - - // else : !m_bEnvelopeEnded - // Continue playing the same envelope ... - // increments the phaseposition within an envelope. - // also handles looping and resolution appropriately. - // Changes the level of the envelope accordingly - // through calling SetLevels() . This must be called after making - // any changes that will affect the output levels of the env controller!! - // SetLevels also handles left-right channel inverting - - // increment phase position - m_nPhasePosition += m_nResolution; - - // if this means we've gone past 16 (the end of a phase) - // then change phase, and if necessary, loop - // Refer to datasheet for meanings of (3) and (4) in following text - // w.r.t SAA1099 envelopes - - // Note that we will always reach position (3) or (4), even if we keep toggling - // resolution from 4-bit to 3-bit and back, because the counter will always wrap to 0. - // In fact it's quite elegant: - // No matter how you increment and toggle and increment and toggle, the counter - // will at some point be either 0xe (either 4-bit mode or 3-bit mode) or 0xf (4-bit mode only). - // Depending on the mode, even if you change the mode, the next increment, - // or the one after it, will then take it to 0. - // 0xe + 2 (3bit mode) => 0x0 - // 0xe + 1 (4bit mode) => 0xf - // 0xf + 1 (4bit mode) => 0x0 - // 0xe -> (toggle 3bit mode to 4bit mode) => 0xf - // 0xe -> (toggle 4bit mode to 3bit mode) => 0xe - // 0xf -> (toggle 4bit mode to 3bit mode) => 0xe - // - // but there is a subtlety (of course), which is that any changes at point (3) - // can take place immediately you hit point (3), but changes at point (4) are actually - // only acted upon when the counter transitions from 0xe (or 0xf) to 0x0 (which also - // means that, for these looping envelopes, which are the ones that have a point(4), - // immediately after the counter wrapping to 0x0, a write to the env data register will - // NOT set the waveform and will NOT reset the phase/phaseposition (even though it - // will still let you toggle the 4bit/3bit mode, which will change the phaseposition LSB!) - // See test case: envext_34c - - bool bProcessNewDataIfAvailable = false; - if (m_nPhasePosition >= 16) - { - m_nPhase++; - - // if we should loop, then do so - and we've reached position (4) - // otherwise, if we shouldn't loop, - // then we've reached position (3) and so we say that - // we're ok for new data. - if (m_nPhase == m_nNumberOfPhases) - { - // at position (3) or (4) - if (!m_bLooping) - { - // position (3) only - // note that it seems that the sustain level is ALWAYS zero - // in the case of non-looping waveforms - m_bEnvelopeEnded = true; - bProcessNewDataIfAvailable = true; - } - else - { - // position (4) only - // note that any data already latched is ONLY acted upon - // at THIS point. If (after this Tick has completed) any new - // env data is written, it will NOT be acted upon, until - // we get back to position (4) again. - // this is why m_bEnvelopeEnded (which affects the behaviour - // of the SetEnvControl method) is FALSE here. - // See test case: envext_34c (as noted earlier) - m_bEnvelopeEnded = false; - // set phase pointer to start of envelope for loop - // and reset m_nPhasePosition - m_nPhase=0; - m_nPhasePosition -= 16; - bProcessNewDataIfAvailable = true; - } - } - else // (m_nPhase < m_nNumberOfPhases) - { - // not at position (3) or (4) ... - // (i.e., we're in the middle of an envelope with - // more than one phase. Specifically, we're in - // the middle of envelope 4 or 5 - the - // triangle envelopes - but that's not important) - - // any commands sent to this envelope controller - // will be buffered. Set the flag to indicate this. - m_bEnvelopeEnded = false; - m_nPhasePosition -= 16; - } - } - else // (m_nPhasePosition < 16) - { - // still within the same phase; - // but, importantly, we are no longer at the start of the phase ... - // so new data cannot be acted on immediately, and must - // be buffered - m_bEnvelopeEnded = false; - // Phase and PhasePosition have already been updated. - // SetLevels() will need to be called to actually calculate - // the output 'level' of this envelope controller - } - - - // if we have new (buffered) data, now is the time to act on it - if (m_bNewData && bProcessNewDataIfAvailable) - { - m_bNewData = false; - SetNewEnvData(m_nNextData); - } - else - { - // ok, we didn't have any new buffered date to act on, - // so we just call SetLevels() to calculate the output level - // for whatever the current envelope is - SetLevels(); - } - -} - -inline void CSAAEnv::SetLevels(void) -{ - // sets m_nLeftLevel - // Also sets m_nRightLevel in terms of m_nLeftLevel - // and m_bInvertRightChannel - - // m_nResolution: 1 means 4-bit resolution; 2 means 3-bit resolution. Resolution of envelope waveform. - - // Note that this is handled 'immediately', and doesn't wait for synchronisation of - // the envelope waveform (this is important, see test case EnvExt_imm) - // It is therefore possible to switch between 4-bit and 3-bit resolution in the middle of - // an envelope waveform. if you are at an 'odd' phase position, you would be able to hear - // the difference. if you are at an 'even' phase position, the volume level for 4-bit - // and 3-bit would be the same. - // NOTE: additional test cases are required. - - switch (m_nResolution) - { - case 1: // 4 bit res waveforms - default: - { - // special case: if envelope is not a looping one, and we're at the end - // then our level should be zero (all of the non-looping waveforms have - // a sustain level of zero): - if (m_bEnvelopeEnded && !m_bLooping) - m_nLeftLevel = 0; - else - m_nLeftLevel = m_pEnvData->nLevels[0][m_nPhase][m_nPhasePosition]; - - if (m_bInvertRightChannel) - m_nRightLevel = 15-m_nLeftLevel; - else - m_nRightLevel = m_nLeftLevel; - break; - } - case 2: // 3 bit res waveforms - { - // special case: if envelope is not a looping one, and we're at the end - // then our level should be zero (all of the non-looping waveforms have - // a sustain level of zero): - if (m_bEnvelopeEnded && !m_bLooping) - m_nLeftLevel = 0; - else - m_nLeftLevel = m_pEnvData->nLevels[1][m_nPhase][m_nPhasePosition]; - if (m_bInvertRightChannel) - m_nRightLevel = 14-m_nLeftLevel; - else - m_nRightLevel = m_nLeftLevel; - break; - } - } -} - - -inline void CSAAEnv::SetNewEnvData(int nData) -{ - // loads envgenerator's registers according to the bits set - // in nData - - m_nPhase = 0; - m_nPhasePosition = 0; - m_pEnvData = &(cs_EnvData[(nData >> 1) & 0x07]); - m_bInvertRightChannel = ((nData & 0x01) == 0x01); - m_bClockExternally = ((nData & 0x20) == 0x20); - m_nNumberOfPhases = m_pEnvData->nNumberOfPhases; - m_bLooping = m_pEnvData->bLooping; - m_nResolution = (((nData & 0x10)==0x10) ? 2 : 1); - m_bEnabled = ((nData & 0x80) == 0x80); - if (m_bEnabled) - { - m_bEnvelopeEnded = false; - // is this right? - // YES. See test case EnvExt_34c (setting data multiple times - // when at a point (3) resets the waveform so you're no longer - // at a point (3). - } - else - { - // DISABLED - so set stuff accordingly - m_bEnvelopeEnded = true; - m_nPhase = 0; - m_nPhasePosition = 0; - } - - SetLevels(); -} diff --git a/src/sound/saasound/SAAEnv.h b/src/sound/saasound/SAAEnv.h deleted file mode 100755 index 131659c06..000000000 --- a/src/sound/saasound/SAAEnv.h +++ /dev/null @@ -1,54 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// SAAEnv.h: interface for the CSAAEnv class. -// -////////////////////////////////////////////////////////////////////// - -#ifndef SAAENV_H_INCLUDED -#define SAAENV_H_INCLUDED - -class CSAAEnv -{ -private: - int m_nLeftLevel, m_nRightLevel; - ENVDATA const * m_pEnvData; - - bool m_bEnabled; - bool m_bInvertRightChannel; - BYTE m_nPhase; - BYTE m_nPhasePosition; - bool m_bEnvelopeEnded; - char m_nPhaseAdd[2]; - char m_nCurrentPhaseAdd; - bool m_bLooping; - char m_nNumberOfPhases; - char m_nResolution; - char m_nInitialLevel; - bool m_bNewData; - BYTE m_nNextData; - bool m_bClockExternally; - static const ENVDATA cs_EnvData[8]; - - void Tick(void); - void SetLevels(void); - void SetNewEnvData(int nData); - -public: - CSAAEnv(); - ~CSAAEnv(); - - void InternalClock(void); - void ExternalClock(void); - void SetEnvControl(int nData); // really just a BYTE - int LeftLevel(void) const; - int RightLevel(void) const; - bool IsActive(void) const; - -}; - -inline bool CSAAEnv::IsActive(void) const -{ - return m_bEnabled; -} - -#endif // SAAENV_H_INCLUDED diff --git a/src/sound/saasound/SAAFreq.cpp b/src/sound/saasound/SAAFreq.cpp deleted file mode 100755 index 61a04f6ad..000000000 --- a/src/sound/saasound/SAAFreq.cpp +++ /dev/null @@ -1,287 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// SAAFreq.cpp: implementation of the CSAAFreq class. -// only 7-bit fractional accuracy on oscillator periods. I may consider fixing that. -// -////////////////////////////////////////////////////////////////////// - -#include "SAASound.h" -#include "types.h" -#include "SAANoise.h" -#include "SAAEnv.h" -#include "SAAFreq.h" -#include "defns.h" - -#ifdef SAAFREQ_FIXED_CLOCKRATE -// 'load in' the data for the static frequency lookup table -// precomputed for a fixed clockrate -// See: tools/freqdat.py -const unsigned long CSAAFreq::m_FreqTable[2048] = { -#include "SAAFreq.dat" -}; -#else -unsigned long CSAAFreq::m_FreqTable[2048]; -unsigned long CSAAFreq::m_nClockRate = 0; -#endif // SAAFREQ_FIXED_CLOCKRATE - -const int INITIAL_LEVEL = 1; - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -CSAAFreq::CSAAFreq(CSAANoise * const NoiseGenerator, CSAAEnv * const EnvGenerator) -: -m_nCounter(0), -m_nAdd(0), -m_nCounter_low(0), -m_nOversample(0), -m_nCounterLimit_low(1), -m_nLevel(INITIAL_LEVEL), -m_nCurrentOffset(0), -m_nCurrentOctave(0), -m_nNextOffset(0), -m_nNextOctave(0), -m_bIgnoreOffsetData(false), -m_bNewData(false), -m_bSync(false), -m_nSampleRate(SAMPLE_RATE_HZ), -m_pcConnectedNoiseGenerator(NoiseGenerator), -m_pcConnectedEnvGenerator(EnvGenerator), -m_nConnectedMode((NoiseGenerator == NULL) ? ((EnvGenerator == NULL) ? 0 : 1) : 2) -{ - _SetClockRate(EXTERNAL_CLK_HZ); - SetAdd(); // current octave, current offset -} - -CSAAFreq::~CSAAFreq() -{ - // Nothing to do -} - -void CSAAFreq::SetFreqOffset(BYTE nOffset) -{ - // nOffset between 0 and 255 - - if (!m_bSync) - { - m_nNextOffset = nOffset; - m_bNewData=true; - if (m_nNextOctave==m_nCurrentOctave) - { - // According to Philips, if you send the SAA-1099 - // new Octave data and then new Offset data in that - // order, on the next half-cycle of the current frequency - // generator, ONLY the octave data is acted upon. - // The offset data will be acted upon next time. - - // ?? TEST CASE : if you set the octave and then the offset - // but the octave you set it to is the same one it already was. - // Will this ignore the offset data? - // Do you get the same behaviour if you set offset THEN octave - // even if you set octave to the same value it was before? - - m_bIgnoreOffsetData=true; - } - } - else - { - // updates straightaway if m_bSync - m_bNewData=false; - m_bIgnoreOffsetData = false; - m_nCurrentOffset = nOffset; - m_nNextOffset = nOffset; - m_nCurrentOctave = m_nNextOctave; - SetAdd(); - } - -} - -void CSAAFreq::SetFreqOctave(BYTE nOctave) -{ - // nOctave between 0 and 7 - - if (!m_bSync) - { - m_nNextOctave = nOctave; - m_bNewData=true; - m_bIgnoreOffsetData = false; - } - else - { - // updates straightaway if m_bSync - m_bNewData=false; - m_bIgnoreOffsetData = false; - m_nCurrentOctave = nOctave; - m_nNextOctave = nOctave; - m_nCurrentOffset = m_nNextOffset; - SetAdd(); - } -} - -void CSAAFreq::UpdateOctaveOffsetData(void) -{ - // loads the buffered new octave and new offset data into the current registers - // and sets up the new frequency for this frequency generator (i.e. sets up m_nAdd) - // - called during Sync, and called when waveform half-cycle completes - - // How the SAA-1099 really treats new data: - // if only new octave data is present, - // then set new period based on just the octave data - // Otherwise, if only new offset data is present, - // then set new period based on just the offset data - // Otherwise, if new octave data is present, and new offset data is present, - // and the offset data was set BEFORE the octave data, - // then set new period based on both the octave and offset data - // Else, if the offset data came AFTER the new octave data - // then set new period based on JUST THE OCTAVE DATA, and continue - // signalling the offset data as 'new', so it will be acted upon - // next half-cycle - // - // Weird, I know. But that's how it works. Philips even documented as much. - - if (!m_bNewData) - { - // optimise for the most common case! No new data! - return; - } - - m_nCurrentOctave=m_nNextOctave; - if (!m_bIgnoreOffsetData) - { - m_nCurrentOffset=m_nNextOffset; - m_bNewData=false; - } - m_bIgnoreOffsetData=false; - - SetAdd(); -} - -void CSAAFreq::_SetSampleRate(unsigned int nSampleRate) -{ - m_nSampleRate = nSampleRate; -} - -void CSAAFreq::_SetOversample(unsigned int oversample) -{ - // oversample is a power of 2 i.e. - // if oversample == 2 then 4x oversample - // if oversample == 6 then 64x oversample - if (oversample < m_nOversample) - { - m_nCounter_low <<= (m_nOversample - oversample); - } - else - { - m_nCounter_low >>= (oversample - m_nOversample); - } - - m_nCounterLimit_low = 1<= (m_nSampleRate<<12)) - { - m_nCounter -= (m_nSampleRate<<12); - m_nCounter_low++; - if (m_nCounter_low >= m_nCounterLimit_low) - { - // period elapsed for (at least) one half-cycle of - // current frequency - m_nCounter_low = 0; - // flip state - from 0 to 1 or vice versa - m_nLevel = 1 - m_nLevel; - - // trigger any connected devices - switch (m_nConnectedMode) - { - case 1: - // env trigger - m_pcConnectedEnvGenerator->InternalClock(); - break; - - case 2: - // noise trigger - m_pcConnectedNoiseGenerator->Trigger(); - break; - - default: - // do nothing - break; - } - - // get new frequency (set period length m_nAdd) if new data is waiting: - UpdateOctaveOffsetData(); - } - } - - return m_nLevel; -} - -void CSAAFreq::SetAdd(void) -{ - // nOctave between 0 and 7; nOffset between 0 and 255 - - // Used to be: - // m_nAdd = (15625 << nOctave) / (511 - nOffset); - // Now just table lookup: - m_nAdd = m_FreqTable[m_nCurrentOctave<<8 | m_nCurrentOffset]; -} - -void CSAAFreq::Sync(bool bSync) -{ - m_bSync = bSync; - - // update straightaway if m_bSync - if (m_bSync) - { - m_nCounter = 0; - m_nCounter_low = 0; - - // this seems to need to be required to make the Fred59 SPACE DEMO audio work correctly - m_nLevel = INITIAL_LEVEL; - - m_nCurrentOctave=m_nNextOctave; - m_nCurrentOffset=m_nNextOffset; - SetAdd(); - } -} diff --git a/src/sound/saasound/SAAFreq.dat b/src/sound/saasound/SAAFreq.dat deleted file mode 100755 index 04fb9081a..000000000 --- a/src/sound/saasound/SAAFreq.dat +++ /dev/null @@ -1,141 +0,0 @@ -/* -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// Precalculated oscillator frequency period steps -// Higher scaling for better accuracy. -// -// After construction, it's important to SetSampleRate before -// trying to use the generator. -// (Just because the CSAANoise object has a default samplerate -// doesn't mean you should rely on it) -// -////////////////////////////////////////////////////////////////////// -*/ - 250489 , 250980 , 251473 , 251969 , 252465 , 252964 , 253465 , 253968 , 254473 , 254980 , 255489 , 256000 , 256513 , 257028 , 257545 , 258065 , - 258586 , 259109 , 259635 , 260163 , 260692 , 261224 , 261759 , 262295 , 262834 , 263374 , 263918 , 264463 , 265010 , 265560 , 266112 , 266667 , - 267223 , 267782 , 268344 , 268908 , 269474 , 270042 , 270613 , 271186 , 271762 , 272340 , 272921 , 273504 , 274090 , 274678 , 275269 , 275862 , - 276458 , 277056 , 277657 , 278261 , 278867 , 279476 , 280088 , 280702 , 281319 , 281938 , 282561 , 283186 , 283814 , 284444 , 285078 , 285714 , - 286353 , 286996 , 287640 , 288288 , 288939 , 289593 , 290249 , 290909 , 291572 , 292237 , 292906 , 293578 , 294253 , 294931 , 295612 , 296296 , - 296984 , 297674 , 298368 , 299065 , 299766 , 300469 , 301176 , 301887 , 302600 , 303318 , 304038 , 304762 , 305489 , 306220 , 306954 , 307692 , - 308434 , 309179 , 309927 , 310680 , 311436 , 312195 , 312958 , 313725 , 314496 , 315271 , 316049 , 316832 , 317618 , 318408 , 319202 , 320000 , - 320802 , 321608 , 322418 , 323232 , 324051 , 324873 , 325700 , 326531 , 327366 , 328205 , 329049 , 329897 , 330749 , 331606 , 332468 , 333333 , - 334204 , 335079 , 335958 , 336842 , 337731 , 338624 , 339523 , 340426 , 341333 , 342246 , 343164 , 344086 , 345013 , 345946 , 346883 , 347826 , - 348774 , 349727 , 350685 , 351648 , 352617 , 353591 , 354571 , 355556 , 356546 , 357542 , 358543 , 359551 , 360563 , 361582 , 362606 , 363636 , - 364672 , 365714 , 366762 , 367816 , 368876 , 369942 , 371014 , 372093 , 373178 , 374269 , 375367 , 376471 , 377581 , 378698 , 379822 , 380952 , - 382090 , 383234 , 384384 , 385542 , 386707 , 387879 , 389058 , 390244 , 391437 , 392638 , 393846 , 395062 , 396285 , 397516 , 398754 , 400000 , - 401254 , 402516 , 403785 , 405063 , 406349 , 407643 , 408946 , 410256 , 411576 , 412903 , 414239 , 415584 , 416938 , 418301 , 419672 , 421053 , - 422442 , 423841 , 425249 , 426667 , 428094 , 429530 , 430976 , 432432 , 433898 , 435374 , 436860 , 438356 , 439863 , 441379 , 442907 , 444444 , - 445993 , 447552 , 449123 , 450704 , 452297 , 453901 , 455516 , 457143 , 458781 , 460432 , 462094 , 463768 , 465455 , 467153 , 468864 , 470588 , - 472325 , 474074 , 475836 , 477612 , 479401 , 481203 , 483019 , 484848 , 486692 , 488550 , 490421 , 492308 , 494208 , 496124 , 498054 , 500000 , - 500978 , 501961 , 502947 , 503937 , 504931 , 505929 , 506931 , 507937 , 508946 , 509960 , 510978 , 512000 , 513026 , 514056 , 515091 , 516129 , - 517172 , 518219 , 519270 , 520325 , 521385 , 522449 , 523517 , 524590 , 525667 , 526749 , 527835 , 528926 , 530021 , 531120 , 532225 , 533333 , - 534447 , 535565 , 536688 , 537815 , 538947 , 540084 , 541226 , 542373 , 543524 , 544681 , 545842 , 547009 , 548180 , 549356 , 550538 , 551724 , - 552916 , 554113 , 555315 , 556522 , 557734 , 558952 , 560175 , 561404 , 562637 , 563877 , 565121 , 566372 , 567627 , 568889 , 570156 , 571429 , - 572707 , 573991 , 575281 , 576577 , 577878 , 579186 , 580499 , 581818 , 583144 , 584475 , 585812 , 587156 , 588506 , 589862 , 591224 , 592593 , - 593968 , 595349 , 596737 , 598131 , 599532 , 600939 , 602353 , 603774 , 605201 , 606635 , 608076 , 609524 , 610979 , 612440 , 613909 , 615385 , - 616867 , 618357 , 619855 , 621359 , 622871 , 624390 , 625917 , 627451 , 628993 , 630542 , 632099 , 633663 , 635236 , 636816 , 638404 , 640000 , - 641604 , 643216 , 644836 , 646465 , 648101 , 649746 , 651399 , 653061 , 654731 , 656410 , 658098 , 659794 , 661499 , 663212 , 664935 , 666667 , - 668407 , 670157 , 671916 , 673684 , 675462 , 677249 , 679045 , 680851 , 682667 , 684492 , 686327 , 688172 , 690027 , 691892 , 693767 , 695652 , - 697548 , 699454 , 701370 , 703297 , 705234 , 707182 , 709141 , 711111 , 713092 , 715084 , 717087 , 719101 , 721127 , 723164 , 725212 , 727273 , - 729345 , 731429 , 733524 , 735632 , 737752 , 739884 , 742029 , 744186 , 746356 , 748538 , 750733 , 752941 , 755162 , 757396 , 759644 , 761905 , - 764179 , 766467 , 768769 , 771084 , 773414 , 775758 , 778116 , 780488 , 782875 , 785276 , 787692 , 790123 , 792570 , 795031 , 797508 , 800000 , - 802508 , 805031 , 807571 , 810127 , 812698 , 815287 , 817891 , 820513 , 823151 , 825806 , 828479 , 831169 , 833876 , 836601 , 839344 , 842105 , - 844884 , 847682 , 850498 , 853333 , 856187 , 859060 , 861953 , 864865 , 867797 , 870748 , 873720 , 876712 , 879725 , 882759 , 885813 , 888889 , - 891986 , 895105 , 898246 , 901408 , 904594 , 907801 , 911032 , 914286 , 917563 , 920863 , 924188 , 927536 , 930909 , 934307 , 937729 , 941176 , - 944649 , 948148 , 951673 , 955224 , 958801 , 962406 , 966038 , 969697 , 973384 , 977099 , 980843 , 984615 , 988417 , 992248 , 996109 , 1000000 , - 1001957 , 1003922 , 1005894 , 1007874 , 1009862 , 1011858 , 1013861 , 1015873 , 1017893 , 1019920 , 1021956 , 1024000 , 1026052 , 1028112 , 1030181 , 1032258 , - 1034343 , 1036437 , 1038540 , 1040650 , 1042770 , 1044898 , 1047035 , 1049180 , 1051335 , 1053498 , 1055670 , 1057851 , 1060041 , 1062241 , 1064449 , 1066667 , - 1068894 , 1071130 , 1073375 , 1075630 , 1077895 , 1080169 , 1082452 , 1084746 , 1087049 , 1089362 , 1091684 , 1094017 , 1096360 , 1098712 , 1101075 , 1103448 , - 1105832 , 1108225 , 1110629 , 1113043 , 1115468 , 1117904 , 1120350 , 1122807 , 1125275 , 1127753 , 1130243 , 1132743 , 1135255 , 1137778 , 1140312 , 1142857 , - 1145414 , 1147982 , 1150562 , 1153153 , 1155756 , 1158371 , 1160998 , 1163636 , 1166287 , 1168950 , 1171625 , 1174312 , 1177011 , 1179724 , 1182448 , 1185185 , - 1187935 , 1190698 , 1193473 , 1196262 , 1199063 , 1201878 , 1204706 , 1207547 , 1210402 , 1213270 , 1216152 , 1219048 , 1221957 , 1224880 , 1227818 , 1230769 , - 1233735 , 1236715 , 1239709 , 1242718 , 1245742 , 1248780 , 1251834 , 1254902 , 1257985 , 1261084 , 1264198 , 1267327 , 1270471 , 1273632 , 1276808 , 1280000 , - 1283208 , 1286432 , 1289673 , 1292929 , 1296203 , 1299492 , 1302799 , 1306122 , 1309463 , 1312821 , 1316195 , 1319588 , 1322997 , 1326425 , 1329870 , 1333333 , - 1336815 , 1340314 , 1343832 , 1347368 , 1350923 , 1354497 , 1358090 , 1361702 , 1365333 , 1368984 , 1372654 , 1376344 , 1380054 , 1383784 , 1387534 , 1391304 , - 1395095 , 1398907 , 1402740 , 1406593 , 1410468 , 1414365 , 1418283 , 1422222 , 1426184 , 1430168 , 1434174 , 1438202 , 1442254 , 1446328 , 1450425 , 1454545 , - 1458689 , 1462857 , 1467049 , 1471264 , 1475504 , 1479769 , 1484058 , 1488372 , 1492711 , 1497076 , 1501466 , 1505882 , 1510324 , 1514793 , 1519288 , 1523810 , - 1528358 , 1532934 , 1537538 , 1542169 , 1546828 , 1551515 , 1556231 , 1560976 , 1565749 , 1570552 , 1575385 , 1580247 , 1585139 , 1590062 , 1595016 , 1600000 , - 1605016 , 1610063 , 1615142 , 1620253 , 1625397 , 1630573 , 1635783 , 1641026 , 1646302 , 1651613 , 1656958 , 1662338 , 1667752 , 1673203 , 1678689 , 1684211 , - 1689769 , 1695364 , 1700997 , 1706667 , 1712375 , 1718121 , 1723906 , 1729730 , 1735593 , 1741497 , 1747440 , 1753425 , 1759450 , 1765517 , 1771626 , 1777778 , - 1783972 , 1790210 , 1796491 , 1802817 , 1809187 , 1815603 , 1822064 , 1828571 , 1835125 , 1841727 , 1848375 , 1855072 , 1861818 , 1868613 , 1875458 , 1882353 , - 1889299 , 1896296 , 1903346 , 1910448 , 1917603 , 1924812 , 1932075 , 1939394 , 1946768 , 1954198 , 1961686 , 1969231 , 1976834 , 1984496 , 1992218 , 2000000 , - 2003914 , 2007843 , 2011788 , 2015748 , 2019724 , 2023715 , 2027723 , 2031746 , 2035785 , 2039841 , 2043912 , 2048000 , 2052104 , 2056225 , 2060362 , 2064516 , - 2068687 , 2072874 , 2077079 , 2081301 , 2085540 , 2089796 , 2094070 , 2098361 , 2102669 , 2106996 , 2111340 , 2115702 , 2120083 , 2124481 , 2128898 , 2133333 , - 2137787 , 2142259 , 2146751 , 2151261 , 2155789 , 2160338 , 2164905 , 2169492 , 2174098 , 2178723 , 2183369 , 2188034 , 2192719 , 2197425 , 2202151 , 2206897 , - 2211663 , 2216450 , 2221258 , 2226087 , 2230937 , 2235808 , 2240700 , 2245614 , 2250549 , 2255507 , 2260486 , 2265487 , 2270510 , 2275556 , 2280624 , 2285714 , - 2290828 , 2295964 , 2301124 , 2306306 , 2311512 , 2316742 , 2321995 , 2327273 , 2332574 , 2337900 , 2343249 , 2348624 , 2354023 , 2359447 , 2364896 , 2370370 , - 2375870 , 2381395 , 2386946 , 2392523 , 2398126 , 2403756 , 2409412 , 2415094 , 2420804 , 2426540 , 2432304 , 2438095 , 2443914 , 2449761 , 2455635 , 2461538 , - 2467470 , 2473430 , 2479419 , 2485437 , 2491484 , 2497561 , 2503667 , 2509804 , 2515971 , 2522167 , 2528395 , 2534653 , 2540943 , 2547264 , 2553616 , 2560000 , - 2566416 , 2572864 , 2579345 , 2585859 , 2592405 , 2598985 , 2605598 , 2612245 , 2618926 , 2625641 , 2632391 , 2639175 , 2645995 , 2652850 , 2659740 , 2666667 , - 2673629 , 2680628 , 2687664 , 2694737 , 2701847 , 2708995 , 2716180 , 2723404 , 2730667 , 2737968 , 2745308 , 2752688 , 2760108 , 2767568 , 2775068 , 2782609 , - 2790191 , 2797814 , 2805479 , 2813187 , 2820937 , 2828729 , 2836565 , 2844444 , 2852368 , 2860335 , 2868347 , 2876404 , 2884507 , 2892655 , 2900850 , 2909091 , - 2917379 , 2925714 , 2934097 , 2942529 , 2951009 , 2959538 , 2968116 , 2976744 , 2985423 , 2994152 , 3002933 , 3011765 , 3020649 , 3029586 , 3038576 , 3047619 , - 3056716 , 3065868 , 3075075 , 3084337 , 3093656 , 3103030 , 3112462 , 3121951 , 3131498 , 3141104 , 3150769 , 3160494 , 3170279 , 3180124 , 3190031 , 3200000 , - 3210031 , 3220126 , 3230284 , 3240506 , 3250794 , 3261146 , 3271565 , 3282051 , 3292605 , 3303226 , 3313916 , 3324675 , 3335505 , 3346405 , 3357377 , 3368421 , - 3379538 , 3390728 , 3401993 , 3413333 , 3424749 , 3436242 , 3447811 , 3459459 , 3471186 , 3482993 , 3494881 , 3506849 , 3518900 , 3531034 , 3543253 , 3555556 , - 3567944 , 3580420 , 3592982 , 3605634 , 3618375 , 3631206 , 3644128 , 3657143 , 3670251 , 3683453 , 3696751 , 3710145 , 3723636 , 3737226 , 3750916 , 3764706 , - 3778598 , 3792593 , 3806691 , 3820896 , 3835206 , 3849624 , 3864151 , 3878788 , 3893536 , 3908397 , 3923372 , 3938462 , 3953668 , 3968992 , 3984436 , 4000000 , - 4007828 , 4015686 , 4023576 , 4031496 , 4039448 , 4047431 , 4055446 , 4063492 , 4071571 , 4079681 , 4087824 , 4096000 , 4104208 , 4112450 , 4120724 , 4129032 , - 4137374 , 4145749 , 4154158 , 4162602 , 4171079 , 4179592 , 4188139 , 4196721 , 4205339 , 4213992 , 4222680 , 4231405 , 4240166 , 4248963 , 4257796 , 4266667 , - 4275574 , 4284519 , 4293501 , 4302521 , 4311579 , 4320675 , 4329810 , 4338983 , 4348195 , 4357447 , 4366738 , 4376068 , 4385439 , 4394850 , 4404301 , 4413793 , - 4423326 , 4432900 , 4442516 , 4452174 , 4461874 , 4471616 , 4481400 , 4491228 , 4501099 , 4511013 , 4520971 , 4530973 , 4541020 , 4551111 , 4561247 , 4571429 , - 4581655 , 4591928 , 4602247 , 4612613 , 4623025 , 4633484 , 4643991 , 4654545 , 4665148 , 4675799 , 4686499 , 4697248 , 4708046 , 4718894 , 4729792 , 4740741 , - 4751740 , 4762791 , 4773893 , 4785047 , 4796253 , 4807512 , 4818824 , 4830189 , 4841608 , 4853081 , 4864608 , 4876190 , 4887828 , 4899522 , 4911271 , 4923077 , - 4934940 , 4946860 , 4958838 , 4970874 , 4982968 , 4995122 , 5007335 , 5019608 , 5031941 , 5044335 , 5056790 , 5069307 , 5081886 , 5094527 , 5107232 , 5120000 , - 5132832 , 5145729 , 5158690 , 5171717 , 5184810 , 5197970 , 5211196 , 5224490 , 5237852 , 5251282 , 5264781 , 5278351 , 5291990 , 5305699 , 5319481 , 5333333 , - 5347258 , 5361257 , 5375328 , 5389474 , 5403694 , 5417989 , 5432361 , 5446809 , 5461333 , 5475936 , 5490617 , 5505376 , 5520216 , 5535135 , 5550136 , 5565217 , - 5580381 , 5595628 , 5610959 , 5626374 , 5641873 , 5657459 , 5673130 , 5688889 , 5704735 , 5720670 , 5736695 , 5752809 , 5769014 , 5785311 , 5801700 , 5818182 , - 5834758 , 5851429 , 5868195 , 5885057 , 5902017 , 5919075 , 5936232 , 5953488 , 5970845 , 5988304 , 6005865 , 6023529 , 6041298 , 6059172 , 6077151 , 6095238 , - 6113433 , 6131737 , 6150150 , 6168675 , 6187311 , 6206061 , 6224924 , 6243902 , 6262997 , 6282209 , 6301538 , 6320988 , 6340557 , 6360248 , 6380062 , 6400000 , - 6420063 , 6440252 , 6460568 , 6481013 , 6501587 , 6522293 , 6543131 , 6564103 , 6585209 , 6606452 , 6627832 , 6649351 , 6671010 , 6692810 , 6714754 , 6736842 , - 6759076 , 6781457 , 6803987 , 6826667 , 6849498 , 6872483 , 6895623 , 6918919 , 6942373 , 6965986 , 6989761 , 7013699 , 7037801 , 7062069 , 7086505 , 7111111 , - 7135889 , 7160839 , 7185965 , 7211268 , 7236749 , 7262411 , 7288256 , 7314286 , 7340502 , 7366906 , 7393502 , 7420290 , 7447273 , 7474453 , 7501832 , 7529412 , - 7557196 , 7585185 , 7613383 , 7641791 , 7670412 , 7699248 , 7728302 , 7757576 , 7787072 , 7816794 , 7846743 , 7876923 , 7907336 , 7937984 , 7968872 , 8000000 , - 8015656 , 8031373 , 8047151 , 8062992 , 8078895 , 8094862 , 8110891 , 8126984 , 8143141 , 8159363 , 8175649 , 8192000 , 8208417 , 8224900 , 8241449 , 8258065 , - 8274747 , 8291498 , 8308316 , 8325203 , 8342159 , 8359184 , 8376278 , 8393443 , 8410678 , 8427984 , 8445361 , 8462810 , 8480331 , 8497925 , 8515593 , 8533333 , - 8551148 , 8569038 , 8587002 , 8605042 , 8623158 , 8641350 , 8659619 , 8677966 , 8696391 , 8714894 , 8733475 , 8752137 , 8770878 , 8789700 , 8808602 , 8827586 , - 8846652 , 8865801 , 8885033 , 8904348 , 8923747 , 8943231 , 8962801 , 8982456 , 9002198 , 9022026 , 9041943 , 9061947 , 9082040 , 9102222 , 9122494 , 9142857 , - 9163311 , 9183857 , 9204494 , 9225225 , 9246050 , 9266968 , 9287982 , 9309091 , 9330296 , 9351598 , 9372998 , 9394495 , 9416092 , 9437788 , 9459584 , 9481481 , - 9503480 , 9525581 , 9547786 , 9570093 , 9592506 , 9615023 , 9637647 , 9660377 , 9683215 , 9706161 , 9729216 , 9752381 , 9775656 , 9799043 , 9822542 , 9846154 , - 9869880 , 9893720 , 9917676 , 9941748 , 9965937 , 9990244 , 10014670 , 10039216 , 10063882 , 10088670 , 10113580 , 10138614 , 10163772 , 10189055 , 10214464 , 10240000 , - 10265664 , 10291457 , 10317380 , 10343434 , 10369620 , 10395939 , 10422392 , 10448980 , 10475703 , 10502564 , 10529563 , 10556701 , 10583979 , 10611399 , 10638961 , 10666667 , - 10694517 , 10722513 , 10750656 , 10778947 , 10807388 , 10835979 , 10864721 , 10893617 , 10922667 , 10951872 , 10981233 , 11010753 , 11040431 , 11070270 , 11100271 , 11130435 , - 11160763 , 11191257 , 11221918 , 11252747 , 11283747 , 11314917 , 11346260 , 11377778 , 11409471 , 11441341 , 11473389 , 11505618 , 11538028 , 11570621 , 11603399 , 11636364 , - 11669516 , 11702857 , 11736390 , 11770115 , 11804035 , 11838150 , 11872464 , 11906977 , 11941691 , 11976608 , 12011730 , 12047059 , 12082596 , 12118343 , 12154303 , 12190476 , - 12226866 , 12263473 , 12300300 , 12337349 , 12374622 , 12412121 , 12449848 , 12487805 , 12525994 , 12564417 , 12603077 , 12641975 , 12681115 , 12720497 , 12760125 , 12800000 , - 12840125 , 12880503 , 12921136 , 12962025 , 13003175 , 13044586 , 13086262 , 13128205 , 13170418 , 13212903 , 13255663 , 13298701 , 13342020 , 13385621 , 13429508 , 13473684 , - 13518152 , 13562914 , 13607973 , 13653333 , 13698997 , 13744966 , 13791246 , 13837838 , 13884746 , 13931973 , 13979522 , 14027397 , 14075601 , 14124138 , 14173010 , 14222222 , - 14271777 , 14321678 , 14371930 , 14422535 , 14473498 , 14524823 , 14576512 , 14628571 , 14681004 , 14733813 , 14787004 , 14840580 , 14894545 , 14948905 , 15003663 , 15058824 , - 15114391 , 15170370 , 15226766 , 15283582 , 15340824 , 15398496 , 15456604 , 15515152 , 15574144 , 15633588 , 15693487 , 15753846 , 15814672 , 15875969 , 15937743 , 16000000 , - 16031311 , 16062745 , 16094303 , 16125984 , 16157791 , 16189723 , 16221782 , 16253968 , 16286282 , 16318725 , 16351297 , 16384000 , 16416834 , 16449799 , 16482897 , 16516129 , - 16549495 , 16582996 , 16616633 , 16650407 , 16684318 , 16718367 , 16752556 , 16786885 , 16821355 , 16855967 , 16890722 , 16925620 , 16960663 , 16995851 , 17031185 , 17066667 , - 17102296 , 17138075 , 17174004 , 17210084 , 17246316 , 17282700 , 17319239 , 17355932 , 17392781 , 17429787 , 17466951 , 17504274 , 17541756 , 17579399 , 17617204 , 17655172 , - 17693305 , 17731602 , 17770065 , 17808696 , 17847495 , 17886463 , 17925602 , 17964912 , 18004396 , 18044053 , 18083885 , 18123894 , 18164080 , 18204444 , 18244989 , 18285714 , - 18326622 , 18367713 , 18408989 , 18450450 , 18492099 , 18533937 , 18575964 , 18618182 , 18660592 , 18703196 , 18745995 , 18788991 , 18832184 , 18875576 , 18919169 , 18962963 , - 19006961 , 19051163 , 19095571 , 19140187 , 19185012 , 19230047 , 19275294 , 19320755 , 19366430 , 19412322 , 19458432 , 19504762 , 19551313 , 19598086 , 19645084 , 19692308 , - 19739759 , 19787440 , 19835351 , 19883495 , 19931873 , 19980488 , 20029340 , 20078431 , 20127764 , 20177340 , 20227160 , 20277228 , 20327543 , 20378109 , 20428928 , 20480000 , - 20531328 , 20582915 , 20634761 , 20686869 , 20739241 , 20791878 , 20844784 , 20897959 , 20951407 , 21005128 , 21059126 , 21113402 , 21167959 , 21222798 , 21277922 , 21333333 , - 21389034 , 21445026 , 21501312 , 21557895 , 21614776 , 21671958 , 21729443 , 21787234 , 21845333 , 21903743 , 21962466 , 22021505 , 22080863 , 22140541 , 22200542 , 22260870 , - 22321526 , 22382514 , 22443836 , 22505495 , 22567493 , 22629834 , 22692521 , 22755556 , 22818942 , 22882682 , 22946779 , 23011236 , 23076056 , 23141243 , 23206799 , 23272727 , - 23339031 , 23405714 , 23472779 , 23540230 , 23608069 , 23676301 , 23744928 , 23813953 , 23883382 , 23953216 , 24023460 , 24094118 , 24165192 , 24236686 , 24308605 , 24380952 , - 24453731 , 24526946 , 24600601 , 24674699 , 24749245 , 24824242 , 24899696 , 24975610 , 25051988 , 25128834 , 25206154 , 25283951 , 25362229 , 25440994 , 25520249 , 25600000 , - 25680251 , 25761006 , 25842271 , 25924051 , 26006349 , 26089172 , 26172524 , 26256410 , 26340836 , 26425806 , 26511327 , 26597403 , 26684039 , 26771242 , 26859016 , 26947368 , - 27036304 , 27125828 , 27215947 , 27306667 , 27397993 , 27489933 , 27582492 , 27675676 , 27769492 , 27863946 , 27959044 , 28054795 , 28151203 , 28248276 , 28346021 , 28444444 , - 28543554 , 28643357 , 28743860 , 28845070 , 28946996 , 29049645 , 29153025 , 29257143 , 29362007 , 29467626 , 29574007 , 29681159 , 29789091 , 29897810 , 30007326 , 30117647 , - 30228782 , 30340741 , 30453532 , 30567164 , 30681648 , 30796992 , 30913208 , 31030303 , 31148289 , 31267176 , 31386973 , 31507692 , 31629344 , 31751938 , 31875486 , 32000000 , - 32062622 , 32125490 , 32188605 , 32251969 , 32315582 , 32379447 , 32443564 , 32507937 , 32572565 , 32637450 , 32702595 , 32768000 , 32833667 , 32899598 , 32965795 , 33032258 , - 33098990 , 33165992 , 33233266 , 33300813 , 33368635 , 33436735 , 33505112 , 33573770 , 33642710 , 33711934 , 33781443 , 33851240 , 33921325 , 33991701 , 34062370 , 34133333 , - 34204593 , 34276151 , 34348008 , 34420168 , 34492632 , 34565401 , 34638478 , 34711864 , 34785563 , 34859574 , 34933902 , 35008547 , 35083512 , 35158798 , 35234409 , 35310345 , - 35386609 , 35463203 , 35540130 , 35617391 , 35694989 , 35772926 , 35851204 , 35929825 , 36008791 , 36088106 , 36167770 , 36247788 , 36328160 , 36408889 , 36489978 , 36571429 , - 36653244 , 36735426 , 36817978 , 36900901 , 36984199 , 37067873 , 37151927 , 37236364 , 37321185 , 37406393 , 37491991 , 37577982 , 37664368 , 37751152 , 37838337 , 37925926 , - 38013921 , 38102326 , 38191142 , 38280374 , 38370023 , 38460094 , 38550588 , 38641509 , 38732861 , 38824645 , 38916865 , 39009524 , 39102625 , 39196172 , 39290168 , 39384615 , - 39479518 , 39574879 , 39670702 , 39766990 , 39863747 , 39960976 , 40058680 , 40156863 , 40255528 , 40354680 , 40454321 , 40554455 , 40655087 , 40756219 , 40857855 , 40960000 , - 41062657 , 41165829 , 41269521 , 41373737 , 41478481 , 41583756 , 41689567 , 41795918 , 41902813 , 42010256 , 42118252 , 42226804 , 42335917 , 42445596 , 42555844 , 42666667 , - 42778068 , 42890052 , 43002625 , 43115789 , 43229551 , 43343915 , 43458886 , 43574468 , 43690667 , 43807487 , 43924933 , 44043011 , 44161725 , 44281081 , 44401084 , 44521739 , - 44643052 , 44765027 , 44887671 , 45010989 , 45134986 , 45259669 , 45385042 , 45511111 , 45637883 , 45765363 , 45893557 , 46022472 , 46152113 , 46282486 , 46413598 , 46545455 , - 46678063 , 46811429 , 46945559 , 47080460 , 47216138 , 47352601 , 47489855 , 47627907 , 47766764 , 47906433 , 48046921 , 48188235 , 48330383 , 48473373 , 48617211 , 48761905 , - 48907463 , 49053892 , 49201201 , 49349398 , 49498489 , 49648485 , 49799392 , 49951220 , 50103976 , 50257669 , 50412308 , 50567901 , 50724458 , 50881988 , 51040498 , 51200000 , - 51360502 , 51522013 , 51684543 , 51848101 , 52012698 , 52178344 , 52345048 , 52512821 , 52681672 , 52851613 , 53022654 , 53194805 , 53368078 , 53542484 , 53718033 , 53894737 , - 54072607 , 54251656 , 54431894 , 54613333 , 54795987 , 54979866 , 55164983 , 55351351 , 55538983 , 55727891 , 55918089 , 56109589 , 56302405 , 56496552 , 56692042 , 56888889 , - 57087108 , 57286713 , 57487719 , 57690141 , 57893993 , 58099291 , 58306050 , 58514286 , 58724014 , 58935252 , 59148014 , 59362319 , 59578182 , 59795620 , 60014652 , 60235294 , - 60457565 , 60681481 , 60907063 , 61134328 , 61363296 , 61593985 , 61826415 , 62060606 , 62296578 , 62534351 , 62773946 , 63015385 , 63258687 , 63503876 , 63750973 , 64000000 diff --git a/src/sound/saasound/SAAFreq.h b/src/sound/saasound/SAAFreq.h deleted file mode 100755 index 478754621..000000000 --- a/src/sound/saasound/SAAFreq.h +++ /dev/null @@ -1,72 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// SAAFreq.h: interface for the CSAAFreq class. -// Note about Samplerates: 0=44100, 1=22050; 2=11025 -// -////////////////////////////////////////////////////////////////////// - -#ifndef SAAFREQ_H_INCLUDE -#define SAAFREQ_H_INCLUDE - -#include "defns.h" - -class CSAAFreq -{ -private: -#ifdef SAAFREQ_FIXED_CLOCKRATE - // 'load in' the data for the static frequency lookup table - // precomputed for a fixed clockrate - // See: tools/freqdat.py - const static unsigned long m_FreqTable[2048]; -#else - // we'll calculate the frequency lookup table at runtime. - static unsigned long m_FreqTable[2048]; - static unsigned long m_nClockRate; -#endif - - unsigned long m_nCounter; - unsigned long m_nAdd; - unsigned long m_nCounter_low; - unsigned int m_nOversample; - unsigned long m_nCounterLimit_low; - int m_nLevel; - - int m_nCurrentOffset; - int m_nCurrentOctave; - int m_nNextOffset; - int m_nNextOctave; - bool m_bIgnoreOffsetData; - bool m_bNewData; - bool m_bSync; - - unsigned long m_nSampleRate; - CSAANoise * const m_pcConnectedNoiseGenerator; - CSAAEnv * const m_pcConnectedEnvGenerator; - const int m_nConnectedMode; // 0 = nothing; 1 = envgenerator; 2 = noisegenerator - - void UpdateOctaveOffsetData(void); - void SetAdd(void); - -public: - CSAAFreq(CSAANoise * const pcNoiseGenerator, CSAAEnv * const pcEnvGenerator); - ~CSAAFreq(); - void SetFreqOffset(BYTE nOffset); - void SetFreqOctave(BYTE nOctave); - void _SetSampleRate(unsigned int nSampleRate); - void _SetOversample(unsigned int oversample); - void _SetClockRate(int nClockRate); - void Sync(bool bSync); - int Tick(void); - int Level(void) const; - -}; - -inline int CSAAFreq::Level(void) const -{ - if (m_bSync) - return 1; - - return m_nLevel; -} - -#endif // SAAFREQ_H_INCLUDE diff --git a/src/sound/saasound/SAAImpl.cpp b/src/sound/saasound/SAAImpl.cpp deleted file mode 100644 index f136eefc6..000000000 --- a/src/sound/saasound/SAAImpl.cpp +++ /dev/null @@ -1,489 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// SAAImpl.cpp: implementation of the CSAASound class. -// the bones of the 'virtual SAA-1099' emulation -// -// the actual sound generation is carried out in the other classes; -// this class provides the output stage and the external interface only -// -////////////////////////////////////////////////////////////////////// - -#include "SAASound.h" - -#include "types.h" -#include "SAAImpl.h" -#include "defns.h" - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -CSAASoundInternal::CSAASoundInternal() - : -m_chip(), -m_uParam(0), -m_uParamRate(0), -m_nClockRate(EXTERNAL_CLK_HZ), -m_nSampleRate(SAMPLE_RATE_HZ), -m_nOversample(DEFAULT_OVERSAMPLE), -#if defined(DEBUGSAA) || defined(USE_CONFIG_FILE) -m_bHighpass(false), -m_nDebugSample(0) -#else -m_bHighpass(false) -#endif -{ -#ifdef USE_CONFIG_FILE - m_Config.ReadConfig(); -#endif - -#if defined(DEBUGSAA) - m_dbgfile.open(_T(DEBUG_SAA_REGISTER_LOG), std::ios_base::out); - m_pcmfile.open(_T(DEBUG_SAA_PCM_LOG), std::ios_base::out | std::ios_base::binary); -#elif defined(USE_CONFIG_FILE) - if (m_Config.m_bGenerateRegisterLogs) - m_dbgfile.open(m_Config.m_strRegisterLogPath, std::ios_base::out); - if (m_Config.m_bGeneratePcmLogs) - m_pcmfile.open(m_Config.m_strPcmOutputPath, std::ios_base::out | std::ios_base::binary); - - if (m_Config.m_bGeneratePcmLogs && m_Config.m_bGeneratePcmSeparateChannels) - { - for (int i = 0; i < 6; i++) - { - m_channel_pcmfile[i].open(m_Config.getChannelPcmOutputPath(i), std::ios_base::out | std::ios_base::binary); - } - } - - -#endif - // set parameters - // TODO support defaults and overrides from config file - // m_chip.SetSoundParameters(SAAP_FILTER | SAAP_11025 | SAAP_8BIT | SAAP_MONO); - // reset the virtual SAA - // m_chip.Clear(); - - m_chip._SetClockRate(m_nClockRate); - m_chip._SetOversample(m_nOversample); -} - -CSAASoundInternal::~CSAASoundInternal() -{ - // -} - -////////////////////////////////////////////////////////////////////// -// CSAASound members -////////////////////////////////////////////////////////////////////// - -void CSAASoundInternal::SetClockRate(unsigned int nClockRate) -{ - m_nClockRate = nClockRate; - m_chip._SetClockRate(m_nClockRate); -} - -void CSAASoundInternal::Clear(void) -{ - // reinitialises virtual SAA: - // sets reg 28 to 0x02; - sync and disabled - // sets regs 00-31 (except 28) to 0x00; - // sets reg 28 to 0x00; - // sets current reg to 0 - WriteAddressData(28,2); - for (int i=31; i>=0; i--) - { - if (i!=28) WriteAddressData(i,0); - } - WriteAddressData(28,0); - WriteAddress(0); -} - -void CSAASoundInternal::WriteData(BYTE nData) -{ - // originated from an OUT 255,d call - m_chip._WriteData(nData); -#if defined(DEBUGSAA) || defined(USE_CONFIG_FILE) -#ifdef USE_CONFIG_FILE - if (m_Config.m_bGenerateRegisterLogs) - { -#endif - m_dbgfile << m_nDebugSample << " " << (int)m_chip._ReadAddress() << ":" << (int)nData << std::endl; -#ifdef USE_CONFIG_FILE - } -#endif -#endif -} - -void CSAASoundInternal::WriteAddress(BYTE nReg) -{ - // originated from an OUT 511,r call - m_chip._WriteAddress(nReg); -#if defined(DEBUGSAA) || defined(USE_CONFIG_FILE) -#ifdef USE_CONFIG_FILE - if (m_Config.m_bGenerateRegisterLogs) - { -#endif - m_dbgfile << m_nDebugSample << " " << (int)nReg << ":"; - if (nReg==24) - { - m_dbgfile << ""; - } - else if (nReg==25) - { - m_dbgfile << ""; - } - m_dbgfile << std::endl; -#ifdef USE_CONFIG_FILE - } -#endif -#endif -} - -void CSAASoundInternal::WriteAddressData(BYTE nReg, BYTE nData) -{ - // performs WriteAddress(nReg) followed by WriteData(nData) - m_chip._WriteAddress(nReg); - m_chip._WriteData(nData); -} - -#if 1 -BYTE CSAASoundInternal::ReadAddress(void) -{ - // Not a real hardware function of the SAA-1099, which is write-only - return(m_chip._ReadAddress()); -} -#else -BYTE CSAASoundInternal::ReadAddress(void) -{ - // Not a real hardware function of the SAA-1099, which is write-only - return(0); -} -#endif - -void CSAASoundInternal::SetSoundParameters(SAAPARAM uParam) -{ - // set samplerate properties from uParam (deprecated but still supported) - unsigned int nSampleRate = m_nSampleRate; - switch (uParam & SAAP_MASK_SAMPLERATE) - { - case SAAP_44100: - nSampleRate = 44100; - m_uParamRate = (m_uParamRate & ~SAAP_MASK_SAMPLERATE) | SAAP_44100; - break; - case SAAP_22050: - nSampleRate = 22050; - m_uParamRate = (m_uParamRate & ~SAAP_MASK_SAMPLERATE) | SAAP_22050; - break; - case SAAP_11025: - nSampleRate = 11025; - m_uParamRate = (m_uParamRate & ~SAAP_MASK_SAMPLERATE) | SAAP_11025; - break; - case 0:// change nothing! - default: - break; - } - - if (nSampleRate != m_nSampleRate) - { - m_nSampleRate = nSampleRate; - m_chip._SetSampleRate(m_nSampleRate); - } - - // set filter properties from uParam - m_uParam = (m_uParam & ~SAAP_MASK_FILTER) | (uParam & SAAP_MASK_FILTER); - - m_bHighpass=true; -} - -void CSAASoundInternal::SetSampleRate(unsigned int nSampleRate) -{ - if (nSampleRate != m_nSampleRate) - { - m_nSampleRate = nSampleRate; - m_chip._SetSampleRate(m_nSampleRate); - } -} - -void CSAASoundInternal::SetOversample(unsigned int nOversample) -{ - if (nOversample != m_nOversample) - { - m_nOversample = nOversample; - m_chip._SetOversample(m_nOversample); - } -} - -SAAPARAM CSAASoundInternal::GetCurrentSoundParameters(void) -{ - return m_uParam | m_uParamRate; -} - -unsigned short CSAASoundInternal::GetCurrentBytesPerSample(void) -{ - // 16 bit stereo => 4 bytes per sample - return 4; -} - -/*static*/ unsigned short CSAASound::GetBytesPerSample(SAAPARAM uParam) -{ - // 16 bit stereo => 4 bytes per sample - switch (uParam & (SAAP_MASK_CHANNELS | SAAP_MASK_BITDEPTH)) - { - case SAAP_STEREO | SAAP_16BIT: - return 4; - default: - return 0; - } -} - -unsigned long CSAASoundInternal::GetCurrentSampleRate(void) -{ - return CSAASound::GetSampleRate(m_uParamRate); -} - -/*static*/ unsigned long CSAASound::GetSampleRate(SAAPARAM uParam) // static member function -{ - switch (uParam & SAAP_MASK_SAMPLERATE) - { - case SAAP_11025: - return 11025; - case SAAP_22050: - return 22050; - case SAAP_44100: - return 44100; - default: - return 0; - } -} - -#if defined(USE_CONFIG_FILE) || (defined(DEFAULT_BOOST) && DEFAULT_BOOST>1) -#define DO_BOOST -#endif - -void scale_for_output(unsigned int left_input, unsigned int right_input, - double oversample_scalar, bool highpass, double boost, - double& filterout_z1_left, double& filterout_z1_right, - BYTE* &pBuffer) -{ - double float_left = (double)left_input; - double float_right = (double)right_input; - float_left /= oversample_scalar; - float_right /= oversample_scalar; - - // scale output into good range - float_left *= DEFAULT_UNBOOSTED_MULTIPLIER; - float_right *= DEFAULT_UNBOOSTED_MULTIPLIER; - - if (highpass) - { - /* cutoff = 5 Hz (say) - const double b1 = exp(-2.0 * M_PI * (Fc/Fs)) - const double a0 = 1.0 - b1; - */ - const double b1 = 0.99928787; - const double a0 = 1.0 - b1; - - filterout_z1_left = float_left * a0 + filterout_z1_left * b1; - filterout_z1_right = float_right * a0 + filterout_z1_right * b1; - float_left -= filterout_z1_left; - float_right -= filterout_z1_right; - } - - // multiply by boost, if defined -#if defined(DO_BOOST) - float_left *= boost; - float_right *= boost; -#endif - // convert to 16-bit signed range with hard clipping - signed short left_output = (signed short)(float_left > 32767 ? 32767 : float_left < -32768 ? -32768 : float_left); - signed short right_output = (signed short)(float_right > 32767 ? 32767 : float_right < -32768 ? -32768 : float_right); - - *pBuffer++ = left_output & 0x00ff; - *pBuffer++ = (left_output >> 8) & 0x00ff; - *pBuffer++ = right_output & 0x00ff; - *pBuffer++ = (right_output >> 8) & 0x00ff; -} - -void CSAASoundInternal::GenerateMany(BYTE* pBuffer, unsigned long nSamples) -{ - unsigned int left_mixed, right_mixed; - static double filterout_z1_left_mixed = 0, filterout_z1_right_mixed = 0; - -#if defined(DEBUGSAA) || defined(USE_CONFIG_FILE) - BYTE* pBufferStart = pBuffer; - unsigned long nTotalSamples = nSamples; -#endif - -#if defined(DO_BOOST) -#if defined(USE_CONFIG_FILE) - double nBoost = m_Config.m_nBoost; -#else - double nBoost = DEFAULT_BOOST; -#endif -#else - double nBoost = 1.0; -#endif - - double oversample = double(1 << m_nOversample); - -#if defined(USE_CONFIG_FILE) - static double filterout_z1_left_0 = 0, filterout_z1_right_0 = 0; - static double filterout_z1_left_1 = 0, filterout_z1_right_1 = 0; - static double filterout_z1_left_2 = 0, filterout_z1_right_2 = 0; - static double filterout_z1_left_3 = 0, filterout_z1_right_3 = 0; - static double filterout_z1_left_4 = 0, filterout_z1_right_4 = 0; - static double filterout_z1_left_5 = 0, filterout_z1_right_5 = 0; - - if (m_Config.m_bGeneratePcmLogs && m_Config.m_bGeneratePcmSeparateChannels) - { - unsigned int left0, right0, left1, right1, left2, right2, left3, right3, left4, right4, left5, right5; - BYTE* pChannelBufferPtr[6] = { m_pChannelBuffer[0], m_pChannelBuffer[1], m_pChannelBuffer[2], m_pChannelBuffer[3], m_pChannelBuffer[4], m_pChannelBuffer[5] }; - - while (nSamples--) - { - m_chip._TickAndOutputSeparate(left_mixed, right_mixed, - left0, right0, - left1, right1, - left2, right2, - left3, right3, - left4, right4, - left5, right5); - scale_for_output(left_mixed, right_mixed, oversample, m_bHighpass, nBoost, filterout_z1_left_mixed, filterout_z1_right_mixed, pBuffer); - - // and the separate channels - scale_for_output(left0, right0, oversample, m_bHighpass, nBoost, filterout_z1_left_0, filterout_z1_right_0, pChannelBufferPtr[0]); - scale_for_output(left1, right1, oversample, m_bHighpass, nBoost, filterout_z1_left_1, filterout_z1_right_1, pChannelBufferPtr[1]); - scale_for_output(left2, right2, oversample, m_bHighpass, nBoost, filterout_z1_left_2, filterout_z1_right_2, pChannelBufferPtr[2]); - scale_for_output(left3, right3, oversample, m_bHighpass, nBoost, filterout_z1_left_3, filterout_z1_right_3, pChannelBufferPtr[3]); - scale_for_output(left4, right4, oversample, m_bHighpass, nBoost, filterout_z1_left_4, filterout_z1_right_4, pChannelBufferPtr[4]); - scale_for_output(left5, right5, oversample, m_bHighpass, nBoost, filterout_z1_left_5, filterout_z1_right_5, pChannelBufferPtr[5]); - - // flush channel output PCM buffers when full - if (pChannelBufferPtr[0] >= m_pChannelBuffer[0] + CHANNEL_BUFFER_SIZE) - { - for (int i = 0; i < 6; i++) - { - m_channel_pcmfile[i].write((const char*)m_pChannelBuffer[i], CHANNEL_BUFFER_SIZE); - pChannelBufferPtr[i] = m_pChannelBuffer[i]; - } - } - } - // flush remaining channel PCM output data - if (pChannelBufferPtr[0] >= m_pChannelBuffer[0]) - { - for (int i = 0; i < 6; i++) - { - m_channel_pcmfile[i].write((const char*)m_pChannelBuffer[i], pChannelBufferPtr[i]-m_pChannelBuffer[i]); - } - } - } - else - { -#endif - while (nSamples--) - { - m_chip._TickAndOutputStereo(left_mixed, right_mixed); - scale_for_output(left_mixed, right_mixed, oversample, m_bHighpass, nBoost, filterout_z1_left_mixed, filterout_z1_right_mixed, pBuffer); - } - -#if defined(USE_CONFIG_FILE) - } -#endif - -#if defined(DEBUGSAA) || defined(USE_CONFIG_FILE) -#ifdef USE_CONFIG_FILE - if (m_Config.m_bGeneratePcmLogs) - { -#endif - m_pcmfile.write((const char *)pBufferStart, nTotalSamples * (unsigned long)GetCurrentBytesPerSample()); - m_nDebugSample += nTotalSamples; -#ifdef USE_CONFIG_FILE - } -#endif - -#endif -} - -/////////////////////////////////////////////////////// - -LPCSAASOUND SAAAPI CreateCSAASound(void) -{ - return (new CSAASoundInternal); -} - -void SAAAPI DestroyCSAASound(LPCSAASOUND object) -{ - delete (object); -} - - -/* thoughts on lowpass filtering as part of oversampling. -I tried this and really it didn't seem to make a lot of (audible) difference. - -// lowpass oversample filter adds complexity and not particularly audibly better than simple averaging. -// use_lowpass_oversample_filter_average_output adds an additional averaging step to the output of the oversample -// filter. this seems critical, because without this, the raw output of the lowpass filter is full of aliases -// If use_lowpass_oversample_filter is False, then the _average_output flag is ignored. -// Default, use_lowpass_oversample_filter is False, it sounds just fine really. - -//#define USE_LOWPASS_OVERSAMPLE_FILTER -#undef USE_LOWPASS_OVERSAMPLE_FILTER -//#define USE_LOWPASS_OVERSAMPLE_FILTER_AVERAGE_OUTPUT -#undef USE_LOWPASS_OVERSAMPLE_FILTER_AVERAGE_OUTPUT - -#ifdef USE_LOWPASS_OVERSAMPLE_FILTER -static double oversample_lp_filterout_z1_left_stages[10] = { 0,0,0,0,0,0,0,0,0,0 }; -static double oversample_lp_filterout_z1_right_stages[10] = { 0,0,0,0,0,0,0,0,0,0 }; -double averaged_filterout_left = 0.0, averaged_filterout_right = 0.0; -const int nStages = 10; -for (int i = 0; i < 1 << m_nOversample; i++) -{ - Noise[0]->Tick(); - Noise[1]->Tick(); - f_left = f_right = 0; - for (int c = 0; c < 6; c++) - { - Amp[c]->TickAndOutputStereo(temp_left, temp_right); - f_left += (double)temp_left; - f_right += (double)temp_right; - } - // apply lowpass here. - // HACK: ASSUME m_nOversample is 64 (I was experimenting only using the 64x oversample anyway) - // therefore Fs = 44100*64 - // let's set Fc = 10kHz - // so Fc/Fs = 0.00354308390022675736961451247166 - // const double b1 = exp(-2.0 * M_PI * (Fc/Fs)) - // const double a0 = 1.0 - b1; - // const double b1 = 0.9779841137335348363722276130195; - const double b1 = 0.977; - const double a0 = 1.0 - b1; - - oversample_lp_filterout_z1_left_stages[0] = f_left * a0 + oversample_lp_filterout_z1_left_stages[0] * b1; - for (int stage = 1; stage < nStages; stage++) - oversample_lp_filterout_z1_left_stages[stage] = oversample_lp_filterout_z1_left_stages[stage - 1] * a0 + oversample_lp_filterout_z1_left_stages[stage] * b1; - oversample_lp_filterout_z1_right_stages[0] = f_right * a0 + oversample_lp_filterout_z1_right_stages[0] * b1; - for (int stage = 1; stage < nStages; stage++) - oversample_lp_filterout_z1_right_stages[stage] = oversample_lp_filterout_z1_right_stages[stage - 1] * a0 + oversample_lp_filterout_z1_right_stages[stage] * b1; - -#ifdef USE_LOWPASS_OVERSAMPLE_FILTER_AVERAGE_OUTPUT - averaged_filterout_left += oversample_lp_filterout_4z1_left; - averaged_filterout_right += oversample_lp_filterout_4z1_right; -#endif -} - -// by the end of this loop we will have computed the oversample lowpass filter m_nOversample times -// and yielded exactly ONE sample output. -#ifdef USE_LOWPASS_OVERSAMPLE_FILTER_AVERAGE_OUTPUT -f_left = averaged_filterout_left / (1 << m_nOversample); -f_right = averaged_filterout_right / (1 << m_nOversample); -#else -f_left = oversample_lp_filterout_z1_left_stages[nStages - 1]; -f_right = oversample_lp_filterout_z1_right_stages[nStages - 1]; -#endif - -#else - // do the simple 1/N averaging which is easier and sounds good enough - -#endif - -*/ - diff --git a/src/sound/saasound/SAAImpl.h b/src/sound/saasound/SAAImpl.h deleted file mode 100755 index 61fa79c58..000000000 --- a/src/sound/saasound/SAAImpl.h +++ /dev/null @@ -1,75 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// This is the internal implementation (header file) of the SAASound object. -// This is done so that the external interface to the object always stays the same -// (SAASound.h) even though the internal object can change -// .. Meaning future releases don't require relinking everyone elses code against -// the updated saasound stuff -// -////////////////////////////////////////////////////////////////////// - -#ifndef SAAIMPL_H_INCLUDED -#define SAAIMPL_H_INCLUDED - -#include "SAASound.h" -#include "SAADevice.h" -#ifdef USE_CONFIG_FILE -#include "SAAConfig.h" -#endif - -#if defined(DEBUGSAA) || defined(USE_CONFIG_FILE) -#include -#include -#include - -#if defined(USE_CONFIG_FILE) -const int CHANNEL_BUFFER_SIZE=1024; -#endif -#endif - -class CSAASoundInternal : public CSAASound -{ -private: - CSAADevice m_chip; - int m_uParam, m_uParamRate; - unsigned int m_nClockRate; - unsigned int m_nSampleRate; - unsigned int m_nOversample; - bool m_bHighpass; -#ifdef USE_CONFIG_FILE - SAAConfig m_Config; -#endif -#if defined(DEBUGSAA) || defined(USE_CONFIG_FILE) - unsigned long m_nDebugSample; - std::ofstream m_dbgfile, m_pcmfile; -#if defined(USE_CONFIG_FILE) - std::ofstream m_channel_pcmfile[6]; - BYTE m_pChannelBuffer[6][CHANNEL_BUFFER_SIZE]; -#endif -#endif - -public: - CSAASoundInternal(); - ~CSAASoundInternal(); - - void SetClockRate(unsigned int nClockRate); - void SetSampleRate(unsigned int nClockRate); - void SetOversample(unsigned int nOversample); - void SetSoundParameters(SAAPARAM uParam); - void WriteAddress(BYTE nReg); - void WriteData(BYTE nData); - void WriteAddressData(BYTE nReg, BYTE nData); - BYTE ReadAddress(void); - void Clear(void); - - SAAPARAM GetCurrentSoundParameters(void); - unsigned long GetCurrentSampleRate(void); - static unsigned long GetSampleRate(SAAPARAM uParam); - unsigned short GetCurrentBytesPerSample(void); - static unsigned short GetBytesPerSample(SAAPARAM uParam); - - void GenerateMany(BYTE * pBuffer, unsigned long nSamples); - -}; - -#endif // SAAIMPL_H_INCLUDED diff --git a/src/sound/saasound/SAANoise.cpp b/src/sound/saasound/SAANoise.cpp deleted file mode 100755 index 1cf3458dd..000000000 --- a/src/sound/saasound/SAANoise.cpp +++ /dev/null @@ -1,180 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// SAANoise.cpp: implementation of the CSAANoise class. -// One noise generator -// -// After construction, it's important to SetSampleRate before -// trying to use the generator. -// (Just because the CSAANoise object has a default samplerate -// doesn't mean you should rely on it) -// -////////////////////////////////////////////////////////////////////// - -#include "SAASound.h" - -#include "types.h" -#include "SAANoise.h" -#include "defns.h" - - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -CSAANoise::CSAANoise() -: -m_nCounter(0), -m_nCounter_low(0), -m_nOversample(0), -m_nCounterLimit_low(1), -m_bSync(false), -m_nSampleRate(SAMPLE_RATE_HZ), -m_nSourceMode(0), -m_nRand(1) -{ - _SetClockRate(EXTERNAL_CLK_HZ); - m_nAdd = m_nAddBase; -} - -CSAANoise::CSAANoise(unsigned long seed) -: -m_nCounter(0), -m_nCounter_low(0), -m_nOversample(0), -m_nCounterLimit_low(1), -m_bSync(false), -m_nSampleRate(SAMPLE_RATE_HZ), -m_nSourceMode(0), -m_nRand(seed) -{ - _SetClockRate(EXTERNAL_CLK_HZ); - m_nAdd = m_nAddBase; -} - -CSAANoise::~CSAANoise() -{ - // Nothing to do -} - -void CSAANoise::_SetClockRate(int nClockRate) -{ - // at 8MHz the clock rate is 31.250kHZ - // This is simply the clock rate divided by 256 i.e. 2^8 - // We then shift this by 2^12 (like the Freq) for better - // period accuracy. So that's the same as shifting by (12-8) - m_nAddBase = nClockRate << (12 - 8); -} - -void CSAANoise::Seed(unsigned long seed) -{ - m_nRand = seed; -} - -void CSAANoise::SetSource(int nSource) -{ - m_nSourceMode = nSource; - m_nAdd = m_nAddBase >> m_nSourceMode; -} - -void CSAANoise::Trigger(void) -{ - // Trigger only does anything useful when we're - // clocking from the frequency generator - i.e - // if bUseFreqGen = true (i.e. SourceMode = 3) - - // So if we're clocking from the noise generator - // clock (ie, SourceMode = 0, 1 or 2) then do nothing - -// No point actually checking m_bSync here ... because if sync is true, -// then frequency generators won't actually be generating Trigger pulses -// so we wouldn't even get here! - // EXCEPT - cool edge case: if sync is set, then actually the Noise Generator - // is triggered on EVERY CLOCK PULSE (i.e. 8MHz noise). So indeed it is correct - // to not check for sync here. NEEDS TEST CASE. - - if (m_nSourceMode == 3) - { - ChangeLevel(); - } -} - -void CSAANoise::Tick(void) -{ - // Tick only does anything useful when we're - // clocking from the noise generator clock - // (ie, SourceMode = 0, 1 or 2) - - // So, if SourceMode = 3 (ie, we're clocking from a - // frequency generator ==> bUseFreqGen = true) - // then do nothing - if ( (!m_bSync) && (m_nSourceMode!=3) ) - { - m_nCounter += m_nAdd; - while (m_nCounter >= (m_nSampleRate<<12)) - { - m_nCounter -= (m_nSampleRate<<12); - m_nCounter_low++; - if (m_nCounter_low >= m_nCounterLimit_low) - { - m_nCounter_low = 0; - ChangeLevel(); - } - } - } -} - -void CSAANoise::Sync(bool bSync) -{ - if (bSync) - { - m_nCounter = 0; - m_nCounter_low = 0; - } - m_bSync = bSync; -} - - -void CSAANoise::_SetSampleRate(int nSampleRate) -{ - m_nSampleRate = nSampleRate; -} - - -void CSAANoise::_SetOversample(unsigned int oversample) -{ - // oversample is a power of 2 i.e. - // if oversample == 2 then 4x oversample - // if oversample == 6 then 64x oversample - if (oversample < m_nOversample) - { - m_nCounter_low <<= (m_nOversample - oversample); - } - else - { - m_nCounter_low >>= (oversample - m_nOversample); - } - - m_nCounterLimit_low = 1<> 1) ^ 0x20400; - } - else - { - m_nRand >>= 1; - } -} diff --git a/src/sound/saasound/SAANoise.h b/src/sound/saasound/SAANoise.h deleted file mode 100755 index 61a65dee8..000000000 --- a/src/sound/saasound/SAANoise.h +++ /dev/null @@ -1,54 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// SAANoise.h: interface for the CSAANoise class. -// -////////////////////////////////////////////////////////////////////// - -#ifndef SAANOISE_H_INCLUDED -#define SAANOISE_H_INCLUDED - -class CSAANoise -{ -private: - unsigned long m_nCounter; - unsigned long m_nAdd; - unsigned long m_nCounter_low; - unsigned int m_nOversample; - unsigned long m_nCounterLimit_low; - bool m_bSync; // see description of "SYNC" bit of register 28 - unsigned long m_nSampleRate; // = 44100 when RateMode=0, for example - int m_nSourceMode; - unsigned long m_nAddBase; // nAdd for 31.25 kHz noise at 44.1 kHz samplerate - - // pseudo-random number generator - unsigned long m_nRand; - - void ChangeLevel(void); - - -public: - CSAANoise(); - CSAANoise(unsigned long seed); - ~CSAANoise(); - - void SetSource(int nSource); - void Trigger(void); - void _SetSampleRate(int nSampleRate); - void _SetOversample(unsigned int oversample); - void _SetClockRate(int nClockRate); - void Seed(unsigned long seed); - - void Tick(void); - int Level(void) const; - void Sync(bool bSync); - -}; - -inline int CSAANoise::Level(void) const -{ - // returns 0 or 1 - return (m_nRand & 0x00000001); -} - - -#endif // SAANOISE_H_INCLUDED diff --git a/src/sound/saasound/SAASndC.cpp b/src/sound/saasound/SAASndC.cpp deleted file mode 100755 index 9af0d76e7..000000000 --- a/src/sound/saasound/SAASndC.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// Thanks to this file (and associated header file) you can now -// use CSAASound from within a standard 'C' program -// -////////////////////////////////////////////////////////////////////// - -#include "SAASound.h" -#include "types.h" -#include "SAAEnv.h" -#include "SAANoise.h" -#include "SAAFreq.h" -#include "SAAAmp.h" -#include "SAASound.h" -#include "SAAImpl.h" - -SAASND SAAAPI newSAASND(void) -{ - return (SAASND)(new CSAASoundInternal()); -} - -void SAAAPI deleteSAASND(SAASND object) -{ - delete (LPCSAASOUND)(object); -} - -void SAAAPI SAASNDSetClockRate(SAASND object, unsigned int nClockRate) -{ - ((LPCSAASOUND)(object))->SetClockRate(nClockRate); -} - -void SAAAPI SAASNDSetSoundParameters(SAASND object, SAAPARAM uParam) -{ - ((LPCSAASOUND)(object))->SetSoundParameters(uParam); -} - -void SAAAPI SAASNDWriteAddress(SAASND object, BYTE nReg) -{ - ((LPCSAASOUND)(object))->WriteAddress(nReg); -} - -void SAAAPI SAASNDWriteData(SAASND object, BYTE nData) -{ - ((LPCSAASOUND)(object))->WriteData(nData); -} - -void SAAAPI SAASNDWriteAddressData(SAASND object, BYTE nReg, BYTE nData) -{ - ((LPCSAASOUND)(object))->WriteAddressData(nReg, nData); -} - -void SAAAPI SAASNDClear(SAASND object) -{ - ((LPCSAASOUND)(object))->Clear(); -} - -SAAPARAM SAAAPI SAASNDGetCurrentSoundParameters(SAASND object) -{ - return ((LPCSAASOUND)(object))->GetCurrentSoundParameters(); -} - -unsigned short SAAAPI SAASNDGetCurrentBytesPerSample(SAASND object) -{ - return ((LPCSAASOUND)(object))->GetCurrentBytesPerSample(); -} - -unsigned short SAAAPI SAASNDGetBytesPerSample(SAAPARAM uParam) -{ - return CSAASound::GetBytesPerSample(uParam); -} - -unsigned long SAAAPI SAASNDGetCurrentSampleRate(SAASND object) -{ - return ((LPCSAASOUND)(object))->GetCurrentSampleRate(); -} - -unsigned long SAAAPI SAASNDGetSampleRate(SAAPARAM uParam) -{ - return CSAASound::GetSampleRate(uParam); -} - -void SAAAPI SAASNDGenerateMany(SAASND object, BYTE * pBuffer, unsigned long nSamples) -{ - ((LPCSAASOUND)(object))->GenerateMany(pBuffer, nSamples); -} - -void SAAAPI SAASNDSetSampleRate(SAASND object, unsigned int nSampleRate) -{ - return ((LPCSAASOUND)(object))->SetSampleRate(nSampleRate); -} - -void SAAAPI SAASNDSetOversample(SAASND object, unsigned int nOversample) -{ - return ((LPCSAASOUND)(object))->SetOversample(nOversample); -} - -BYTE SAAAPI SAASNDReadAddress(SAASND object) -{ - return ((LPCSAASOUND)(object))->ReadAddress(); -} diff --git a/src/sound/saasound/SAASndC.h b/src/sound/saasound/SAASndC.h deleted file mode 100644 index c6fd65765..000000000 --- a/src/sound/saasound/SAASndC.h +++ /dev/null @@ -1,102 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// ********** -// * PUBLIC * -// ********** -// -// SAASndC.h: "C-style" interface for the CSAASound class. -// -////////////////////////////////////////////////////////////////////// - -#ifndef SAASNDC_H_INCLUDED -#define SAASNDC_H_INCLUDED - -#ifdef _MSC_VER -#if _MSC_VER >= 1000 -#pragma once -#endif // _MSC_VER >= 1000 -#endif - -#ifndef SAASOUND_H_INCLUDED - -// Parameters for use with SetSoundParameters, for example, -// SetSoundParameters(SAAP_NOFILTER | SAAP_44100 | SAAP_16BIT | SAAP_STEREO); -#define SAAP_FILTER_HIGHPASS_SIMPLE 0x00000400 -#define SAAP_FILTER_OVERSAMPLE64x 0x00000300 -#define SAAP_FILTER_OVERSAMPLE2x 0x00000200 -#define SAAP_FILTER SAAP_FILTER_OVERSAMPLE2x -#define SAAP_NOFILTER 0x00000100 -#define SAAP_44100 0x00000030 -#define SAAP_22050 0x00000020 -#define SAAP_11025 0x00000010 -#define SAAP_16BIT 0x0000000c -#define SAAP_8BIT 0x00000004 -#define SAAP_STEREO 0x00000003 -#define SAAP_MONO 0x00000001 - -// Bitmasks for use with GetCurrentSoundParameters, for example, -// unsigned long CurrentSampleRateParameter = GetCurrentSoundParameters() -#define SAAP_MASK_FILTER 0x00000f00 -#define SAAP_MASK_FILTER_HIGHPASS 0x00000c00 -#define SAAP_MASK_FILTER_OVERSAMPLE 0x00000300 -#define SAAP_MASK_SAMPLERATE 0x000000030 -#define SAAP_MASK_BITDEPTH 0x0000000c -#define SAAP_MASK_CHANNELS 0x00000003 - -typedef unsigned long SAAPARAM; - - -#ifndef BYTE -#define BYTE unsigned char -#endif - -#ifdef WIN32 -#ifndef WINAPI -#define WINAPI __stdcall -#endif -#define EXTAPI __declspec(dllexport) WINAPI -#else // Win32 -#ifndef WINAPI -#define WINAPI /**/ -#endif -#define EXTAPI /**/ -#endif // Win32 - -#endif // SAASOUND_H_INCLUDED - -typedef void * SAASND; - -// the following are implemented as calls, etc, to a class. - -#ifdef __cplusplus -extern "C" { -#endif - -SAASND EXTAPI newSAASND(void); -void EXTAPI deleteSAASND(SAASND object); - -void EXTAPI SAASNDSetSoundParameters(SAASND object, SAAPARAM uParam); -void EXTAPI SAASNDWriteAddress(SAASND object, BYTE nReg); -void EXTAPI SAASNDWriteData(SAASND object, BYTE nData); -void EXTAPI SAASNDWriteAddressData(SAASND object, BYTE nReg, BYTE nData); -void EXTAPI SAASNDClear(SAASND object); -BYTE EXTAPI SAASNDReadAddress(SAASND object); - -SAAPARAM EXTAPI SAASNDGetCurrentSoundParameters(SAASND object); -unsigned short EXTAPI SAASNDGetCurrentBytesPerSample(SAASND object); -unsigned short EXTAPI SAASNDGetBytesPerSample(SAAPARAM uParam); -unsigned long EXTAPI SAASNDGetCurrentSampleRate(SAASND object); -unsigned long EXTAPI SAASNDGetSampleRate(SAAPARAM uParam); - -void EXTAPI SAASNDGenerateMany(SAASND object, BYTE * pBuffer, unsigned long nSamples); - -void EXTAPI SAASNDSetClockRate(SAASND object, unsigned int nClockRate); -void EXTAPI SAASNDSetSampleRate(SAASND object, unsigned int nSampleRate); -void EXTAPI SAASNDSetOversample(SAASND object, unsigned int nOversample); - - -#ifdef __cplusplus -}; // extern "C" -#endif - -#endif // SAASNDC_H_INCLUDED diff --git a/src/sound/saasound/SAASound.cpp b/src/sound/saasound/SAASound.cpp deleted file mode 100755 index c5e33d862..000000000 --- a/src/sound/saasound/SAASound.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// SAASound.cpp - dummy function -// -////////////////////////////////////////////////////////////////////// - -#include - -// Provide something so the compiler doesn't optimise us out of existance -int SomeFunction () -{ - return 42; -} diff --git a/src/sound/saasound/SAASound.h b/src/sound/saasound/SAASound.h deleted file mode 100644 index a5e9265ac..000000000 --- a/src/sound/saasound/SAASound.h +++ /dev/null @@ -1,130 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// SAASound.h: interface for the CSAASound class. -// -// This corresponds to the public (exported) DLL interface, so all -// APIs and client factory methods belong here. -// -// Compatibility notes : the intention is for this to be fully backwards -// compatible across minor and patch versions. Any backwards breaking changes -// should be reflected as a major version increment. New functionality can be added -// in minor versions so long as backwards compatiblity is maintained -// -// Version 3.3.0 (4th Dec 2018) -// -////////////////////////////////////////////////////////////////////// - -#ifndef SAASOUND_H_INCLUDED -#define SAASOUND_H_INCLUDED - -// define this if you want to output diagnostic text and PCM files -//#define DEBUGSAA - -// Parameters for use with SetSoundParameters, for example, -// SetSoundParameters(SAAP_NOFILTER | SAAP_44100 | SAA_16BIT | SAA_STEREO); -// SAAP_FILTER_HIGHPASS_SIMPLE can be ORd with SAAP_FILTER_OVERSAMPLE64x/2x -#define SAAP_FILTER_HIGHPASS_SIMPLE 0x00000400 -#define SAAP_FILTER_OVERSAMPLE64x 0x00000300 -#define SAAP_FILTER_OVERSAMPLE2x 0x00000200 -#define SAAP_FILTER SAAP_FILTER_OVERSAMPLE2x -#define SAAP_NOFILTER 0x00000100 -#define SAAP_44100 0x00000030 -#define SAAP_22050 0x00000020 -#define SAAP_11025 0x00000010 -#define SAAP_16BIT 0x0000000c -#define SAAP_8BIT 0x00000004 -#define SAAP_STEREO 0x00000003 -#define SAAP_MONO 0x00000001 - -// Bitmasks for use with GetCurrentSoundParameters, for example, -// unsigned long CurrentSampleRateParameter = GetCurrentSoundParameters() -#define SAAP_MASK_FILTER 0x00000f00 -#define SAAP_MASK_FILTER_HIGHPASS 0x00000c00 -#define SAAP_MASK_FILTER_OVERSAMPLE 0x00000300 -#define SAAP_MASK_SAMPLERATE 0x000000030 -#define SAAP_MASK_BITDEPTH 0x0000000c -#define SAAP_MASK_CHANNELS 0x00000003 - -typedef unsigned long SAAPARAM; - - -#ifndef BYTE -#define BYTE unsigned char -#endif - -#ifdef _WIN32 -#define SAAAPI _stdcall -#else -#define SAAAPI -#endif - - -#ifdef __cplusplus - -class CSAASound -{ -public: - virtual ~CSAASound() { } - - virtual void SetSoundParameters (SAAPARAM uParam) = 0; - virtual void WriteAddress (BYTE nReg) = 0; - virtual void WriteData (BYTE nData) = 0; - virtual void WriteAddressData (BYTE nReg, BYTE nData) = 0; - virtual void Clear () = 0; - virtual BYTE ReadAddress () = 0; - - virtual SAAPARAM GetCurrentSoundParameters () = 0; - virtual unsigned long GetCurrentSampleRate () = 0; - static unsigned long GetSampleRate (SAAPARAM uParam); - virtual unsigned short GetCurrentBytesPerSample () = 0; - static unsigned short GetBytesPerSample (SAAPARAM uParam); - - virtual void GenerateMany (BYTE * pBuffer, unsigned long nSamples) = 0; - - virtual void SetClockRate(unsigned int nClockRate) = 0; - virtual void SetSampleRate(unsigned int nSampleRate) = 0; - virtual void SetOversample(unsigned int nOversample) = 0; -}; - -typedef class CSAASound * LPCSAASOUND; - -LPCSAASOUND SAAAPI CreateCSAASound(void); -void SAAAPI DestroyCSAASound(LPCSAASOUND object); - -#endif // __cplusplus - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void * SAASND; - -// "C-style" interface for the CSAASound class -SAASND SAAAPI newSAASND(void); -void SAAAPI deleteSAASND(SAASND object); - -void SAAAPI SAASNDSetSoundParameters(SAASND object, SAAPARAM uParam); -void SAAAPI SAASNDWriteAddress(SAASND object, BYTE nReg); -void SAAAPI SAASNDWriteData(SAASND object, BYTE nData); -void SAAAPI SAASNDWriteAddressData(SAASND object, BYTE nReg, BYTE nData); -void SAAAPI SAASNDClear(SAASND object); - -SAAPARAM SAAAPI SAASNDGetCurrentSoundParameters(SAASND object); -unsigned short SAAAPI SAASNDGetCurrentBytesPerSample(SAASND object); -unsigned short SAAAPI SAASNDGetBytesPerSample(SAAPARAM uParam); -unsigned long SAAAPI SAASNDGetCurrentSampleRate(SAASND object); -unsigned long SAAAPI SAASNDGetSampleRate(SAAPARAM uParam); - -void SAAAPI SAASNDGenerateMany(SAASND object, BYTE * pBuffer, unsigned long nSamples); -void SAAAPI SAASNDSetClockRate(SAASND object, unsigned int nClockRate); -void SAAAPI SAASNDSetSampleRate(SAASND object, unsigned int nSampleRate); -void SAAAPI SAASNDSetOversample(SAASND object, unsigned int nOversample); - -BYTE SAAAPI SAASNDReadAddress(SAASND object); - -#ifdef __cplusplus -}; // extern "C" -#endif - -#endif // SAASOUND_H_INCLUDED diff --git a/src/sound/saasound/defns.h b/src/sound/saasound/defns.h deleted file mode 100644 index e81d1c819..000000000 --- a/src/sound/saasound/defns.h +++ /dev/null @@ -1,59 +0,0 @@ -// Part of SAASound copyright 2020 Dave Hooper -// -// defns.h: compile-time configuration parameters -// -////////////////////////////////////////////////////////////////////// - -#ifndef DEFNS_H_INCLUDED -#define DEFNS_H_INCLUDED - -#define HAVE_CONFIG_H -#ifdef HAVE_CONFIG_H -// using CMAKE -#include "saasound_cmake_config.h" -#else - -// initial default SAA1099 crystal clock rate in HZ (can be changed subsequently by calling SetClockRate) -#define EXTERNAL_CLK_HZ 8000000 - -// define SAAFREQ_FIXED_CLOCKRATE if the above external clock rate is the only supported clock rate -// i.e. only support a single compile-time clock rate (=> this also prevents using the SetClockRate method) -#undef SAAFREQ_FIXED_CLOCKRATE -// #define SAAFREQ_FIXED_CLOCKRATE - -// initial default sample rate (audio samplerate) -#define SAMPLE_RATE_HZ 44100 - -// initial default oversample (audio quality) recommend 0<=oversample<=6 -#define DEFAULT_OVERSAMPLE 6 - -// Whether to dump out a log of all register and value changes and raw output pcm -//#define DEBUGSAA -#undef DEBUGSAA - -// the (default) names of the register output and pcm output log files. -// If you're using a config file, you can change these (or, if you enable -// debugging via the config file settings, but leave the filenames unspecified, -// it will use these defaults) -#define DEBUG_SAA_REGISTER_LOG "debugsaa.txt" -#define DEBUG_SAA_PCM_LOG "debugsaa.pcm" -// Whether to include support for these debug logs via config file (only making -// sense if USE_CONFIG_FILE is also defined) - -// Whether to support a startup configuration file that is parsed at load time -// #undef USE_CONFIG_FILE -#define USE_CONFIG_FILE - -// and if so, what is its location -#ifdef USE_CONFIG_FILE -#define CONFIG_FILE_PATH "SAASound.cfg" -#endif // USE_CONFIG_FILE - -#define DEFAULT_UNBOOSTED_MULTIPLIER 11.35 - -#define DEFAULT_BOOST 1 - - -#endif // HAVE_CONFIG_H - -#endif // DEFNS_H_INCLUDED diff --git a/src/sound/saasound/resource.h b/src/sound/saasound/resource.h deleted file mode 100755 index 0b893bf3a..000000000 --- a/src/sound/saasound/resource.h +++ /dev/null @@ -1,15 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by SAASound.rc -// - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/sound/saasound/saasound_cmake_config.h b/src/sound/saasound/saasound_cmake_config.h deleted file mode 100644 index da914a71b..000000000 --- a/src/sound/saasound/saasound_cmake_config.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#define EXTERNAL_CLK_HZ 7159090 -/* #undef SAAFREQ_FIXED_CLOCKRATE */ -#define SAMPLE_RATE_HZ 44100 -#define DEFAULT_OVERSAMPLE 6 -#define DEFAULT_UNBOOSTED_MULTIPLIER 11.3 -#define DEFAULT_BOOST 1 -/* #undef DEBUGSAA */ -#define DEBUG_SAA_REGISTER_LOG "debugsaa.txt" -#define DEBUG_SAA_PCM_LOG "debugsaa.pcm" - -/* #undef USE_CONFIG_FILE */ -#define CONFIG_FILE_PATH "SAASound.cfg" diff --git a/src/sound/saasound/types.h b/src/sound/saasound/types.h deleted file mode 100755 index 4eb62f485..000000000 --- a/src/sound/saasound/types.h +++ /dev/null @@ -1,34 +0,0 @@ -// Part of SAASound copyright 1998-2018 Dave Hooper -// -// handy typedefs -// -////////////////////////////////////////////////////////////////////// - -#ifndef TYPES_H_INCLUDED -#define TYPES_H_INCLUDED - -#if defined(__i386__) || defined(WIN32) || \ - (defined(__alpha__) || defined(__alpha)) || \ - defined(__arm__) || \ - (defined(__mips__) && defined(__MIPSEL__)) -#else -#define __BIG_ENDIAN -#endif - - -#ifndef NULL -#define NULL 0 -#endif - -typedef struct -{ - int nNumberOfPhases; - bool bLooping; - int nLevels[2][2][16]; // [Resolution][Phase][Withinphase] -} ENVDATA; - -#ifdef WIN32 -extern "C" void _stdcall OutputDebugStringA (char*); -#endif - -#endif diff --git a/src/sound/snd_ac97_codec.c b/src/sound/snd_ac97_codec.c index e92830f67..1b28a8aab 100644 --- a/src/sound/snd_ac97_codec.c +++ b/src/sound/snd_ac97_codec.c @@ -68,7 +68,6 @@ static const struct { .device = &cs4297_device, .misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_AUXOUT_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .reset_flags = AC97_HPOUT | AC97_DAC_18B | AC97_ADC_18B, - .extid_flags = 0, .pcsr_mask = 0x7f, .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x5a, 0x0301, 0x0000}, {0}} }, @@ -100,15 +99,18 @@ static const struct { { .device = &tr28023_device, .misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_POP | AC97_MS | AC97_LPBK, - .reset_flags = 0, - .extid_flags = 0, + .pcsr_mask = 0x3f + }, + { + .device = &w83971d_device, + .misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .reset_flags = (27 << AC97_3D_SHIFT), .pcsr_mask = 0x3f }, { .device = &wm9701a_device, .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .reset_flags = AC97_DAC_18B | AC97_ADC_18B, - .extid_flags = 0, .pcsr_mask = 0x3f } // clang-format on @@ -284,8 +286,9 @@ line_gain: case 0x22: /* 3D Control */ switch (ac97_codecs[dev->model].reset_flags >> AC97_3D_SHIFT) { - case 1: /* Analog Devices */ - case 6: /* Crystal */ + case 1: /* Analog Devices */ + case 6: /* Crystal */ + case 27: /* Winbond */ val &= 0x000f; break; @@ -764,6 +767,20 @@ const device_t tr28023_device = { .config = NULL }; +const device_t w83971d_device = { + .name = "Winbond W83971D", + .internal_name = "w83971d", + .flags = DEVICE_AC97, + .local = AC97_CODEC_W83971D, + .init = ac97_codec_init, + .close = ac97_codec_close, + .reset = ac97_codec_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t wm9701a_device = { .name = "Wolfson WM9701A", .internal_name = "wm9701a", diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index 202fd891a..e9a4390c0 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -731,9 +731,11 @@ ad1848_poll(void *priv) if (!(ad1848->status & 0x01)) { ad1848->status |= 0x01; ad1848->regs[24] |= 0x10; - if (ad1848->regs[10] & 2) - picint(1 << ad1848->irq); } + if (ad1848->regs[10] & 2) + picint(1 << ad1848->irq); + else + picintc(1 << ad1848->irq); } if (!(ad1848->adpcm_pos & 7)) /* ADPCM counts down every 4 bytes */ diff --git a/src/sound/snd_adlib.c b/src/sound/snd_adlib.c index 17990e842..b21a1f472 100644 --- a/src/sound/snd_adlib.c +++ b/src/sound/snd_adlib.c @@ -1,3 +1,21 @@ +/* + * 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. + * + * Adlib emulation. + * + * Authors: Sarah Walker, + * Miran Grca, + * Jasmine Iwanek, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2025 Miran Grca. + * Copyright 2024-2025 Jasmine Iwanek. + */ #include #include #include @@ -33,7 +51,7 @@ adlib_log(const char *fmt, ...) # define adlib_log(fmt, ...) #endif -typedef struct adlib_t { +typedef struct adlib_s { fm_drv_t opl; uint8_t pos_regs[8]; diff --git a/src/sound/snd_cms.c b/src/sound/snd_cms.c index 9491e3076..66dff80f3 100644 --- a/src/sound/snd_cms.c +++ b/src/sound/snd_cms.c @@ -8,7 +8,6 @@ #include <86box/86box.h> #include <86box/device.h> #include <86box/io.h> -#include "saasound/SAASound.h" #include <86box/snd_cms.h> #include <86box/sound.h> #include <86box/plat_unused.h> @@ -16,13 +15,62 @@ void cms_update(cms_t *cms) { - if (cms->pos < wavetable_pos_global) { - SAASNDGenerateMany(cms->saasound, (unsigned char*)&cms->buffer[cms->pos], wavetable_pos_global - cms->pos); - cms->pos = wavetable_pos_global; - } - if (cms->pos2 < wavetable_pos_global) { - SAASNDGenerateMany(cms->saasound2, (unsigned char*)&cms->buffer2[cms->pos2], wavetable_pos_global - cms->pos2); - cms->pos2 = wavetable_pos_global; + for (; cms->pos < sound_pos_global; cms->pos++) { + int16_t out_l = 0; + int16_t out_r = 0; + + for (uint8_t c = 0; c < 4; c++) { + switch (cms->noisetype[c >> 1][c & 1]) { + case 0: + cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK / 256; + break; + case 1: + cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK / 512; + break; + case 2: + cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK / 1024; + break; + case 3: + cms->noisefreq[c >> 1][c & 1] = cms->freq[c >> 1][(c & 1) * 3]; + break; + + default: + break; + } + } + for (uint8_t c = 0; c < 2; c++) { + if (cms->regs[c][0x1C] & 1) { + for (uint8_t d = 0; d < 6; d++) { + if (cms->regs[c][0x14] & (1 << d)) { + if (cms->stat[c][d]) + out_l += (cms->vol[c][d][0] * 90); + if (cms->stat[c][d]) + out_r += (cms->vol[c][d][1] * 90); + cms->count[c][d] += cms->freq[c][d]; + if (cms->count[c][d] >= 24000) { + cms->count[c][d] -= 24000; + cms->stat[c][d] ^= 1; + } + } else if (cms->regs[c][0x15] & (1 << d)) { + if (cms->noise[c][d / 3] & 1) + out_l += (cms->vol[c][d][0] * 90); + if (cms->noise[c][d / 3] & 1) + out_r += (cms->vol[c][d][0] * 90); + } + } + for (uint8_t d = 0; d < 2; d++) { + cms->noisecount[c][d] += cms->noisefreq[c][d]; + while (cms->noisecount[c][d] >= 24000) { + cms->noisecount[c][d] -= 24000; + cms->noise[c][d] <<= 1; + if (!(((cms->noise[c][d] & 0x4000) >> 8) ^ (cms->noise[c][d] & 0x40))) + cms->noise[c][d] |= 1; + } + } + } + } + cms->buffer[cms->pos << 1] = out_l; + cms->buffer[(cms->pos << 1) + 1] = out_r; } } @@ -34,44 +82,68 @@ cms_get_buffer(int32_t *buffer, int len, void *priv) cms_update(cms); for (int c = 0; c < len * 2; c++) - buffer[c] += (cms->buffer[c] / 2); + buffer[c] += cms->buffer[c]; cms->pos = 0; } -void -cms_get_buffer_2(int32_t *buffer, int len, void *priv) -{ - cms_t *cms = (cms_t *) priv; - - cms_update(cms); - - for (int c = 0; c < len * 2; c++) - buffer[c] += (cms->buffer2[c] / 2); - - cms->pos2 = 0; -} - void cms_write(uint16_t addr, uint8_t val, void *priv) { cms_t *cms = (cms_t *) priv; + int voice; + int chip = (addr & 2) >> 1; switch (addr & 0xf) { case 0x1: /* SAA #1 Register Select Port */ - SAASNDWriteAddress(cms->saasound, val & 31); + cms->addrs[0] = val & 31; break; case 0x3: /* SAA #2 Register Select Port */ - SAASNDWriteAddress(cms->saasound2, val & 31); + cms->addrs[1] = val & 31; break; case 0x0: /* SAA #1 Data Port */ - cms_update(cms); - SAASNDWriteData(cms->saasound, val); - break; case 0x2: /* SAA #2 Data Port */ cms_update(cms); - SAASNDWriteData(cms->saasound2, val); + cms->regs[chip][cms->addrs[chip] & 31] = val; + switch (cms->addrs[chip] & 31) { + case 0x00: + case 0x01: + case 0x02: /*Volume*/ + case 0x03: + case 0x04: + case 0x05: + voice = cms->addrs[chip] & 7; + cms->vol[chip][voice][0] = val & 0xf; + cms->vol[chip][voice][1] = val >> 4; + break; + case 0x08: + case 0x09: + case 0x0A: /*Frequency*/ + case 0x0B: + case 0x0C: + case 0x0D: + voice = cms->addrs[chip] & 7; + cms->latch[chip][voice] = (cms->latch[chip][voice] & 0x700) | val; + cms->freq[chip][voice] = (MASTER_CLOCK / 512 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); + break; + case 0x10: + case 0x11: + case 0x12: /*Octave*/ + voice = (cms->addrs[chip] & 3) << 1; + cms->latch[chip][voice] = (cms->latch[chip][voice] & 0xFF) | ((val & 7) << 8); + cms->latch[chip][voice + 1] = (cms->latch[chip][voice + 1] & 0xFF) | ((val & 0x70) << 4); + cms->freq[chip][voice] = (MASTER_CLOCK / 512 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); + cms->freq[chip][voice + 1] = (MASTER_CLOCK / 512 << (cms->latch[chip][voice + 1] >> 8)) / (511 - (cms->latch[chip][voice + 1] & 255)); + break; + case 0x16: /*Noise*/ + cms->noisetype[chip][0] = val & 3; + cms->noisetype[chip][1] = (val >> 4) & 3; + break; + + default: + break; + } break; case 0x6: /* GameBlaster Write Port */ @@ -91,9 +163,9 @@ cms_read(uint16_t addr, void *priv) switch (addr & 0xf) { case 0x1: /* SAA #1 Register Select Port */ - return SAASNDReadAddress(cms->saasound); + return cms->addrs[0]; case 0x3: /* SAA #2 Register Select Port */ - return SAASNDReadAddress(cms->saasound2); + return cms->addrs[1]; case 0x4: /* GameBlaster Read port (Always returns 0x7F) */ return 0x7f; case 0xa: /* GameBlaster Read Port */ @@ -113,12 +185,7 @@ cms_init(UNUSED(const device_t *info)) uint16_t addr = device_get_config_hex16("base"); io_sethandler(addr, 0x0010, cms_read, NULL, NULL, cms_write, NULL, NULL, cms); - cms->saasound = newSAASND(); - SAASNDSetSoundParameters(cms->saasound, SAAP_44100 | SAAP_16BIT | SAAP_NOFILTER | SAAP_STEREO); - cms->saasound2 = newSAASND(); - SAASNDSetSoundParameters(cms->saasound2, SAAP_44100 | SAAP_16BIT | SAAP_NOFILTER | SAAP_STEREO); - wavetable_add_handler(cms_get_buffer, cms); - wavetable_add_handler(cms_get_buffer_2, cms); + sound_add_handler(cms_get_buffer, cms); return cms; } @@ -127,9 +194,6 @@ cms_close(void *priv) { cms_t *cms = (cms_t *) priv; - deleteSAASND(cms->saasound); - deleteSAASND(cms->saasound2); - free(cms); } diff --git a/src/sound/snd_covox.c b/src/sound/snd_covox.c new file mode 100644 index 000000000..aaffbcf08 --- /dev/null +++ b/src/sound/snd_covox.c @@ -0,0 +1,475 @@ +/* + * 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. + * + * Rainbow Arts PC-Soundman Emulation + * + * Authors: Jasmine Iwanek, + * + * Copyright 2025 Jasmine Iwanek. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H + +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/mca.h> +#include <86box/sound.h> +#include <86box/filters.h> +#include <86box/timer.h> +#include <86box/snd_opl.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> + +#define COVOX_SOUNDMAN 0 +#define COVOX_VOICEMASTERKEY 1 +#define COVOX_SOUNDMASTERPLUS 2 +#define COVOX_ISADACR0 3 +#define COVOX_ISADACR1 4 + +#ifdef ENABLE_COVOX_LOG +int covox_do_log = ENABLE_COVOX_LOG; + +static void +covox_log(const char *fmt, ...) +{ + va_list ap; + + if (covox_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define covox_log(fmt, ...) +#endif + +typedef struct covox_s { + fm_drv_t opl; + + uint8_t dac_val; + + int16_t buffer[2][SOUNDBUFLEN]; + int pos; +} covox_t; + +// TODO: Can this be rolled into covox_get_buffer? +static void +covox_update(covox_t *covox) +{ + for (; covox->pos < sound_pos_global; covox->pos++) { + covox->buffer[0][covox->pos] = (int8_t) (covox->dac_val ^ 0x80) * 0x40; + covox->buffer[1][covox->pos] = (int8_t) (covox->dac_val ^ 0x80) * 0x40; + } +} + +uint8_t +covox_read(uint16_t addr, void *priv) +{ +#if 0 + const covox_t *covox = (covox_t *) priv; +#endif + + covox_log("covox_read: addr=%04x\n", addr); + + return 0xff; +} + +void +covox_write(uint16_t addr, uint8_t val, void *priv) +{ + covox_t *covox = (covox_t *) priv; + + covox_log("covox_write: addr=%04x val=%02x\n", addr, val); + + switch (addr) { + case 0x221: // Soundman + case 0x229: // Soundman + case 0x22f: // Soundman, voicemasterkey + case 0x231: // isadac-r1? + case 0x24f: // voicemasterkey + case 0x279: // isadac-r0 (lPT2) + case 0x28f: // voicemasterkey + case 0x2cf: // voicemasterkey + case 0x301: // Soundman + case 0x309: // Soundman + case 0x30f: // soundman + case 0x331: // soundmasterplus + case 0x339: // soundmasterplus + case 0x371: // isadac-r0 + case 0x379: // isadac-r0 (lPT1) + case 0x381: // isadac-r0 + case 0x3bd: // isadac-r0 (lPT1-Mono) + covox->dac_val = val; + // TODO: Is this needed here? + covox_update(covox); + break; + + default: + break; + } +} + +static void +covox_get_buffer(int32_t *buffer, int len, void *priv) +{ + covox_t *covox = (covox_t *) priv; + + covox_update(covox); + + for (int c = 0; c < len; c++) { + buffer[c * 2] += dac_iir(0, covox->buffer[0][c]); + buffer[c * 2 + 1] += dac_iir(1, covox->buffer[1][c]); + } + covox->pos = 0; +} + +static void +covox_get_music_buffer(int32_t *buffer, int len, void *priv) +{ + covox_t *covox = (covox_t *) priv; + + const int32_t *opl_buf = covox->opl.update(covox->opl.priv); + + for (int c = 0; c < len * 2; c++) + buffer[c] += opl_buf[c]; + + if (covox->opl.reset_buffer) + covox->opl.reset_buffer(covox->opl.priv); +} + +#define IO_SETHANDLER_COVOX_DAC(addr, len) \ + io_sethandler((addr), (len), \ + covox_read, NULL, NULL, \ + covox_write, NULL, NULL, \ + covox) + +#define IO_SETHANDLER_COVOX_ADLIB(addr, len) \ + io_sethandler((addr), (len), \ + covox->opl.read, NULL, NULL, \ + covox->opl.write, NULL, NULL, \ + covox->opl.priv) + +void * +covox_init(UNUSED(const device_t *info)) +{ + covox_t *covox = calloc(1, sizeof(covox_t)); + uint8_t has_adlib = 0; + uint8_t has_stereo = 0; + uint8_t fixed_address = 0; + if (!covox) + return NULL; + + covox_log("covox_init\n"); + switch (info->local) { + case COVOX_SOUNDMAN: + fixed_address = 1; + fallthrough; + case COVOX_SOUNDMASTERPLUS: + has_adlib = 1; + break; + + case COVOX_ISADACR0: + has_stereo = 1; + break; + + case COVOX_ISADACR1: + has_stereo = 2; + break; + + default: + break; + } + + if (fixed_address) { + IO_SETHANDLER_COVOX_DAC(0x220, 0x0002); + IO_SETHANDLER_COVOX_DAC(0x228, 0x0002); + IO_SETHANDLER_COVOX_DAC(0x22e, 0x0002); +#if 0 + // According to vgmpf, this is the address + IO_SETHANDLER_COVOX_DAC(0x22f, 0x0001); +#endif + IO_SETHANDLER_COVOX_DAC(0x300, 0x0002); + IO_SETHANDLER_COVOX_DAC(0x308, 0x0002); + IO_SETHANDLER_COVOX_DAC(0x30e, 0x0002); + } else { + IO_SETHANDLER_COVOX_DAC(device_get_config_hex16("base"), 0x0002); + + // TODO: Needs more work + if (has_stereo) + IO_SETHANDLER_COVOX_DAC(device_get_config_hex16("base2"), 0x0002); + } + sound_add_handler(covox_get_buffer, covox); + + if (has_adlib) { + fm_driver_get(FM_YM3812, &covox->opl); + if (fixed_address) { + // Adlib Clone part + IO_SETHANDLER_COVOX_ADLIB(0x380, 0x0002); + IO_SETHANDLER_COVOX_ADLIB(0x388, 0x0002); + IO_SETHANDLER_COVOX_ADLIB(0x38e, 0x0002); + } else + IO_SETHANDLER_COVOX_ADLIB(device_get_config_hex16("adlibbase"), 0x0002); + + music_add_handler(covox_get_music_buffer, covox); + } + + return covox; +} + +void +covox_close(void *priv) +{ + covox_t *covox = (covox_t *) priv; + + if (covox) + free(covox); +} + +// clang-format off +static const device_config_t voicemasterkey_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x388, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x22f", .value = 0x22f }, + { .description = "0x24f", .value = 0x24f }, + { .description = "0x28f", .value = 0x28f }, + { .description = "0x2cf", .value = 0x2cf }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +// Note: We don't support sound input on this yet +const device_t voicemasterkey_device = { + .name = "Covox Voice Master Key", + .internal_name = "voicemasterkey", + .flags = DEVICE_ISA | DEVICE_SIDECAR, + .local = COVOX_VOICEMASTERKEY, + .init = covox_init, + .close = covox_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = voicemasterkey_config +}; + +// clang-format off +static const device_config_t soundmasterplus_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x330, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x330", .value = 0x330 }, + { .description = "0x338", .value = 0x338 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "adlibbase", + .description = "Adlib Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x388, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x388", .value = 0x388 }, + { .description = "0x380", .value = 0x380 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +const device_t soundmasterplus_device = { + .name = "Covox Sound Master Plus", + .internal_name = "soundmasterplus", + .flags = DEVICE_ISA | DEVICE_SIDECAR, + .local = COVOX_SOUNDMASTERPLUS, + .init = covox_init, + .close = covox_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = soundmasterplus_config +}; + +// clang-format off +static const device_config_t isadacr0_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x380, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x220", .value = 0x220 }, + { .description = "0x228", .value = 0x228 }, + { .description = "0x22e", .value = 0x22e }, + { .description = "0x230", .value = 0x230 }, + { .description = "0x24e", .value = 0x24e }, + { .description = "0x278", .value = 0x278 }, + { .description = "0x28e", .value = 0x28e }, + { .description = "0x2ce", .value = 0x2ce }, + { .description = "0x300", .value = 0x300 }, + { .description = "0x308", .value = 0x308 }, + { .description = "0x303", .value = 0x30e }, + { .description = "0x330", .value = 0x330 }, + { .description = "0x338", .value = 0x338 }, + { .description = "0x370", .value = 0x370 }, + { .description = "0x378", .value = 0x378 }, + { .description = "0x380", .value = 0x380 }, + { .description = "0x3bc", .value = 0x3bc }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "base2", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x370, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x220", .value = 0x220 }, + { .description = "0x228", .value = 0x228 }, + { .description = "0x22e", .value = 0x22e }, + { .description = "0x230", .value = 0x230 }, + { .description = "0x24e", .value = 0x24e }, + { .description = "0x278", .value = 0x278 }, + { .description = "0x28e", .value = 0x28e }, + { .description = "0x2ce", .value = 0x2ce }, + { .description = "0x300", .value = 0x300 }, + { .description = "0x308", .value = 0x308 }, + { .description = "0x303", .value = 0x30e }, + { .description = "0x330", .value = 0x330 }, + { .description = "0x338", .value = 0x338 }, + { .description = "0x370", .value = 0x370 }, + { .description = "0x378", .value = 0x378 }, + { .description = "0x380", .value = 0x380 }, + { .description = "0x3bc", .value = 0x3bc }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +// Note: We don't support stereo on this yet +const device_t isadacr0_device = { + .name = "ISA DAC-r0", + .internal_name = "isadacr0", + .flags = DEVICE_ISA | DEVICE_SIDECAR, + .local = COVOX_ISADACR0, + .init = covox_init, + .close = covox_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = isadacr0_config +}; + +// clang-format off +static const device_config_t isadacr1_config[] = { + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x378, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x378", .value = 0x378 }, + { .description = "0x3bc", .value = 0x3bc }, + { .description = "0x278", .value = 0x278 }, + { .description = "0x230", .value = 0x230 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "base2", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x278, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x378", .value = 0x378 }, + { .description = "0x3bc", .value = 0x3bc }, + { .description = "0x278", .value = 0x278 }, + { .description = "0x230", .value = 0x230 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +// Note: We don't support stereo on this yet +const device_t isadacr1_device = { + .name = "ISA DAC-r1", + .internal_name = "isadacr1", + .flags = DEVICE_ISA | DEVICE_SIDECAR, + .local = COVOX_ISADACR1, + .init = covox_init, + .close = covox_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = isadacr1_config +}; + +const device_t soundman_device = { + .name = "Rainbow Arts PC-Soundman", + .internal_name = "soundman", + .flags = DEVICE_ISA | DEVICE_SIDECAR, + .local = COVOX_SOUNDMAN, + .init = covox_init, + .close = covox_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index 17ea48dd3..74382a53b 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -650,15 +650,7 @@ cs423x_pnp_enable(cs423x_t *dev, uint8_t update_rom, uint8_t update_hwconfig) isapnp_update_card_rom(dev->pnp_card, &dev->ram_data[dev->pnp_offset], dev->pnp_size); /* Disable PnP key if the PKD bit is set, or if it was disabled by command 0x55. */ - /* But wait! The TriGem Delhi-III BIOS sends command 0x55, and its behavior doesn't - line up with real hardware (still listed in the POST summary and seen by software). - Disable the PnP key disabling mechanism until someone figures something out. */ -#if 0 isapnp_enable_card(dev->pnp_card, ((dev->ram_data[0x4002] & 0x20) || !dev->pnp_enable) ? ISAPNP_CARD_NO_KEY : ISAPNP_CARD_ENABLE); -#else - if ((dev->ram_data[0x4002] & 0x20) || !dev->pnp_enable) - pclog("CS423x: Attempted to disable PnP key\n"); -#endif } /* Update some register bits based on the config data in RAM if requested. */ diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 1885581a5..80ce6781d 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -17,9 +17,7 @@ #include <86box/sound.h> #include "cpu.h" #include <86box/timer.h> -#ifdef USE_GUSMAX -# include <86box/snd_ad1848.h> -#endif /*USE_GUSMAX */ +#include <86box/snd_ad1848.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> @@ -145,11 +143,9 @@ typedef struct gus_t { uint8_t usrr; -#ifdef USE_GUSMAX uint8_t max_ctrl; ad1848_t ad1848; -#endif /*USE_GUSMAX */ } gus_t; static int gus_gf1_irqs[8] = { -1, 2, 5, 3, 7, 11, 12, 15 }; @@ -250,16 +246,14 @@ gus_midi_update_int_status(gus_t *gus) } void -writegus(uint16_t addr, uint8_t val, void *priv) +gus_write(uint16_t addr, uint8_t val, void *priv) { gus_t *gus = (gus_t *) priv; int c; int d; int old; uint16_t port; -#ifdef USE_GUSMAX uint16_t csioport; -#endif /*USE_GUSMAX */ if ((addr == 0x388) || (addr == 0x389)) port = addr; @@ -607,10 +601,9 @@ writegus(uint16_t addr, uint8_t val, void *priv) gus->irq_midi = gus->irq; } else gus->irq_midi = gus_midi_irqs[(val >> 3) & 7]; -#ifdef USE_GUSMAX + if (gus->type == GUS_MAX) ad1848_setirq(&gus->ad1848, gus->irq); -#endif /*USE_GUSMAX */ gus->sb_nmi = val & 0x80; } else { @@ -623,10 +616,9 @@ writegus(uint16_t addr, uint8_t val, void *priv) gus->dma2 = gus->dma; } else gus->dma2 = gus_dmas[(val >> 3) & 7]; -#ifdef USE_GUSMAX + if (gus->type == GUS_MAX) ad1848_setdma(&gus->ad1848, gus->dma2); -#endif /*USE_GUSMAX */ } break; case 1: @@ -684,7 +676,6 @@ writegus(uint16_t addr, uint8_t val, void *priv) break; case 0x306: case 0x706: -#ifdef USE_GUSMAX if (gus->type == GUS_MAX) { if (gus->dma >= 4) val |= 0x10; @@ -704,7 +695,6 @@ writegus(uint16_t addr, uint8_t val, void *priv) } } } -#endif /*USE_GUSMAX */ break; default: @@ -713,7 +703,7 @@ writegus(uint16_t addr, uint8_t val, void *priv) } uint8_t -readgus(uint16_t addr, void *priv) +gus_read(uint16_t addr, void *priv) { gus_t *gus = (gus_t *) priv; uint8_t val = 0xff; @@ -756,11 +746,9 @@ readgus(uint16_t addr, void *priv) return val; case 0x20F: -#ifdef USE_GUSMAX if (gus->type == GUS_MAX) val = 0x02; else -#endif /*USE_GUSMAX */ val = 0x00; break; @@ -879,11 +867,9 @@ readgus(uint16_t addr, void *priv) break; case 0x306: case 0x706: -#ifdef USE_GUSMAX if (gus->type == GUS_MAX) val = 0x0a; /* GUS MAX */ else -#endif /*USE_GUSMAX */ val = 0xff; /*Pre 3.7 - no mixer*/ break; @@ -1183,24 +1169,20 @@ gus_get_buffer(int32_t *buffer, int len, void *priv) { gus_t *gus = (gus_t *) priv; -#ifdef USE_GUSMAX if ((gus->type == GUS_MAX) && (gus->max_ctrl)) ad1848_update(&gus->ad1848); -#endif /*USE_GUSMAX */ + gus_update(gus); for (int c = 0; c < len * 2; c++) { -#ifdef USE_GUSMAX if ((gus->type == GUS_MAX) && (gus->max_ctrl)) buffer[c] += (int32_t) (gus->ad1848.buffer[c] / 2); -#endif /*USE_GUSMAX */ buffer[c] += (int32_t) gus->buffer[c & 1][c >> 1]; } -#ifdef USE_GUSMAX if ((gus->type == GUS_MAX) && (gus->max_ctrl)) gus->ad1848.pos = 0; -#endif /*USE_GUSMAX */ + gus->pos = 0; } @@ -1333,9 +1315,7 @@ gus_reset(void *priv) gus->usrr = 0; -#ifdef USE_GUSMAX gus->max_ctrl = 0; -#endif /*USE_GUSMAX */ gus->irq_state = 0; gus->midi_irq_state = 0; @@ -1373,16 +1353,15 @@ gus_init(UNUSED(const device_t *info)) gus->uart_out = 1; - gus->type = device_get_config_int("type"); + gus->type = info->local; gus->base = device_get_config_hex16("base"); - io_sethandler(gus->base, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); - io_sethandler(0x0100 + gus->base, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); - io_sethandler(0x0506 + gus->base, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus); - io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus); + io_sethandler(gus->base, 0x0010, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + io_sethandler(0x0100 + gus->base, 0x0010, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + io_sethandler(0x0506 + gus->base, 0x0001, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + io_sethandler(0x0388, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); -#ifdef USE_GUSMAX if (gus->type == GUS_MAX) { ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231); ad1848_setirq(&gus->ad1848, 5); @@ -1390,7 +1369,6 @@ gus_init(UNUSED(const device_t *info)) io_sethandler(0x10C + gus->base, 4, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &gus->ad1848); } -#endif /*USE_GUSMAX */ timer_add(&gus->samp_timer, gus_poll_wave, gus, 1); timer_add(&gus->timer_1, gus_poll_timer_1, gus, 1); @@ -1423,31 +1401,12 @@ gus_speed_changed(void *priv) else gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); -#ifdef USE_GUSMAX if ((gus->type == GUS_MAX) && (gus->max_ctrl)) ad1848_speed_changed(&gus->ad1848); -#endif /*USE_GUSMAX */ } static const device_config_t gus_config[] = { // clang-format off - { - .name = "type", - .description = "GUS type", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "Classic", .value = GUS_CLASSIC }, -#ifdef USE_GUSMAX - { .description = "MAX", .value = GUS_MAX }, -#endif /*USE_GUSMAX */ - { NULL } - }, - .bios = { { 0 } } - }, { .name = "base", .description = "Address", @@ -1502,7 +1461,21 @@ const device_t gus_device = { .name = "Gravis UltraSound", .internal_name = "gus", .flags = DEVICE_ISA16, - .local = 0, + .local = GUS_CLASSIC, + .init = gus_init, + .close = gus_close, + .reset = gus_reset, + .available = NULL, + .speed_changed = gus_speed_changed, + .force_redraw = NULL, + .config = gus_config +}; + +const device_t gus_max_device = { + .name = "Gravis UltraSound MAX", + .internal_name = "gusmax", + .flags = DEVICE_ISA16, + .local = GUS_MAX, .init = gus_init, .close = gus_close, .reset = gus_reset, diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index 0462818a0..99cf66916 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -8,6 +8,7 @@ #include <86box/86box.h> #include <86box/filters.h> #include <86box/timer.h> +#include <86box/device.h> #include <86box/lpt.h> #include <86box/machine.h> #include <86box/sound.h> @@ -50,6 +51,14 @@ dac_write_data(uint8_t val, void *priv) dac_update(lpt_dac); } +static void +dac_strobe(uint8_t old, uint8_t val, void *priv) +{ + lpt_dac_t *lpt_dac = (lpt_dac_t *) priv; + + lpt_dac->channel = val; +} + static void dac_write_ctrl(uint8_t val, void *priv) { @@ -109,25 +118,35 @@ dac_close(void *priv) } const lpt_device_t lpt_dac_device = { - .name = "LPT DAC / Covox Speech Thing", - .internal_name = "lpt_dac", - .init = dac_init, - .close = dac_close, - .write_data = dac_write_data, - .write_ctrl = dac_write_ctrl, - .read_data = NULL, - .read_status = dac_read_status, - .read_ctrl = NULL + .name = "LPT DAC / Covox Speech Thing", + .internal_name = "lpt_dac", + .init = dac_init, + .close = dac_close, + .write_data = dac_write_data, + .write_ctrl = dac_write_ctrl, + .autofeed = NULL, + .strobe = dac_strobe, + .read_status = dac_read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL, + .priv = NULL, + .lpt = NULL }; const lpt_device_t lpt_dac_stereo_device = { - .name = "Stereo LPT DAC", - .internal_name = "lpt_dac_stereo", - .init = dac_stereo_init, - .close = dac_close, - .write_data = dac_write_data, - .write_ctrl = dac_write_ctrl, - .read_data = NULL, - .read_status = dac_read_status, - .read_ctrl = NULL + .name = "Stereo LPT DAC", + .internal_name = "lpt_dac_stereo", + .init = dac_stereo_init, + .close = dac_close, + .write_data = dac_write_data, + .write_ctrl = dac_write_ctrl, + .autofeed = NULL, + .strobe = dac_strobe, + .read_status = dac_read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL, + .priv = NULL, + .lpt = NULL }; diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index 875230518..206f44ec8 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -8,6 +8,7 @@ #include <86box/86box.h> #include <86box/filters.h> #include <86box/timer.h> +#include <86box/device.h> #include <86box/lpt.h> #include <86box/machine.h> #include <86box/sound.h> @@ -133,13 +134,18 @@ dss_close(void *priv) } const lpt_device_t dss_device = { - .name = "Disney Sound Source", - .internal_name = "dss", - .init = dss_init, - .close = dss_close, - .write_data = dss_write_data, - .write_ctrl = dss_write_ctrl, - .read_data = NULL, - .read_status = dss_read_status, - .read_ctrl = NULL + .name = "Disney Sound Source", + .internal_name = "dss", + .init = dss_init, + .close = dss_close, + .write_data = dss_write_data, + .autofeed = NULL, + .strobe = NULL, + .write_ctrl = dss_write_ctrl, + .read_status = dss_read_status, + .read_ctrl = NULL, + .epp_write_data = NULL, + .epp_request_read = NULL, + .priv = NULL, + .lpt = NULL }; diff --git a/src/sound/snd_mmb.c b/src/sound/snd_mmb.c new file mode 100644 index 000000000..35a72efbc --- /dev/null +++ b/src/sound/snd_mmb.c @@ -0,0 +1,339 @@ +/* + * 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. + * + * Mindscape Music Board emulation. + * + * Authors: Roy Baer, + * Jasmine Iwanek, + * + * Copyright 2025 Roy Baer. + * Copyright 2025 Jasmine Iwanek. + */ +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/sound.h> +//#i nclude "cpu.h" +#include "ayumi/ayumi.h" +#include <86box/snd_mmb.h> +#include <86box/plat_unused.h> + +#ifdef ENABLE_MMB_LOG +int mmb_do_log = ENABLE_MMB_LOG; + +static void +mmb_log(const char *fmt, ...) +{ + va_list ap; + + if (mmb_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define mmb_log(fmt, ...) +#endif + +void +mmb_update(mmb_t *mmb) +{ + for (; mmb->pos < sound_pos_global; mmb->pos++) { + ayumi_process(&mmb->first.chip); + ayumi_process(&mmb->second.chip); + + ayumi_remove_dc(&mmb->first.chip); + ayumi_remove_dc(&mmb->second.chip); + + mmb->buffer[mmb->pos << 1] = (mmb->first.chip.left + mmb->second.chip.left) * 16000; + mmb->buffer[(mmb->pos << 1) + 1] = (mmb->first.chip.right + mmb->second.chip.right) * 16000; + } +} + +void +mmb_get_buffer(int32_t *buffer, int len, void *priv) +{ + mmb_t *mmb = (mmb_t *) priv; + + mmb_update(mmb); + + for (int c = 0; c < len * 2; c++) + buffer[c] += mmb->buffer[c]; + + mmb->pos = 0; +} + +void +mmb_write(uint16_t addr, uint8_t val, void *priv) +{ + mmb_t *mmb = (mmb_t *) priv; + + mmb_update(mmb); + + mmb_log("mmb_write(%04X): activity now: %02X\n", addr, val); + + switch (addr & 3) { + case 0: + mmb->first.index = val; + break; + case 2: + mmb->second.index = val; + break; + case 1: + case 3: + { + ay_3_891x_t *ay = ((addr & 2) == 0) ? &mmb->first : &mmb->second; + + switch (ay->index) { + case 0: + ay->regs[0] = val; + ayumi_set_tone(&ay->chip, 0, (ay->regs[1] << 8) | ay->regs[0]); + break; + case 1: + ay->regs[1] = val & 0xf; + ayumi_set_tone(&ay->chip, 0, (ay->regs[1] << 8) | ay->regs[0]); + break; + case 2: + ay->regs[2] = val; + ayumi_set_tone(&ay->chip, 1, (ay->regs[3] << 8) | ay->regs[2]); + break; + case 3: + ay->regs[3] = val & 0xf; + ayumi_set_tone(&ay->chip, 1, (ay->regs[3] << 8) | ay->regs[2]); + break; + case 4: + ay->regs[4] = val; + ayumi_set_tone(&ay->chip, 2, (ay->regs[5] << 8) | ay->regs[4]); + break; + case 5: + ay->regs[5] = val & 0xf; + ayumi_set_tone(&ay->chip, 2, (ay->regs[5] << 8) | ay->regs[4]); + break; + case 6: + ay->regs[6] = val & 0x1f; + ayumi_set_noise(&ay->chip, ay->regs[6]); + break; + case 7: + ay->regs[7] = val; + ayumi_set_mixer(&ay->chip, 0, val & 1, (val >> 3) & 1, (ay->regs[8] >> 4) & 1); + ayumi_set_mixer(&ay->chip, 1, (val >> 1) & 1, (val >> 4) & 1, (ay->regs[9] >> 4) & 1); + ayumi_set_mixer(&ay->chip, 2, (val >> 2) & 1, (val >> 5) & 1, (ay->regs[10] >> 4) & 1); + break; + case 8: + ay->regs[8] = val; + ayumi_set_volume(&ay->chip, 0, val & 0xf); + ayumi_set_mixer(&ay->chip, 0, ay->regs[7] & 1, (ay->regs[7] >> 3) & 1, (val >> 4) & 1); + break; + case 9: + ay->regs[9] = val; + ayumi_set_volume(&ay->chip, 1, val & 0xf); + ayumi_set_mixer(&ay->chip, 1, (ay->regs[7] >> 1) & 1, (ay->regs[7] >> 4) & 1, (val >> 4) & 1); + break; + case 10: + ay->regs[10] = val; + ayumi_set_volume(&ay->chip, 2, val & 0xf); + ayumi_set_mixer(&ay->chip, 2, (ay->regs[7] >> 2) & 1, (ay->regs[7] >> 5) & 1, (val >> 4) & 1); + break; + case 11: + ay->regs[11] = val; + ayumi_set_envelope(&ay->chip, (ay->regs[12] >> 8) | ay->regs[11]); + break; + case 12: + ay->regs[12] = val; + ayumi_set_envelope(&ay->chip, (ay->regs[12] >> 8) | ay->regs[11]); + break; + case 13: + ay->regs[13] = val; + ayumi_set_envelope_shape(&ay->chip, val & 0xf); + break; + case 14: + ay->regs[14] = val; + break; + case 15: + ay->regs[15] = val; + break; + + default: + break; + } + break; + } + + default: + break; + } +} + +uint8_t +mmb_read(uint16_t addr, void *priv) +{ + mmb_t *mmb = (mmb_t *) priv; + ay_3_891x_t *ay = ((addr & 2) == 0) ? &mmb->first : &mmb->second; + uint8_t ret = 0; + + switch (ay->index) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + ret = ay->regs[ay->index]; + break; + case 14: + if (ay->regs[7] & 0x40) + ret = ay->regs[14]; + break; + case 15: + if (ay->regs[7] & 0x80) + ret = ay->regs[15]; + break; + + default: + break; + } + + mmb_log("mmb_read(%04X): activity now: %02X\n", addr, ret); + + return ret; +} + +void * +mmb_init(UNUSED(const device_t *info)) +{ + mmb_t *mmb = calloc(1, sizeof(mmb_t)); +# if 0 + uint16_t addr = (device_get_config_int("addr96") << 6) | (device_get_config_int("addr52") << 2); +#else + uint16_t addr = 0x300; + +#endif + sound_add_handler(mmb_get_buffer, mmb); + + ayumi_configure(&mmb->first.chip, 0, MMB_CLOCK, MMB_FREQ); + ayumi_configure(&mmb->second.chip, 0, MMB_CLOCK, MMB_FREQ); + + for (uint8_t i = 0; i < 3; i++) { + ayumi_set_pan(&mmb->first.chip, i, 0.5, 1); + ayumi_set_pan(&mmb->second.chip, i, 0.5, 1); + } + + io_sethandler(addr, 0x0004, + mmb_read, NULL, NULL, + mmb_write, NULL, NULL, + mmb); + + return mmb; +} + +void +mmb_close(void *priv) +{ + mmb_t *mmb = (mmb_t *) priv; + + free(mmb); +} + +// clang-format off +#if 0 +static device_config_t mmb_config[] = { + { + .name = "addr96", + .description = "Base address A9...A6", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 12, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0000", .value = 0 }, + { .description = "0001", .value = 1 }, + { .description = "0010", .value = 2 }, + { .description = "0011", .value = 3 }, + { .description = "0100", .value = 4 }, + { .description = "0101", .value = 5 }, + { .description = "0110", .value = 6 }, + { .description = "0111", .value = 7 }, + { .description = "1000", .value = 8 }, + { .description = "1001", .value = 9 }, + { .description = "1010", .value = 10 }, + { .description = "1011", .value = 11 }, + { .description = "1100", .value = 12 }, + { .description = "1101", .value = 13 }, + { .description = "1110", .value = 14 }, + { .description = "1111", .value = 15 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "addr52", + .description = "Base address A5...A2", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0000", .value = 0 }, + { .description = "0001", .value = 1 }, + { .description = "0010", .value = 2 }, + { .description = "0011", .value = 3 }, + { .description = "0100", .value = 4 }, + { .description = "0101", .value = 5 }, + { .description = "0110", .value = 6 }, + { .description = "0111", .value = 7 }, + { .description = "1000", .value = 8 }, + { .description = "1001", .value = 9 }, + { .description = "1010", .value = 10 }, + { .description = "1011", .value = 11 }, + { .description = "1100", .value = 12 }, + { .description = "1101", .value = 13 }, + { .description = "1110", .value = 14 }, + { .description = "1111", .value = 15 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .type = CONFIG_END } +}; +#endif +// clang-format on + +const device_t mmb_device = { + .name = "Mindscape Music Board", + .internal_name = "mmb", + .flags = DEVICE_ISA, + .local = 0, + .init = mmb_init, + .close = mmb_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, +#if 0 + .config = mmb_config +#else + .config = NULL +#endif +}; diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index cfefc8df5..9b82d580d 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -792,14 +792,10 @@ pas16_in(uint16_t port, void *priv) if ((scsi_bus->tx_mode == PIO_TX_BUS) && !(ret & 0x80)) ret |= 0x80; - if (ret & 0x80) { - if (scsi_bus->data_repeat < MIN(511, scsi_bus->total_len)) - scsi_bus->data_repeat++; - } else { - if (scsi_bus->data_repeat == MIN(511, scsi_bus->total_len)) - ret = 0x00; - } - pas16_log("%04X:%08X: Port %04x read ret=%02x, status=%02x, txmode=%x, repeat=%d.\n", CS, cpu_state.pc, port + pas16->base, ret, pas16->scsi->status & 0x06, scsi_bus->tx_mode, scsi_bus->data_repeat); + if ((pas16->scsi->status & 0x06) == 0x00) + ret = 0x00; + + pas16_log("%04X:%08X: Port %04x read ret=%02x, status=%02x, txmode=%x, repeat=%d, total=%d.\n", CS, cpu_state.pc, port + pas16->base, ret, pas16->scsi->status & 0x06, scsi_bus->tx_mode, scsi_bus->data_repeat, MIN(511, scsi_bus->total_len)); } break; case 0x5c03: diff --git a/src/sound/snd_resid.cpp b/src/sound/snd_resid.cpp index b0503cac2..3dda5363b 100644 --- a/src/sound/snd_resid.cpp +++ b/src/sound/snd_resid.cpp @@ -20,23 +20,28 @@ typedef struct psid_t { psid_t *psid; void * -sid_init(uint8_t type) +sid_init(uint8_t type, double range) { reSIDfp::SamplingMethod method = reSIDfp::RESAMPLE; float cycles_per_sec = 14318180.0 / 16.0; psid = new psid_t; psid->sid = new SID; - + psid->sid->setFilter6581Range(range); + psid->sid->reset(); switch (type) { default: + psid->sid->setChipModel(reSIDfp::MOS6581); + break; case 0: psid->sid->setChipModel(reSIDfp::MOS6581); + break; case 1: psid->sid->setChipModel(reSIDfp::MOS8580); + break; } - psid->sid->reset(); + for (uint8_t c = 0; c < 32; c++) psid->sid->write(c, 0); @@ -101,4 +106,4 @@ sid_fillbuf(int16_t *buf, int len, UNUSED(void *priv)) int x = CLOCK_DELTA(len); fillbuf2(x, buf, len); -} +} \ No newline at end of file diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 4a17fe20b..f041ebb8c 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -41,7 +41,6 @@ #include <86box/sound.h> #include "cpu.h" #include <86box/timer.h> -#include "saasound/SAASound.h" #include <86box/snd_sb.h> #include <86box/plat_unused.h> @@ -146,42 +145,6 @@ sb_log(const char *fmt, ...) # define sb_log(fmt, ...) #endif -void -sb_cms_get_buffer(int32_t *buffer, int len, void *priv) -{ - sb_t *sb = (sb_t *) priv; - - cms_update(&sb->cms); - - for (int c = 0; c < len * 2; c++) { - if (sb->mixer_enabled) { - buffer[c] += sb->cms.buffer[c] * sb->mixer_sb2.fm; - } - else - buffer[c] += sb->cms.buffer[c]; - } - - sb->cms.pos = 0; -} - -void -sb_cms_get_buffer_2(int32_t *buffer, int len, void *priv) -{ - sb_t *sb = (sb_t *) priv; - - cms_update(&sb->cms); - - for (int c = 0; c < len * 2; c++) { - if (sb->mixer_enabled) { - buffer[c] += sb->cms.buffer2[c] * sb->mixer_sb2.fm; - } - else - buffer[c] += sb->cms.buffer2[c]; - } - - sb->cms.pos2 = 0; -} - /* SB 1, 1.5, MCV, and 2 do not have a mixer, so signal is hardwired. */ static void sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) @@ -192,10 +155,23 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) sb_dsp_update(&sb->dsp); + if (sb->cms_enabled) + cms_update(&sb->cms); + for (int c = 0; c < len * 2; c += 2) { double out_l = 0.0; double out_r = 0.0; + if (sb->cms_enabled) { + out_l += sb->cms.buffer[c]; + out_r += sb->cms.buffer[c + 1]; + } + + if (sb->cms_enabled && sb->mixer_enabled) { + out_l *= mixer->fm; + out_r *= mixer->fm; + } + /* TODO: Recording: I assume it has direct mic and line in like SB2. It is unclear from the docs if it has a filter, but it probably does. */ /* TODO: Recording: Mic and line In with AGC. */ @@ -216,6 +192,9 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) } sb->dsp.pos = 0; + + if (sb->cms_enabled) + sb->cms.pos = 0; } static void @@ -1173,11 +1152,14 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) 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); + if (sb->gameport != NULL) { + gameport_remap(sb->gameport, 0); + if (!(val & 0x01)) { + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, 0x200); + } } } break; @@ -1640,7 +1622,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) ess_fm_midi_write, NULL, NULL, ess); - gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); + if (ess->gameport != NULL) + gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); if (ess->dsp.sb_subtype > SB_SUBTYPE_ESS_ES1688) { /* Not on ES1688. */ @@ -2112,35 +2095,39 @@ 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); + if (addr != 0x0000) { + 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); + if (addr != 0x0000) { + 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); } @@ -2881,11 +2868,16 @@ sb_init(UNUSED(const device_t *info)) sb_dsp_init(&sb->dsp, model, 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_setdma8(&sb->dsp, 1); // SB 1, SB1.5 and 2 don't support DMA3 if (mixer_addr > 0x0000) sb_ct1335_mixer_reset(sb); + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_200_device); + sb->gameport_addr = 0x200; + } + /* DSP I/O handler is activated in sb_dsp_setaddr */ if (sb->opl_enabled) { // TODO: See if this applies to the SB1.5 as well @@ -2911,13 +2903,6 @@ sb_init(UNUSED(const device_t *info)) cms_read, NULL, NULL, cms_write, NULL, NULL, &sb->cms); - - sb->cms.saasound = newSAASND(); - SAASNDSetSoundParameters(sb->cms.saasound, SAAP_44100 | SAAP_16BIT | SAAP_NOFILTER | SAAP_STEREO); - sb->cms.saasound2 = newSAASND(); - SAASNDSetSoundParameters(sb->cms.saasound2, SAAP_44100 | SAAP_16BIT | SAAP_NOFILTER | SAAP_STEREO); - wavetable_add_handler(sb_cms_get_buffer, sb); - wavetable_add_handler(sb_cms_get_buffer_2, sb); } if (mixer_addr > 0x000) { @@ -2972,6 +2957,11 @@ sb_mcv_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); + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_200_device); + sb->gameport_addr = 0x200; + } + return sb; } @@ -3054,6 +3044,11 @@ sb_pro_v1_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); + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_200_device); + sb->gameport_addr = 0x200; + } + return sb; } @@ -3108,6 +3103,11 @@ sb_pro_v2_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); + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_200_device); + sb->gameport_addr = 0x200; + } + return sb; } @@ -3141,6 +3141,11 @@ sb_pro_mcv_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); + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_200_device); + sb->gameport_addr = 0x200; + } + return sb; } @@ -3225,9 +3230,16 @@ 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); + if (info->local == FM_YMF289B) { + sb->gameport = gameport_add(&gameport_pnp_device); + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); + } else { + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_200_device); + sb->gameport_addr = 0x200; + } + } return sb; } @@ -3261,7 +3273,7 @@ sb_16_reply_mca_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_device); + sb->gameport = gameport_add(&gameport_200_device); /* I/O handlers activated in sb_pro_mcv_write */ mca_add(sb_16_reply_mca_read, sb_16_reply_mca_write, sb_mcv_feedb, NULL, sb); @@ -3505,7 +3517,6 @@ sb_16_compat_init(const device_t *info) music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); mpu401_init(sb->mpu, 0, 0, M_UART, (int) (intptr_t) info->local); sb_dsp_set_mpu(&sb->dsp, sb->mpu); @@ -3573,8 +3584,6 @@ sb_awe32_init(UNUSED(const device_t *info)) uint16_t emu_addr = device_get_config_hex16("emu_base"); int onboard_ram = device_get_config_int("onboard_ram"); - memset(sb, 0x00, sizeof(sb_t)); - sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) fm_driver_get(FM_YMF262, &sb->opl); @@ -3618,7 +3627,6 @@ sb_awe32_init(UNUSED(const device_t *info)) if (mpu_addr) { sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); mpu401_init(sb->mpu, device_get_config_hex16("base401"), 0, M_UART, device_get_config_int("receive_input401")); } else @@ -3630,9 +3638,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); + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_200_device); + sb->gameport_addr = 0x200; + } return sb; } @@ -3894,9 +3903,10 @@ ess_x688_init(UNUSED(const device_t *info)) sb_dsp_set_mpu(&ess->dsp, ess->mpu); } - ess->gameport = gameport_add(&gameport_pnp_device); - ess->gameport_addr = 0x200; - gameport_remap(ess->gameport, ess->gameport_addr); + if (device_get_config_int("gameport")) { + ess->gameport = gameport_add(&gameport_200_device); + ess->gameport_addr = 0x200; + } if (ide_base > 0x0000) { device_add(&ide_qua_pnp_device); @@ -4042,7 +4052,7 @@ ess_x688_mca_init(UNUSED(const device_t *info)) sb_dsp_set_mpu(&ess->dsp, ess->mpu); } - ess->gameport = gameport_add(&gameport_device); + ess->gameport = gameport_add(&gameport_200_device); mpu401_change_addr(ess->mpu, 0); @@ -4072,11 +4082,6 @@ sb_close(void *priv) sb_t *sb = (sb_t *) priv; sb_dsp_close(&sb->dsp); - if (sb->cms_enabled) { - deleteSAASND(sb->cms.saasound); - deleteSAASND(sb->cms.saasound2); - } - free(sb); } @@ -4147,18 +4152,14 @@ static const device_config_t sb_config[] = { .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, .default_string = NULL, - .default_int = 1, + .default_int = 0, .file_filter = NULL, .spinner = { 0 }, - .selection = { - { .description = "DMA 1", .value = 1 }, - { .description = "DMA 3", .value = 3 }, - { .description = "" } - }, + .selection = { { 0 } }, .bios = { { 0 } } }, { @@ -4182,7 +4183,7 @@ static const device_config_t sb_config[] = { .spinner = { 0 }, .selection = { { 0 } }, .bios = { { 0 } } - }, + }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -4207,8 +4208,8 @@ static const device_config_t sb15_config[] = { .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", + .name = "irq", + .description = "IRQ", .type = CONFIG_SELECTION, .default_string = NULL, .default_int = 7, @@ -4224,18 +4225,14 @@ static const device_config_t sb15_config[] = { .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, .default_string = NULL, - .default_int = 1, + .default_int = 0, .file_filter = NULL, .spinner = { 0 }, - .selection = { - { .description = "DMA 1", .value = 1 }, - { .description = "DMA 3", .value = 3 }, - { .description = "" } - }, + .selection = { { 0 } }, .bios = { { 0 } } }, { @@ -4276,8 +4273,8 @@ static const device_config_t sb15_config[] = { static const device_config_t sb2_config[] = { { - .name = "base", - .description = "Address", + .name = "base", + .description = "Address", .type = CONFIG_HEX16, .default_string = NULL, .default_int = 0x220, @@ -4324,18 +4321,14 @@ static const device_config_t sb2_config[] = { .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, .file_filter = NULL, .spinner = { 0 }, - .selection = { - { .description = "DMA 1", .value = 1 }, - { .description = "DMA 3", .value = 3 }, - { .description = "" } - }, + .selection = { { 0 } }, .bios = { { 0 } } }, { @@ -4396,7 +4389,7 @@ static const device_config_t sb_mcv_config[] = { .name = "dma", .description = "DMA", .type = CONFIG_SELECTION, - .default_string = "", + .default_string = NULL, .default_int = 1, .file_filter = NULL, .spinner = { 0 }, @@ -4407,6 +4400,17 @@ static const device_config_t sb_mcv_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "opl", .description = "Enable OPL", @@ -4481,6 +4485,17 @@ static const device_config_t sb_pro_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "opl", .description = "Enable OPL", @@ -4507,6 +4522,17 @@ static const device_config_t sb_pro_config[] = { }; static const device_config_t sb_pro_mcv_config[] = { + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "receive_input", .description = "Receive MIDI input", @@ -4604,6 +4630,17 @@ static const device_config_t sb_16_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "opl", .description = "Enable OPL", @@ -4886,6 +4923,17 @@ static const device_config_t sb_awe32_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "opl", .description = "Enable OPL", @@ -5215,6 +5263,17 @@ static const device_config_t ess_688_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "ide_ctrl", .description = "IDE Controller", @@ -5298,6 +5357,17 @@ static const device_config_t ess_1688_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "ide_ctrl", .description = "IDE Controller", @@ -5372,7 +5442,7 @@ static const device_config_t ess_1688_pnp_config[] = { .name = "control_pc_speaker", .description = "Control PC speaker", .type = CONFIG_BINARY, - .default_string = "", + .default_string = NULL, .default_int = 0, .file_filter = NULL, .spinner = { 0 }, @@ -5383,7 +5453,7 @@ static const device_config_t ess_1688_pnp_config[] = { .name = "receive_input", .description = "Receive MIDI input", .type = CONFIG_BINARY, - .default_string = "", + .default_string = NULL, .default_int = 1, .file_filter = NULL, .spinner = { 0 }, @@ -5394,7 +5464,7 @@ static const device_config_t ess_1688_pnp_config[] = { .name = "receive_input401", .description = "Receive MIDI input (MPU-401)", .type = CONFIG_BINARY, - .default_string = "", + .default_string = NULL, .default_int = 0, .file_filter = NULL, .spinner = { 0 }, diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 10e5601f4..76956c417 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -1582,19 +1582,19 @@ sb_exec_command(sb_dsp_t *dsp) timer_set_delay_u64(&dsp->output_timer, (uint64_t) trunc(dsp->sblatcho)); break; case 0x90: /* High speed 8-bit autoinit DMA output */ - if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated + if (dsp->sb_type >= SB_DSP_201) // TODO docs need validated sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); break; case 0x91: /* High speed 8-bit single cycle DMA output */ - if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated + if (dsp->sb_type >= SB_DSP_201) // TODO docs need validated sb_start_dma(dsp, 1, 0, 0, dsp->sb_8_autolen); break; case 0x98: /* High speed 8-bit autoinit DMA input */ - if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated + if (dsp->sb_type >= SB_DSP_201) // TODO docs need validated sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_8_autolen); break; case 0x99: /* High speed 8-bit single cycle DMA input */ - if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated + if (dsp->sb_type >= SB_DSP_201) // TODO docs need validated sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen); break; case 0xA0: /* Set input mode to mono */ diff --git a/src/sound/snd_speaker.c b/src/sound/snd_speaker.c index 0537cd09a..063554875 100644 --- a/src/sound/snd_speaker.c +++ b/src/sound/snd_speaker.c @@ -56,7 +56,7 @@ speaker_update(void) int32_t val; double amplitude; - amplitude = ((speaker_count / 64.0) * 10240.0) - 5120.0; + amplitude = ((speaker_count / 256.0) * 10240.0) - 5120.0; if (amplitude > 5120.0) amplitude = 5120.0; diff --git a/src/sound/snd_ssi2001.c b/src/sound/snd_ssi2001.c index f1620b817..b832cb526 100644 --- a/src/sound/snd_ssi2001.c +++ b/src/sound/snd_ssi2001.c @@ -72,7 +72,7 @@ ssi2001_init(UNUSED(const device_t *info)) { ssi2001_t *ssi2001 = calloc(1, sizeof(ssi2001_t)); - ssi2001->psid = sid_init(0); + ssi2001->psid = sid_init(device_get_config_int("sid_config"),device_get_config_int("sid_adjustment")); sid_reset(ssi2001->psid); uint16_t addr = device_get_config_hex16("base"); ssi2001->gameport_enabled = device_get_config_int("gameport"); @@ -112,7 +112,7 @@ entertainer_init(UNUSED(const device_t *info)) ssi2001_t *ssi2001 = calloc(1, sizeof(ssi2001_t)); entertainer_t *entertainer = calloc(1, sizeof(entertainer_t)); - ssi2001->psid = sid_init(0); + ssi2001->psid = sid_init(0, 0.5); sid_reset(ssi2001->psid); ssi2001->gameport_enabled = device_get_config_int("gameport"); io_sethandler(0x200, 0x0001, entertainer_read, NULL, NULL, entertainer_write, NULL, NULL, entertainer); @@ -157,12 +157,38 @@ static const device_config_t ssi2001_config[] = { .description = "Enable Game port", .type = CONFIG_BINARY, .default_string = NULL, - .default_int = 1, + .default_int = 0, .file_filter = NULL, .spinner = { 0 }, .selection = { { 0 } }, .bios = { { 0 } } }, + { + .name = "sid_config", + .description = "SID Model", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "8580", .value = 0x001 }, + { .description = "6581", .value = 0x000 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "sid_adjustment", + .description = "SID Filter Strength", + .type = CONFIG_STRING, + .default_string = "0.5", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = {{"0.5"}}, + .bios = { { 0 } } + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format off }; @@ -174,7 +200,7 @@ static const device_config_t entertainer_config[] = { .description = "Enable Game port", .type = CONFIG_BINARY, .default_string = NULL, - .default_int = 1, + .default_int = 0, .file_filter = NULL, .spinner = { 0 }, .selection = { { 0 } }, diff --git a/src/sound/sound.c b/src/sound/sound.c index 0c8dffe12..c81dc47b0 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -12,9 +12,11 @@ * * Authors: Sarah Walker, * Miran Grca, + * Jasmine Iwanek, * * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. + * Copyright 2016-2025 Miran Grca. + * Copyright 2024-2025 Jasmine Iwanek. */ #include #include @@ -100,30 +102,50 @@ static const SOUND_CARD sound_cards[] = { // clang-format off { &device_none }, { &device_internal }, - { &acermagic_s20_device }, - { &mirosound_pcm10_device }, - { &adlib_device }, + /* ISA */ { &adgold_device }, - { &azt2316a_device }, - { &azt1605_device }, { &cms_device }, - { &cs4235_device }, - { &cs4236b_device }, { &ess_688_device }, { &ess_ess0100_pnp_device }, { &ess_1688_device }, { &ess_ess0102_pnp_device }, { &ess_ess0968_pnp_device }, - { &gus_device }, + { &ssi2001_device }, + { &mmb_device }, + { &pasplus_device }, + { &voicemasterkey_device }, + { &soundmasterplus_device }, + { &soundman_device }, + { &isadacr0_device }, + { &isadacr1_device }, { &sb_1_device }, { &sb_15_device }, { &sb_2_device }, { &sb_pro_v1_device }, { &sb_pro_v2_device }, + { &entertainer_device }, + { &pssj_isa_device }, + { &tndy_device }, +#ifdef USE_LIBSERIALPORT /*The following devices required LIBSERIALPORT*/ + { &opl2board_device }, +#endif + /* ISA/Sidecar */ + { &adlib_device }, + /* ISA16 */ + { &acermagic_s20_device }, + { &azt2316a_device }, + { &azt1605_device }, + { &sb_goldfinch_device }, + { &cs4235_device }, + { &cs4236b_device }, + { &gus_device }, + { &gus_max_device }, + { &mirosound_pcm10_device }, + { &pas16_device }, + { &pas16d_device }, { &sb_16_device }, { &sb_16_pnp_device }, { &sb_16_pnp_ide_device }, - { &sb_goldfinch_device }, { &sb_32_pnp_device }, { &sb_awe32_device }, { &sb_awe32_pnp_device }, @@ -135,14 +157,8 @@ static const SOUND_CARD sound_cards[] = { { &sb_vibra16cl_device }, { &sb_vibra16s_device }, { &sb_vibra16xv_device }, - { &ssi2001_device }, - { &entertainer_device }, - { &pasplus_device }, - { &pas16_device }, - { &pas16d_device }, - { &pssj_isa_device }, - { &tndy_device }, { &wss_device }, + /* MCA */ { &adlib_mca_device }, { &ess_chipchat_16_mca_device }, { &ncr_business_audio_device }, @@ -151,17 +167,16 @@ static const SOUND_CARD sound_cards[] = { { &sb_16_reply_mca_device }, { &ess_soundpiper_16_mca_device }, { &ess_soundpiper_32_mca_device }, + /* PCI */ { &cmi8338_device }, { &cmi8738_device }, { &es1370_device }, { &es1371_device }, { &es1373_device }, { &ct5880_device }, + /* AC97 */ { &ad1881_device }, { &cs4297a_device }, -#ifdef USE_LIBSERIALPORT /*The following devices required LIBSERIALPORT*/ - { &opl2board_device }, -#endif { NULL } // clang-format on }; diff --git a/src/sound/ymfm/ymfm_opl.h b/src/sound/ymfm/ymfm_opl.h index 843e5b274..71b098e97 100644 --- a/src/sound/ymfm/ymfm_opl.h +++ b/src/sound/ymfm/ymfm_opl.h @@ -52,7 +52,7 @@ namespace ymfm // // System-wide registers: // 01 xxxxxxxx Test register -// --x----- Enable OPL compatibility mode [OPL2 only] (1 = enable) +// --x----- Enable OPL compatibility mode [OPL2 only] (0 = enable) // 02 xxxxxxxx Timer A value (4 * OPN) // 03 xxxxxxxx Timer B value // 04 x------- RST @@ -243,7 +243,7 @@ public: uint32_t op_decay_rate(uint32_t opoffs) const { return byte(0x60, 0, 4, opoffs); } uint32_t op_sustain_level(uint32_t opoffs) const { return byte(0x80, 4, 4, opoffs); } uint32_t op_release_rate(uint32_t opoffs) const { return byte(0x80, 0, 4, opoffs); } - uint32_t op_waveform(uint32_t opoffs) const { return IsOpl2Plus ? byte(0xe0, 0, newflag() ? 3 : 2, opoffs) : 0; } + uint32_t op_waveform(uint32_t opoffs) const { return waveform_enable() ? byte(0xe0, 0, newflag() ? 3 : 2, opoffs) : 0; } protected: // return a bitfield extracted from a byte diff --git a/src/sound/ymfm/ymfm_opn.cpp b/src/sound/ymfm/ymfm_opn.cpp index 16ca3416c..60469e1c0 100644 --- a/src/sound/ymfm/ymfm_opn.cpp +++ b/src/sound/ymfm/ymfm_opn.cpp @@ -155,14 +155,13 @@ bool opn_registers_base::write(uint16_t index, uint8_t data, uint32_t &c // writes to the upper half just latch (only low 6 bits matter) if (bitfield(index, 2)) - m_regdata[latchindex] = data | 0x80; + m_regdata[latchindex] = data & 0x3f; - // writes to the lower half only commit if the latch is there - else if (bitfield(m_regdata[latchindex], 7)) + // writes to the lower half also apply said latch + else { m_regdata[index] = data; - m_regdata[index | 4] = m_regdata[latchindex] & 0x3f; - m_regdata[latchindex] = 0; + m_regdata[index | 4] = m_regdata[latchindex]; } return false; } diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index 91fa25f39..724ab041f 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -32,6 +32,16 @@ set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) target_link_libraries(86Box Threads::Threads) +find_package(SDL2 REQUIRED) +include_directories(${SDL2_INCLUDE_DIRS}) +if(STATIC_BUILD AND TARGET SDL2::SDL2-static) + target_link_libraries(86Box SDL2::SDL2-static) +elseif(TARGET SDL2::SDL2) + target_link_libraries(86Box SDL2::SDL2) +else() + target_link_libraries(86Box ${SDL2_LIBRARIES}) +endif() + add_library(ui OBJECT unix_sdl.c unix_cdrom.c diff --git a/src/unix/dummy_cdrom_ioctl.c b/src/unix/dummy_cdrom_ioctl.c index bddfabb5b..8dffc6758 100644 --- a/src/unix/dummy_cdrom_ioctl.c +++ b/src/unix/dummy_cdrom_ioctl.c @@ -162,6 +162,7 @@ ioctl_is_empty(const void *local) return 1; } +#if 0 static int ioctl_ext_medium_changed(UNUSED(void *local)) { @@ -174,6 +175,7 @@ ioctl_ext_medium_changed(UNUSED(void *local)) return ret; } +#endif static void ioctl_close(void *local) diff --git a/src/unix/gamemode/gamemode_client.h b/src/unix/gamemode/gamemode_client.h new file mode 100644 index 000000000..49c34fb9f --- /dev/null +++ b/src/unix/gamemode/gamemode_client.h @@ -0,0 +1,376 @@ +/* + +Copyright (c) 2017-2025, Feral Interactive and the GameMode contributors +All rights reserved. + +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 Feral Interactive 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. + + */ +#ifndef CLIENT_GAMEMODE_H +#define CLIENT_GAMEMODE_H +/* + * GameMode supports the following client functions + * Requests are refcounted in the daemon + * + * int gamemode_request_start() - Request gamemode starts + * 0 if the request was sent successfully + * -1 if the request failed + * + * int gamemode_request_end() - Request gamemode ends + * 0 if the request was sent successfully + * -1 if the request failed + * + * GAMEMODE_AUTO can be defined to make the above two functions apply during static init and + * destruction, as appropriate. In this configuration, errors will be printed to stderr + * + * int gamemode_query_status() - Query the current status of gamemode + * 0 if gamemode is inactive + * 1 if gamemode is active + * 2 if gamemode is active and this client is registered + * -1 if the query failed + * + * int gamemode_request_start_for(pid_t pid) - Request gamemode starts for another process + * 0 if the request was sent successfully + * -1 if the request failed + * -2 if the request was rejected + * + * int gamemode_request_end_for(pid_t pid) - Request gamemode ends for another process + * 0 if the request was sent successfully + * -1 if the request failed + * -2 if the request was rejected + * + * int gamemode_query_status_for(pid_t pid) - Query status of gamemode for another process + * 0 if gamemode is inactive + * 1 if gamemode is active + * 2 if gamemode is active and this client is registered + * -1 if the query failed + * + * const char* gamemode_error_string() - Get an error string + * returns a string describing any of the above errors + * + * Note: All the above requests can be blocking - dbus requests can and will block while the daemon + * handles the request. It is not recommended to make these calls in performance critical code + */ + +#include +#include + +#include +#include + +#include + +#include + +static char internal_gamemode_client_error_string[512] = { 0 }; + +/** + * Load libgamemode dynamically to dislodge us from most dependencies. + * This allows clients to link and/or use this regardless of runtime. + * See SDL2 for an example of the reasoning behind this in terms of + * dynamic versioning as well. + */ +static volatile int internal_libgamemode_loaded = 1; + +/* Typedefs for the functions to load */ +typedef int (*api_call_return_int)(void); +typedef const char *(*api_call_return_cstring)(void); +typedef int (*api_call_pid_return_int)(pid_t); + +/* Storage for functors */ +static api_call_return_int REAL_internal_gamemode_request_start = NULL; +static api_call_return_int REAL_internal_gamemode_request_end = NULL; +static api_call_return_int REAL_internal_gamemode_query_status = NULL; +static api_call_return_cstring REAL_internal_gamemode_error_string = NULL; +static api_call_pid_return_int REAL_internal_gamemode_request_start_for = NULL; +static api_call_pid_return_int REAL_internal_gamemode_request_end_for = NULL; +static api_call_pid_return_int REAL_internal_gamemode_query_status_for = NULL; + +/** + * Internal helper to perform the symbol binding safely. + * + * Returns 0 on success and -1 on failure + */ +__attribute__((always_inline)) static inline int internal_bind_libgamemode_symbol( + void *handle, const char *name, void **out_func, size_t func_size, bool required) +{ + void *symbol_lookup = NULL; + char *dl_error = NULL; + + /* Safely look up the symbol */ + symbol_lookup = dlsym(handle, name); + dl_error = dlerror(); + if (required && (dl_error || !symbol_lookup)) { + snprintf(internal_gamemode_client_error_string, + sizeof(internal_gamemode_client_error_string), + "dlsym failed - %s", + dl_error); + return -1; + } + + /* Have the symbol correctly, copy it to make it usable */ + memcpy(out_func, &symbol_lookup, func_size); + return 0; +} + +/** + * Loads libgamemode and needed functions + * + * Returns 0 on success and -1 on failure + */ +__attribute__((always_inline)) static inline int internal_load_libgamemode(void) +{ + /* We start at 1, 0 is a success and -1 is a fail */ + if (internal_libgamemode_loaded != 1) { + return internal_libgamemode_loaded; + } + + /* Anonymous struct type to define our bindings */ + struct binding { + const char *name; + void **functor; + size_t func_size; + bool required; + } bindings[] = { + { "real_gamemode_request_start", + (void **)&REAL_internal_gamemode_request_start, + sizeof(REAL_internal_gamemode_request_start), + true }, + { "real_gamemode_request_end", + (void **)&REAL_internal_gamemode_request_end, + sizeof(REAL_internal_gamemode_request_end), + true }, + { "real_gamemode_query_status", + (void **)&REAL_internal_gamemode_query_status, + sizeof(REAL_internal_gamemode_query_status), + false }, + { "real_gamemode_error_string", + (void **)&REAL_internal_gamemode_error_string, + sizeof(REAL_internal_gamemode_error_string), + true }, + { "real_gamemode_request_start_for", + (void **)&REAL_internal_gamemode_request_start_for, + sizeof(REAL_internal_gamemode_request_start_for), + false }, + { "real_gamemode_request_end_for", + (void **)&REAL_internal_gamemode_request_end_for, + sizeof(REAL_internal_gamemode_request_end_for), + false }, + { "real_gamemode_query_status_for", + (void **)&REAL_internal_gamemode_query_status_for, + sizeof(REAL_internal_gamemode_query_status_for), + false }, + }; + + void *libgamemode = NULL; + + /* Try and load libgamemode */ + libgamemode = dlopen("libgamemode.so.0", RTLD_NOW); + if (!libgamemode) { + /* Attempt to load unversioned library for compatibility with older + * versions (as of writing, there are no ABI changes between the two - + * this may need to change if ever ABI-breaking changes are made) */ + libgamemode = dlopen("libgamemode.so", RTLD_NOW); + if (!libgamemode) { + snprintf(internal_gamemode_client_error_string, + sizeof(internal_gamemode_client_error_string), + "dlopen failed - %s", + dlerror()); + internal_libgamemode_loaded = -1; + return -1; + } + } + + /* Attempt to bind all symbols */ + for (size_t i = 0; i < sizeof(bindings) / sizeof(bindings[0]); i++) { + struct binding *binder = &bindings[i]; + + if (internal_bind_libgamemode_symbol(libgamemode, + binder->name, + binder->functor, + binder->func_size, + binder->required)) { + internal_libgamemode_loaded = -1; + return -1; + }; + } + + /* Success */ + internal_libgamemode_loaded = 0; + return 0; +} + +/** + * Redirect to the real libgamemode + */ +__attribute__((always_inline)) static inline const char *gamemode_error_string(void) +{ + /* If we fail to load the system gamemode, or we have an error string already, return our error + * string instead of diverting to the system version */ + if (internal_load_libgamemode() < 0 || internal_gamemode_client_error_string[0] != '\0') { + return internal_gamemode_client_error_string; + } + + /* Assert for static analyser that the function is not NULL */ + assert(REAL_internal_gamemode_error_string != NULL); + + return REAL_internal_gamemode_error_string(); +} + +/** + * Redirect to the real libgamemode + * Allow automatically requesting game mode + * Also prints errors as they happen. + */ +#ifdef GAMEMODE_AUTO +__attribute__((constructor)) +#else +__attribute__((always_inline)) static inline +#endif +int gamemode_request_start(void) +{ + /* Need to load gamemode */ + if (internal_load_libgamemode() < 0) { +#ifdef GAMEMODE_AUTO + fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); +#endif + return -1; + } + + /* Assert for static analyser that the function is not NULL */ + assert(REAL_internal_gamemode_request_start != NULL); + + if (REAL_internal_gamemode_request_start() < 0) { +#ifdef GAMEMODE_AUTO + fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); +#endif + return -1; + } + + return 0; +} + +/* Redirect to the real libgamemode */ +#ifdef GAMEMODE_AUTO +__attribute__((destructor)) +#else +__attribute__((always_inline)) static inline +#endif +int gamemode_request_end(void) +{ + /* Need to load gamemode */ + if (internal_load_libgamemode() < 0) { +#ifdef GAMEMODE_AUTO + fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); +#endif + return -1; + } + + /* Assert for static analyser that the function is not NULL */ + assert(REAL_internal_gamemode_request_end != NULL); + + if (REAL_internal_gamemode_request_end() < 0) { +#ifdef GAMEMODE_AUTO + fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); +#endif + return -1; + } + + return 0; +} + +/* Redirect to the real libgamemode */ +__attribute__((always_inline)) static inline int gamemode_query_status(void) +{ + /* Need to load gamemode */ + if (internal_load_libgamemode() < 0) { + return -1; + } + + if (REAL_internal_gamemode_query_status == NULL) { + snprintf(internal_gamemode_client_error_string, + sizeof(internal_gamemode_client_error_string), + "gamemode_query_status missing (older host?)"); + return -1; + } + + return REAL_internal_gamemode_query_status(); +} + +/* Redirect to the real libgamemode */ +__attribute__((always_inline)) static inline int gamemode_request_start_for(pid_t pid) +{ + /* Need to load gamemode */ + if (internal_load_libgamemode() < 0) { + return -1; + } + + if (REAL_internal_gamemode_request_start_for == NULL) { + snprintf(internal_gamemode_client_error_string, + sizeof(internal_gamemode_client_error_string), + "gamemode_request_start_for missing (older host?)"); + return -1; + } + + return REAL_internal_gamemode_request_start_for(pid); +} + +/* Redirect to the real libgamemode */ +__attribute__((always_inline)) static inline int gamemode_request_end_for(pid_t pid) +{ + /* Need to load gamemode */ + if (internal_load_libgamemode() < 0) { + return -1; + } + + if (REAL_internal_gamemode_request_end_for == NULL) { + snprintf(internal_gamemode_client_error_string, + sizeof(internal_gamemode_client_error_string), + "gamemode_request_end_for missing (older host?)"); + return -1; + } + + return REAL_internal_gamemode_request_end_for(pid); +} + +/* Redirect to the real libgamemode */ +__attribute__((always_inline)) static inline int gamemode_query_status_for(pid_t pid) +{ + /* Need to load gamemode */ + if (internal_load_libgamemode() < 0) { + return -1; + } + + if (REAL_internal_gamemode_query_status_for == NULL) { + snprintf(internal_gamemode_client_error_string, + sizeof(internal_gamemode_client_error_string), + "gamemode_query_status_for missing (older host?)"); + return -1; + } + + return REAL_internal_gamemode_query_status_for(pid); +} + +#endif // CLIENT_GAMEMODE_H diff --git a/src/unix/unix.c b/src/unix/unix.c index bdee9006b..551bde26b 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -64,8 +64,8 @@ int fixed_size_x = 640; int fixed_size_y = 480; extern int title_set; extern wchar_t sdl_win_title[512]; -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -joystick_t joystick_state[GAMEPORT_MAX][MAX_JOYSTICKS]; +plat_joystick_state_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +joystick_state_t joystick_state[GAMEPORT_MAX][MAX_JOYSTICKS]; int joysticks_present; SDL_mutex *blitmtx; SDL_threadID eventthread; @@ -208,22 +208,33 @@ dynld_module(const char *name, dllimp_t *table) return modhandle; } +#define TMPFILE_BUFSIZE 1024 // Assumed max buffer size void plat_tempfile(char *bufp, char *prefix, char *suffix) { struct tm *calendertime; struct timeval t; time_t curtime; + size_t used = 0; if (prefix != NULL) - sprintf(bufp, "%s-", prefix); - else - strcpy(bufp, ""); + used = snprintf(bufp, TMPFILE_BUFSIZE, "%s-", prefix); + else if (TMPFILE_BUFSIZE > 0) + bufp[0] = '\0'; + gettimeofday(&t, NULL); curtime = time(NULL); calendertime = localtime(&curtime); - sprintf(&bufp[strlen(bufp)], "%d%02d%02d-%02d%02d%02d-%03ld%s", calendertime->tm_year, calendertime->tm_mon, calendertime->tm_mday, calendertime->tm_hour, calendertime->tm_min, calendertime->tm_sec, t.tv_usec / 1000, suffix); + + if (used < TMPFILE_BUFSIZE) { + snprintf(bufp + used, TMPFILE_BUFSIZE - used, + "%d%02d%02d-%02d%02d%02d-%03" PRId32 "%s", + calendertime->tm_year, calendertime->tm_mon, calendertime->tm_mday, + calendertime->tm_hour, calendertime->tm_min, calendertime->tm_sec, + (int32_t)(t.tv_usec / 1000), suffix); + } } +#undef TMPFILE_BUFSIZE int plat_getcwd(char *bufp, int max) @@ -565,7 +576,7 @@ main_thread(UNUSED(void *param)) old_time = new_time; if (drawits > 0 && !dopause) { /* Yes, so do one frame now. */ - drawits -= 10; + drawits -= force_10ms ? 10 : 1; if (drawits > 50) drawits = 0; @@ -573,7 +584,7 @@ main_thread(UNUSED(void *param)) pc_run(); /* Every 200 frames we save the machine status. */ - if (++frames >= 200 && nvr_dosave) { + if (++frames >= (force_10ms ? 200 : 2000) && nvr_dosave) { nvr_save(); nvr_dosave = 0; frames = 0; @@ -783,65 +794,83 @@ plat_pause(int p) } } +#define TMP_PATH_BUFSIZE 1024 void 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/", 1023); - - if (!plat_dir_check(xdg_rom_path)) + const char *xdg_data_home = getenv("XDG_DATA_HOME"); + if (xdg_data_home) { + char xdg_rom_path[TMP_PATH_BUFSIZE] = {0}; + size_t used = snprintf(xdg_rom_path, sizeof(xdg_rom_path), "%s/", xdg_data_home); + if (used < sizeof(xdg_rom_path)) + used += snprintf(xdg_rom_path + used, sizeof(xdg_rom_path) - used, "86Box/"); + if (used < sizeof(xdg_rom_path) && !plat_dir_check(xdg_rom_path)) plat_dir_create(xdg_rom_path); - strcat(xdg_rom_path, "roms/"); - - if (!plat_dir_check(xdg_rom_path)) + if (used < sizeof(xdg_rom_path)) + used += snprintf(xdg_rom_path + used, sizeof(xdg_rom_path) - used, "roms/"); + if (used < sizeof(xdg_rom_path) && !plat_dir_check(xdg_rom_path)) plat_dir_create(xdg_rom_path); - rom_add_path(xdg_rom_path); + if (used < sizeof(xdg_rom_path)) + 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)) - plat_dir_create(home_rom_path); - strcat(home_rom_path, "roms/"); - - if (!plat_dir_check(home_rom_path)) - plat_dir_create(home_rom_path); - rom_add_path(home_rom_path); - } - if (getenv("XDG_DATA_DIRS")) { - 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) { - char real_xdg_rom_path[1024] = { '\0' }; - strcat(real_xdg_rom_path, cur_xdg_rom_path); - path_slash(real_xdg_rom_path); - strcat(real_xdg_rom_path, "86Box/roms/"); - rom_add_path(real_xdg_rom_path); - } + const char *home = getenv("HOME"); + if (!home) { + struct passwd *pw = getpwuid(getuid()); + if (pw) + home = pw->pw_dir; + } + + if (home) { + char home_rom_path[TMP_PATH_BUFSIZE] = {0}; + size_t used = snprintf(home_rom_path, sizeof(home_rom_path), + "%s/.local/share/86Box/", home); + if (used < sizeof(home_rom_path) && !plat_dir_check(home_rom_path)) + plat_dir_create(home_rom_path); + if (used < sizeof(home_rom_path)) + used += snprintf(home_rom_path + used, + sizeof(home_rom_path) - used, "roms/"); + if (used < sizeof(home_rom_path) && !plat_dir_check(home_rom_path)) + plat_dir_create(home_rom_path); + if (used < sizeof(home_rom_path)) + rom_add_path(home_rom_path); + } + } + + const char *xdg_data_dirs = getenv("XDG_DATA_DIRS"); + if (xdg_data_dirs) { + char *xdg_rom_paths = strdup(xdg_data_dirs); + if (xdg_rom_paths) { + // Trim trailing colons + size_t len = strlen(xdg_rom_paths); + while (len > 0 && xdg_rom_paths[len - 1] == ':') + xdg_rom_paths[--len] = '\0'; + + char *saveptr = NULL; + char *cur_xdg = strtok_r(xdg_rom_paths, ":", &saveptr); + while (cur_xdg) { + char real_xdg_rom_path[TMP_PATH_BUFSIZE] = {0}; + size_t used = snprintf(real_xdg_rom_path, + sizeof(real_xdg_rom_path), + "%s/86Box/roms/", cur_xdg); + if (used < sizeof(real_xdg_rom_path)) + rom_add_path(real_xdg_rom_path); + cur_xdg = strtok_r(NULL, ":", &saveptr); + } + + free(xdg_rom_paths); } - free(xdg_rom_paths_orig); } else { rom_add_path("/usr/local/share/86Box/roms/"); rom_add_path("/usr/share/86Box/roms/"); } #else - char default_rom_path[1024] = { '\0' }; + char default_rom_path[TMP_PATH_BUFSIZE] = {0}; getDefaultROMPath(default_rom_path); rom_add_path(default_rom_path); #endif } +#undef TMP_PATH_BUFSIZE void plat_get_global_config_dir(char *outbuf, const size_t len) @@ -919,6 +948,11 @@ void (*f_rl_callback_handler_remove)(void) = NULL; # define LIBEDIT_LIBRARY "libedit.so" #endif +void ui_sb_update_icon_wp(int tag, int state) +{ + /* No-op */ +} + uint32_t timer_onesec(uint32_t interval, UNUSED(void *param)) { @@ -972,12 +1006,12 @@ monitor_thread(UNUSED(void *param)) printf( "fddload - Load floppy disk image into drive .\n" "cdload - Load CD-ROM image into drive .\n" - "zipload - Load ZIP image into ZIP drive .\n" + "rdiskload - Load removable disk image into removable disk drive .\n" "cartload - Load cartridge image into cartridge drive .\n" "moload - Load MO image into MO drive .\n\n" "fddeject - eject disk from floppy drive .\n" "cdeject - eject disc from CD-ROM drive .\n" - "zipeject - eject ZIP image from ZIP drive .\n" + "rdiskeject - eject removable disk image from removable disk drive .\n" "carteject - eject cartridge from drive .\n" "moeject - eject image from MO drive .\n\n" "hardreset - hard reset the emulated system.\n" @@ -1082,8 +1116,8 @@ monitor_thread(UNUSED(void *param)) mo_eject(atoi(xargv[1])); } else if (strncasecmp(xargv[0], "carteject", 8) == 0 && cmdargc >= 2) { cartridge_eject(atoi(xargv[1])); - } else if (strncasecmp(xargv[0], "zipeject", 8) == 0 && cmdargc >= 2) { - zip_eject(atoi(xargv[1])); + } else if (strncasecmp(xargv[0], "rdiskeject", 8) == 0 && cmdargc >= 2) { + rdisk_eject(atoi(xargv[1])); } else if (strncasecmp(xargv[0], "fddload", 7) == 0 && cmdargc >= 4) { uint8_t id; uint8_t wp; @@ -1150,7 +1184,7 @@ monitor_thread(UNUSED(void *param)) printf("Inserting tape into cartridge holder %hhu: %s\n", id, fn); cartridge_mount(id, fn, wp); } - } else if (strncasecmp(xargv[0], "zipload", 7) == 0 && cmdargc >= 4) { + } else if (strncasecmp(xargv[0], "rdiskload", 7) == 0 && cmdargc >= 4) { uint8_t id; uint8_t wp; bool err = false; @@ -1169,8 +1203,8 @@ monitor_thread(UNUSED(void *param)) if (fn[strlen(fn) - 1] == '\'' || fn[strlen(fn) - 1] == '"') fn[strlen(fn) - 1] = '\0'; - printf("Inserting disk into ZIP drive %c: %s\n", id + 'A', fn); - zip_mount(id, fn, wp); + printf("Inserting disk into removable disk drive %c: %s\n", id + 'A', fn); + rdisk_mount(id, fn, wp); } } free(line); diff --git a/src/unix/unix_cdrom.c b/src/unix/unix_cdrom.c index b1096b0b4..09aaa5092 100644 --- a/src/unix/unix_cdrom.c +++ b/src/unix/unix_cdrom.c @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * Handle the platform-side of CDROM/ZIP/MO drives. + * Handle the platform-side of CDROM/RDisk/MO drives. * * * @@ -34,7 +34,7 @@ #include <86box/cdrom.h> #include <86box/cdrom_image.h> #include <86box/mo.h> -#include <86box/zip.h> +#include <86box/rdisk.h> #include <86box/scsi_disk.h> #include <86box/plat.h> #include <86box/ui.h> @@ -220,58 +220,58 @@ mo_reload(uint8_t id) } void -zip_eject(uint8_t id) +rdisk_eject(uint8_t id) { - zip_t *dev = (zip_t *) zip_drives[id].priv; + rdisk_t *dev = (rdisk_t *) rdisk_drives[id].priv; - zip_disk_close(dev); - if (zip_drives[id].bus_type) { + rdisk_disk_close(dev); + if (rdisk_drives[id].bus_type) { /* Signal disk change to the emulated machine. */ - zip_insert(dev); + rdisk_insert(dev); } - ui_sb_update_icon_state(SB_ZIP | id, 1); + ui_sb_update_icon_state(SB_RDISK | id, 1); #if 0 - media_menu_update_zip(id); + media_menu_update_rdisk(id); #endif - ui_sb_update_tip(SB_ZIP | id); + ui_sb_update_tip(SB_RDISK | id); config_save(); } void -zip_mount(uint8_t id, char *fn, uint8_t wp) +rdisk_mount(uint8_t id, char *fn, uint8_t wp) { - zip_t *dev = (zip_t *) zip_drives[id].priv; + rdisk_t *dev = (rdisk_t *) rdisk_drives[id].priv; - zip_disk_close(dev); - zip_drives[id].read_only = wp; - zip_load(dev, fn, 0); + rdisk_disk_close(dev); + rdisk_drives[id].read_only = wp; + rdisk_load(dev, fn, 0); - ui_sb_update_icon_state(SB_ZIP | id, strlen(zip_drives[id].image_path) ? 0 : 1); + ui_sb_update_icon_state(SB_RDISK | id, strlen(rdisk_drives[id].image_path) ? 0 : 1); #if 0 - media_menu_update_zip(id); + media_menu_update_rdisk(id); #endif - ui_sb_update_tip(SB_ZIP | id); + ui_sb_update_tip(SB_RDISK | id); config_save(); } void -zip_reload(uint8_t id) +rdisk_reload(uint8_t id) { - zip_t *dev = (zip_t *) zip_drives[id].priv; + rdisk_t *dev = (rdisk_t *) rdisk_drives[id].priv; - zip_disk_reload(dev); - if (strlen(zip_drives[id].image_path) == 0) { - ui_sb_update_icon_state(SB_ZIP | id, 1); + rdisk_disk_reload(dev); + if (strlen(rdisk_drives[id].image_path) == 0) { + ui_sb_update_icon_state(SB_RDISK | id, 1); } else { - ui_sb_update_icon_state(SB_ZIP | id, 0); + ui_sb_update_icon_state(SB_RDISK | id, 0); } #if 0 - media_menu_update_zip(id); + media_menu_update_rdisk(id); #endif - ui_sb_update_tip(SB_ZIP | id); + ui_sb_update_tip(SB_RDISK | id); config_save(); } diff --git a/src/unix/unix_netsocket.c b/src/unix/unix_netsocket.c index d626d025b..850fa3c6c 100644 --- a/src/unix/unix_netsocket.c +++ b/src/unix/unix_netsocket.c @@ -94,6 +94,8 @@ plat_netsocket_accept(SOCKET socket) if (clientsocket == -1) return -1; + fcntl(clientsocket, F_SETFL, fcntl(clientsocket, F_GETFL, 0) | O_NONBLOCK); + return clientsocket; } diff --git a/src/unix/unix_serial_passthrough.c b/src/unix/unix_serial_passthrough.c index 9929f3298..873c706b9 100644 --- a/src/unix/unix_serial_passthrough.c +++ b/src/unix/unix_serial_passthrough.c @@ -13,7 +13,7 @@ * Jasmine Iwanek * * Copyright 2021 Andreas J. Reichel. - * Copyright 2021-2022 Jasmine Iwanek. + * Copyright 2021-2025 Jasmine Iwanek. */ #ifndef __APPLE__ @@ -310,14 +310,12 @@ plat_serpt_open_device(void *priv) switch (dev->mode) { case SERPT_MODE_VCON: - if (!open_pseudo_terminal(dev)) { + if (!open_pseudo_terminal(dev)) return 1; - } break; case SERPT_MODE_HOSTSER: - if (!open_host_serial_port(dev)) { + if (!open_host_serial_port(dev)) return 1; - } break; default: break; diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index 2ffe41f7b..bcbc7aafd 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -18,6 +18,7 @@ add_library(utils OBJECT cJSON.c crc.c + crc32.c fifo.c fifo8.c ini.c diff --git a/src/utils/crc32.c b/src/utils/crc32.c new file mode 100644 index 000000000..2d3ad867a --- /dev/null +++ b/src/utils/crc32.c @@ -0,0 +1,1010 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * This interleaved implementation of a CRC makes use of pipelined multiple + * arithmetic-logic units, commonly found in modern CPU cores. It is due to + * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + + MAKECRCH can be #defined to write out crc32.h. A main() routine is also + produced, so that this one source file can be compiled to an executable. + */ +#include +#include + +#define __USE_LARGEFILE64 +#include + +#if (defined(__HAIKU__) || defined(__unix__) || defined(__APPLE__)) && !defined(__linux__) +# define off64_t off_t +#endif + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + + /* + A CRC of a message is computed on N braids of words in the message, where + each word consists of W bytes (4 or 8). If N is 3, for example, then three + running sparse CRCs are calculated respectively on each braid, at these + indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... + This is done starting at a word boundary, and continues until as many blocks + of N * W bytes as are available have been processed. The results are combined + into a single CRC at the end. For this code, N must be in the range 1..6 and + W must be 4 or 8. The upper limit on N can be increased if desired by adding + more #if blocks, extending the patterns apparent in the code. In addition, + crc32.h would need to be regenerated, if the maximum N value is increased. + + N and W are chosen empirically by benchmarking the execution time on a given + processor. The choices for N and W below were based on testing on Intel Kaby + Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 + Octeon II processors. The Intel, AMD, and ARM processors were all fastest + with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. + They were all tested with either gcc or clang, all using the -O3 optimization + level. Your mileage may vary. + */ + +/* Define N */ +#ifdef Z_TESTN +# define N Z_TESTN +#else +# define N 5 +#endif +#if N < 1 || N > 6 +# error N must be in 1..6 +#endif + +/* + crc_t must be at least 32 bits. word_t must be at least as long as + crc_t. It is assumed here that word_t is either 32 bits or 64 bits, and + that bytes are eight bits. + */ + +/* + Define W and the associated word_t type. If W is not defined, then a + braided calculation is not used, and the associated tables and code are not + compiled. + */ +#ifdef CDROM_TESTW +# if CDROM_TESTW-1 != -1 +# define W CDROM_TESTW +# endif +#else +# ifdef MAKECRCH +# define W 8 /* required for MAKECRCH */ +# else +# if defined(__x86_64__) || defined(__aarch64__) +# define W 8 +# else +# define W 4 +# endif +# endif +#endif +#ifdef W +# if W == 8 + typedef uint64_t word_t; +# else +# undef W +# define W 4 + typedef uint32_t word_t; +# endif +#endif + +/* If available, use the ARM processor CRC32 instruction. */ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 +# define ARMCRC32 +#endif + +#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) +/* + Swap the bytes in a word_t to convert between little and big endian. Any + self-respecting compiler will optimize this to a single machine byte-swap + instruction, if one is available. This assumes that word_t is either 32 bits + or 64 bits. + */ +static word_t byte_swap(word_t word) { +# if W == 8 + return + (word & 0xff00000000000000) >> 56 | + (word & 0xff000000000000) >> 40 | + (word & 0xff0000000000) >> 24 | + (word & 0xff00000000) >> 8 | + (word & 0xff000000) << 8 | + (word & 0xff0000) << 24 | + (word & 0xff00) << 40 | + (word & 0xff) << 56; +# else /* W == 4 */ + return + (word & 0xff000000) >> 24 | + (word & 0xff0000) >> 8 | + (word & 0xff00) << 8 | + (word & 0xff) << 24; +# endif +} +#endif + +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Table of powers of x for combining CRC-32s, filled in by make_crc_table() + * below. + */ + static crc_t x2n_table[32]; +#else +/* ========================================================================= + * Tables for byte-wise and braided CRC-32 calculations, and a table of powers + * of x for combining CRC-32s, all made by make_crc_table(). + */ +# include "crc32.h" +#endif + +/* CRC polynomial. */ +// #define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ +#define POLY 0xd8018001 /* p(x) reflected, with x^32 implied */ + +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Build the tables for byte-wise and braided CRC-32 calculations, and a table + * of powers of x for combining CRC-32s. + */ +static crc_t crc_table[256]; +#ifdef W + static word_t crc_big_table[256]; + static crc_t crc_braid_table[W][256]; + static word_t crc_braid_big_table[W][256]; + static void braid(crc_t [][256], word_t [][256], int, int); +#endif +#ifdef MAKECRCH + static void write_table(FILE *, const crc_t *, int); + static void write_table32hi(FILE *, const word_t *, int); + static void write_table64(FILE *, const word_t *, int); +#endif /* MAKECRCH */ + +/* + Define a once() function depending on the availability of atomics. If this is + compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in + multiple threads, and if atomics are not available, then get_crc_table() must + be called to initialize the tables and must return before any threads are + allowed to compute or combine CRCs. + */ + +/* Definition of once functionality. */ +typedef struct once_s once_t; + +/* Check for the availability of atomics. */ +#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ + !defined(__STDC_NO_ATOMICS__) + +#include + +/* Structure for once(), which must be initialized with ONCE_INIT. */ +struct once_s { + atomic_flag begun; + atomic_int done; +}; +#define ONCE_INIT {ATOMIC_FLAG_INIT, 0} + +/* + Run the provided init() function exactly once, even if multiple threads + invoke once() at the same time. The state must be a once_t initialized with + ONCE_INIT. + */ +static void once(once_t *state, void (*init)(void)) { + if (!atomic_load(&state->done)) { + if (atomic_flag_test_and_set(&state->begun)) + while (!atomic_load(&state->done)) + ; + else { + init(); + atomic_store(&state->done, 1); + } + } +} + +#else /* no atomics */ + +/* Structure for once(), which must be initialized with ONCE_INIT. */ +struct once_s { + volatile int begun; + volatile int done; +}; +#define ONCE_INIT {0, 0} + +/* Test and set. Alas, not atomic, but tries to minimize the period of + vulnerability. */ +static int test_and_set(int volatile *flag) { + int was; + + was = *flag; + *flag = 1; + return was; +} + +/* Run the provided init() function once. This is not thread-safe. */ +static void once(once_t *state, void (*init)(void)) { + if (!state->done) { + if (test_and_set(&state->begun)) + while (!state->done) + ; + else { + init(); + state->done = 1; + } + } +} + +#endif + +/* State for once(). */ +static once_t made = ONCE_INIT; + +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x + (which is shifting right by one and adding x^32 mod p if the bit shifted out + is a one). We start with the highest power (least significant bit) of q and + repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all the + information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. + */ + +static void make_crc_table(void) { + unsigned i, j, n; + crc_t p; + + /* initialize the CRC of bytes tables */ + for (i = 0; i < 256; i++) { + p = i; + for (j = 0; j < 8; j++) + p = p & 1 ? (p >> 1) ^ POLY : p >> 1; + crc_table[i] = p; +#ifdef W + crc_big_table[i] = byte_swap(p); +#endif + } + + /* initialize the x^2^n mod p(x) table */ + p = (crc_t) 1 << 30; /* x^1 */ + x2n_table[0] = p; + for (n = 1; n < 32; n++) + x2n_table[n] = p = multmodp(p, p); + +#ifdef W + /* initialize the braiding tables -- needs x2n_table[] */ + braid(crc_braid_table, crc_braid_big_table, N, W); +#endif + +#ifdef MAKECRCH + { + /* + The crc32.h header file contains tables for both 32-bit and 64-bit + word_t's, and so requires a 64-bit type be available. In that + case, word_t must be defined to be 64-bits. This code then also + generates and writes out the tables for the case that word_t is + 32 bits. + */ +#if !defined(W) || W != 8 +# error Need a 64-bit integer type in order to generate crc32.h. +#endif + FILE *out; + int k, n; + crc_t ltl[8][256]; + word_t big[8][256]; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + + /* write out little-endian CRC table to crc32.h */ + fprintf(out, + "/* crc32.h -- tables for rapid CRC calculation\n" + " * Generated automatically by crc32.c\n */\n" + "\n" + "static const crc_t crc_table[] = {\n" + " "); + write_table(out, crc_table, 256); + fprintf(out, + "};\n"); + + /* write out big-endian CRC table for 64-bit word_t to crc32.h */ + fprintf(out, + "\n" + "#ifdef W\n" + "\n" + "#if W == 8\n" + "\n" + "static const word_t crc_big_table[] = {\n" + " "); + write_table64(out, crc_big_table, 256); + fprintf(out, + "};\n"); + + /* write out big-endian CRC table for 32-bit word_t to crc32.h */ + fprintf(out, + "\n" + "#else /* W == 4 */\n" + "\n" + "static const word_t crc_big_table[] = {\n" + " "); + write_table32hi(out, crc_big_table, 256); + fprintf(out, + "};\n" + "\n" + "#endif\n"); + + /* write out braid tables for each value of N */ + for (n = 1; n <= 6; n++) { + fprintf(out, + "\n" + "#if N == %d\n", n); + + /* compute braid tables for this N and 64-bit word_t */ + braid(ltl, big, n, 8); + + /* write out braid tables for 64-bit word_t to crc32.h */ + fprintf(out, + "\n" + "#if W == 8\n" + "\n" + "static const crc_t crc_braid_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + fprintf(out, " {"); + write_table(out, ltl[k], 256); + fprintf(out, "}%s", k < 7 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "static const word_t crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + fprintf(out, " {"); + write_table64(out, big[k], 256); + fprintf(out, "}%s", k < 7 ? ",\n" : ""); + } + fprintf(out, + "};\n"); + + /* compute braid tables for this N and 32-bit word_t */ + braid(ltl, big, n, 4); + + /* write out braid tables for 32-bit word_t to crc32.h */ + fprintf(out, + "\n" + "#else /* W == 4 */\n" + "\n" + "static const crc_t crc_braid_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + fprintf(out, " {"); + write_table(out, ltl[k], 256); + fprintf(out, "}%s", k < 3 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "static const word_t crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + fprintf(out, " {"); + write_table32hi(out, big[k], 256); + fprintf(out, "}%s", k < 3 ? ",\n" : ""); + } + fprintf(out, + "};\n" + "\n" + "#endif\n" + "\n" + "#endif\n"); + } + fprintf(out, + "\n" + "#endif\n"); + + /* write out zeros operator table to crc32.h */ + fprintf(out, + "\n" + "static const crc_t x2n_table[] = {\n" + " "); + write_table(out, x2n_table, 32); + fprintf(out, + "};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH + +/* + Write the 32-bit values in table[0..k-1] to out, five per line in + hexadecimal separated by commas. + */ +static void write_table(FILE *out, const crc_t *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", + (unsigned long)(table[n]), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the high 32-bits of each value in table[0..k-1] to out, five per line + in hexadecimal separated by commas. + */ +static void write_table32hi(FILE *out, const word_t *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", + (unsigned long)(table[n] >> 32), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the 64-bit values in table[0..k-1] to out, three per line in + hexadecimal separated by commas. This assumes that if there is a 64-bit + type, then there is also a long long integer type, and it is at least 64 + bits. If not, then the type cast and format string can be adjusted + accordingly. + */ +static void write_table64(FILE *out, const word_t *table, int k) { + int n; + + for (n = 0; n < k; n++) + fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : " ", + (unsigned long long)(table[n]), + n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); +} + +/* Actually do the deed. */ +int main(void) { + make_crc_table(); + return 0; +} + +#endif /* MAKECRCH */ + +#ifdef W +/* + Generate the little and big-endian braid tables for the given n and word_t + size w. Each array must have room for w blocks of 256 elements. + */ +static void braid(crc_t ltl[][256], word_t big[][256], int n, int w) { + int k; + crc_t i, p, q; + for (k = 0; k < w; k++) { + p = x2nmodp((n * w + 3 - k) << 3, 0); + ltl[k][0] = 0; + big[w - 1 - k][0] = 0; + for (i = 1; i < 256; i++) { + ltl[k][i] = q = multmodp(i << 24, p); + big[w - 1 - k][i] = byte_swap(q); + } + } +} +#endif + +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * Use ARM machine instructions if available. This will compute the CRC about + * ten times faster than the braided calculation. This code does not check for + * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will + * only be defined if the compilation specifies an ARM processor architecture + * that has the instructions. For example, compiling with -march=armv8.1-a or + * -march=armv8-a+crc, or -march=native if the compile machine has the crc32 + * instructions. + */ +#ifdef ARMCRC32 + +/* + Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, + reflected. For speed, this requires that a not be zero. + */ +static crc_t multmodp(crc_t a, crc_t b) { + crc_t m, p; + + m = (crc_t)1 << 31; + p = 0; + for (;;) { + if (a & m) { + p ^= b; + if ((a & (m - 1)) == 0) + break; + } + m >>= 1; + b = b & 1 ? (b >> 1) ^ POLY : b >> 1; + } + return p; +} + +/* + Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been + initialized. + */ +static crc_t x2nmodp(off64_t n, unsigned k) { + crc_t p; + + p = (crc_t)1 << 31; /* x^0 == 1 */ + while (n) { + if (n & 1) + p = multmodp(x2n_table[k & 31], p); + n >>= 1; + k++; + } + return p; +} + +/* + Constants empirically determined to maximize speed. These values are from + measurements on a Cortex-A57. Your mileage may vary. + */ +#define Z_BATCH 3990 /* number of words in a batch */ +#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ +#define Z_BATCH_MIN 800 /* fewest words in a final batch */ + +uint32_t cdrom_crc32(unsigned long crc, const unsigned char *buf, + size_t len) { + crc_t val; + word_t crc1, crc2; + const word_t *word; + word_t val0, val1, val2; + size_t last, last2, i; + size_t num; + + /* Return initial CRC, if requested. */ + if (buf == NULL) + return 0; + +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + + /* Pre-condition the CRC */ + crc = (~crc) & 0xffffffff; + + /* Compute the CRC up to a word boundary. */ + while (len && ((size_t) buf & 7) != 0) { + len--; + val = *buf++; + __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); + } + + /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */ + word = (word_t const *)buf; + num = len >> 3; + len &= 7; + + /* Do three interleaved CRCs to realize the throughput of one crc32x + instruction per cycle. Each CRC is calculated on Z_BATCH words. The + three CRCs are combined into a single CRC after each set of batches. */ + while (num >= 3 * Z_BATCH) { + crc1 = 0; + crc2 = 0; + for (i = 0; i < Z_BATCH; i++) { + val0 = word[i]; + val1 = word[i + Z_BATCH]; + val2 = word[i + 2 * Z_BATCH]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); + } + word += 3 * Z_BATCH; + num -= 3 * Z_BATCH; + crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1; + crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2; + } + + /* Do one last smaller batch with the remaining words, if there are enough + to pay for the combination of CRCs. */ + last = num / 3; + if (last >= Z_BATCH_MIN) { + last2 = last << 1; + crc1 = 0; + crc2 = 0; + for (i = 0; i < last; i++) { + val0 = word[i]; + val1 = word[i + last]; + val2 = word[i + last2]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); + } + word += 3 * last; + num -= 3 * last; + val = x2nmodp(last, 6); + crc = multmodp(val, crc) ^ crc1; + crc = multmodp(val, crc) ^ crc2; + } + + /* Compute the CRC on any remaining words. */ + for (i = 0; i < num; i++) { + val0 = word[i]; + __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); + } + word += num; + + /* Complete the CRC on any remaining bytes. */ + buf = (const unsigned char *) word; + while (len) { + len--; + val = *buf++; + __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); + } + + /* Return the CRC, post-conditioned. */ + return crc ^ 0xffffffff; +} + +#else + +#ifdef W + +/* + Return the CRC of the W bytes in the word_t data, taking the + least-significant byte of the word as the first byte of data, without any pre + or post conditioning. This is used to combine the CRCs of each braid. + */ +static crc_t crc_word(word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data >> 8) ^ crc_table[data & 0xff]; + return (crc_t) data; +} + +static word_t crc_word_big(word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data << 8) ^ + crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; + return data; +} + +#endif + +/* ========================================================================= */ +unsigned long cdrom_crc32(unsigned long crc, const unsigned char *buf, + size_t len) { + /* Return initial CRC, if requested. */ + if (buf == NULL) + return 0; + +#ifdef DYNAMIC_CRC_TABLE + once(&made, make_crc_table); +#endif /* DYNAMIC_CRC_TABLE */ + + /* Pre-condition the CRC */ + crc = (~crc) & 0xffffffff; + +#ifdef W + + /* If provided enough bytes, do a braided CRC calculation. */ + if (len >= N * W + W - 1) { + size_t blks; + word_t const *words; + unsigned endian; + int k; + + /* Compute the CRC up to a word_t boundary. */ + while (len && ((size_t) buf & (W - 1)) != 0) { + len--; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + } + + /* Compute the CRC on as many N word_t blocks as are available. */ + blks = len / (N * W); + len -= blks * N * W; + words = (word_t const *)buf; + + /* Do endian check at execution time instead of compile time, since ARM + processors can change the endianness at execution time. If the + compiler knows what the endianness will be, it can optimize out the + check and the unused branch. */ + endian = 1; + if (*(unsigned char *)&endian) { + /* Little endian. */ + + crc_t crc0; + word_t word0; +#if N > 1 + crc_t crc1; + word_t word1; +#if N > 2 + crc_t crc2; + word_t word2; +#if N > 3 + crc_t crc3; + word_t word3; +#if N > 4 + crc_t crc4; + word_t word4; +#if N > 5 + crc_t crc5; + word_t word5; +#endif +#endif +#endif +#endif +#endif + + /* Initialize the CRC for each braid. */ + crc0 = crc; +#if N > 1 + crc1 = 0; +#if N > 2 + crc2 = 0; +#if N > 3 + crc3 = 0; +#if N > 4 + crc4 = 0; +#if N > 5 + crc5 = 0; +#endif +#endif +#endif +#endif +#endif + + /* + Process the first blks-1 blocks, computing the CRCs on each braid + independently. + */ + while (--blks) { + /* Load the word for each braid into registers. */ + word0 = crc0 ^ words[0]; +#if N > 1 + word1 = crc1 ^ words[1]; +#if N > 2 + word2 = crc2 ^ words[2]; +#if N > 3 + word3 = crc3 ^ words[3]; +#if N > 4 + word4 = crc4 ^ words[4]; +#if N > 5 + word5 = crc5 ^ words[5]; +#endif +#endif +#endif +#endif +#endif + words += N; + + /* Compute and update the CRC for each word. The loop should + get unrolled. */ + crc0 = crc_braid_table[0][word0 & 0xff]; +#if N > 1 + crc1 = crc_braid_table[0][word1 & 0xff]; +#if N > 2 + crc2 = crc_braid_table[0][word2 & 0xff]; +#if N > 3 + crc3 = crc_braid_table[0][word3 & 0xff]; +#if N > 4 + crc4 = crc_braid_table[0][word4 & 0xff]; +#if N > 5 + crc5 = crc_braid_table[0][word5 & 0xff]; +#endif +#endif +#endif +#endif +#endif + for (k = 1; k < W; k++) { + crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff]; +#if N > 1 + crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff]; +#if N > 2 + crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff]; +#if N > 3 + crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff]; +#if N > 4 + crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff]; +#if N > 5 + crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff]; +#endif +#endif +#endif +#endif +#endif + } + } + + /* + Process the last block, combining the CRCs of the N braids at the + same time. + */ + crc = crc_word(crc0 ^ words[0]); +#if N > 1 + crc = crc_word(crc1 ^ words[1] ^ crc); +#if N > 2 + crc = crc_word(crc2 ^ words[2] ^ crc); +#if N > 3 + crc = crc_word(crc3 ^ words[3] ^ crc); +#if N > 4 + crc = crc_word(crc4 ^ words[4] ^ crc); +#if N > 5 + crc = crc_word(crc5 ^ words[5] ^ crc); +#endif +#endif +#endif +#endif +#endif + words += N; + } + else { + /* Big endian. */ + + word_t crc0, word0, comb; +#if N > 1 + word_t crc1, word1; +#if N > 2 + word_t crc2, word2; +#if N > 3 + word_t crc3, word3; +#if N > 4 + word_t crc4, word4; +#if N > 5 + word_t crc5, word5; +#endif +#endif +#endif +#endif +#endif + + /* Initialize the CRC for each braid. */ + crc0 = byte_swap(crc); +#if N > 1 + crc1 = 0; +#if N > 2 + crc2 = 0; +#if N > 3 + crc3 = 0; +#if N > 4 + crc4 = 0; +#if N > 5 + crc5 = 0; +#endif +#endif +#endif +#endif +#endif + + /* + Process the first blks-1 blocks, computing the CRCs on each braid + independently. + */ + while (--blks) { + /* Load the word for each braid into registers. */ + word0 = crc0 ^ words[0]; +#if N > 1 + word1 = crc1 ^ words[1]; +#if N > 2 + word2 = crc2 ^ words[2]; +#if N > 3 + word3 = crc3 ^ words[3]; +#if N > 4 + word4 = crc4 ^ words[4]; +#if N > 5 + word5 = crc5 ^ words[5]; +#endif +#endif +#endif +#endif +#endif + words += N; + + /* Compute and update the CRC for each word. The loop should + get unrolled. */ + crc0 = crc_braid_big_table[0][word0 & 0xff]; +#if N > 1 + crc1 = crc_braid_big_table[0][word1 & 0xff]; +#if N > 2 + crc2 = crc_braid_big_table[0][word2 & 0xff]; +#if N > 3 + crc3 = crc_braid_big_table[0][word3 & 0xff]; +#if N > 4 + crc4 = crc_braid_big_table[0][word4 & 0xff]; +#if N > 5 + crc5 = crc_braid_big_table[0][word5 & 0xff]; +#endif +#endif +#endif +#endif +#endif + for (k = 1; k < W; k++) { + crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff]; +#if N > 1 + crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff]; +#if N > 2 + crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff]; +#if N > 3 + crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff]; +#if N > 4 + crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff]; +#if N > 5 + crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff]; +#endif +#endif +#endif +#endif +#endif + } + } + + /* + Process the last block, combining the CRCs of the N braids at the + same time. + */ + comb = crc_word_big(crc0 ^ words[0]); +#if N > 1 + comb = crc_word_big(crc1 ^ words[1] ^ comb); +#if N > 2 + comb = crc_word_big(crc2 ^ words[2] ^ comb); +#if N > 3 + comb = crc_word_big(crc3 ^ words[3] ^ comb); +#if N > 4 + comb = crc_word_big(crc4 ^ words[4] ^ comb); +#if N > 5 + comb = crc_word_big(crc5 ^ words[5] ^ comb); +#endif +#endif +#endif +#endif +#endif + words += N; + crc = byte_swap(comb); + } + + /* + Update the pointer to the remaining bytes to process. + */ + buf = (unsigned char const *)words; + } + +#endif /* W */ + + /* Complete the computation of the CRC on any remaining bytes. */ + while (len >= 8) { + len -= 8; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + } + while (len) { + len--; + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + } + + /* Return the CRC, post-conditioned. */ + return crc ^ 0xffffffff; +} + +#endif diff --git a/src/utils/crc32.h b/src/utils/crc32.h new file mode 100644 index 000000000..d4bf86c5a --- /dev/null +++ b/src/utils/crc32.h @@ -0,0 +1,9448 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +typedef uint32_t crc_t; + +static const crc_t crc_table[] = { + 0x00000000, 0x90910101, 0x91210201, 0x01b00300, 0x92410401, + 0x02d00500, 0x03600600, 0x93f10701, 0x94810801, 0x04100900, + 0x05a00a00, 0x95310b01, 0x06c00c00, 0x96510d01, 0x97e10e01, + 0x07700f00, 0x99011001, 0x09901100, 0x08201200, 0x98b11301, + 0x0b401400, 0x9bd11501, 0x9a611601, 0x0af01700, 0x0d801800, + 0x9d111901, 0x9ca11a01, 0x0c301b00, 0x9fc11c01, 0x0f501d00, + 0x0ee01e00, 0x9e711f01, 0x82012001, 0x12902100, 0x13202200, + 0x83b12301, 0x10402400, 0x80d12501, 0x81612601, 0x11f02700, + 0x16802800, 0x86112901, 0x87a12a01, 0x17302b00, 0x84c12c01, + 0x14502d00, 0x15e02e00, 0x85712f01, 0x1b003000, 0x8b913101, + 0x8a213201, 0x1ab03300, 0x89413401, 0x19d03500, 0x18603600, + 0x88f13701, 0x8f813801, 0x1f103900, 0x1ea03a00, 0x8e313b01, + 0x1dc03c00, 0x8d513d01, 0x8ce13e01, 0x1c703f00, 0xb4014001, + 0x24904100, 0x25204200, 0xb5b14301, 0x26404400, 0xb6d14501, + 0xb7614601, 0x27f04700, 0x20804800, 0xb0114901, 0xb1a14a01, + 0x21304b00, 0xb2c14c01, 0x22504d00, 0x23e04e00, 0xb3714f01, + 0x2d005000, 0xbd915101, 0xbc215201, 0x2cb05300, 0xbf415401, + 0x2fd05500, 0x2e605600, 0xbef15701, 0xb9815801, 0x29105900, + 0x28a05a00, 0xb8315b01, 0x2bc05c00, 0xbb515d01, 0xbae15e01, + 0x2a705f00, 0x36006000, 0xa6916101, 0xa7216201, 0x37b06300, + 0xa4416401, 0x34d06500, 0x35606600, 0xa5f16701, 0xa2816801, + 0x32106900, 0x33a06a00, 0xa3316b01, 0x30c06c00, 0xa0516d01, + 0xa1e16e01, 0x31706f00, 0xaf017001, 0x3f907100, 0x3e207200, + 0xaeb17301, 0x3d407400, 0xadd17501, 0xac617601, 0x3cf07700, + 0x3b807800, 0xab117901, 0xaaa17a01, 0x3a307b00, 0xa9c17c01, + 0x39507d00, 0x38e07e00, 0xa8717f01, 0xd8018001, 0x48908100, + 0x49208200, 0xd9b18301, 0x4a408400, 0xdad18501, 0xdb618601, + 0x4bf08700, 0x4c808800, 0xdc118901, 0xdda18a01, 0x4d308b00, + 0xdec18c01, 0x4e508d00, 0x4fe08e00, 0xdf718f01, 0x41009000, + 0xd1919101, 0xd0219201, 0x40b09300, 0xd3419401, 0x43d09500, + 0x42609600, 0xd2f19701, 0xd5819801, 0x45109900, 0x44a09a00, + 0xd4319b01, 0x47c09c00, 0xd7519d01, 0xd6e19e01, 0x46709f00, + 0x5a00a000, 0xca91a101, 0xcb21a201, 0x5bb0a300, 0xc841a401, + 0x58d0a500, 0x5960a600, 0xc9f1a701, 0xce81a801, 0x5e10a900, + 0x5fa0aa00, 0xcf31ab01, 0x5cc0ac00, 0xcc51ad01, 0xcde1ae01, + 0x5d70af00, 0xc301b001, 0x5390b100, 0x5220b200, 0xc2b1b301, + 0x5140b400, 0xc1d1b501, 0xc061b601, 0x50f0b700, 0x5780b800, + 0xc711b901, 0xc6a1ba01, 0x5630bb00, 0xc5c1bc01, 0x5550bd00, + 0x54e0be00, 0xc471bf01, 0x6c00c000, 0xfc91c101, 0xfd21c201, + 0x6db0c300, 0xfe41c401, 0x6ed0c500, 0x6f60c600, 0xfff1c701, + 0xf881c801, 0x6810c900, 0x69a0ca00, 0xf931cb01, 0x6ac0cc00, + 0xfa51cd01, 0xfbe1ce01, 0x6b70cf00, 0xf501d001, 0x6590d100, + 0x6420d200, 0xf4b1d301, 0x6740d400, 0xf7d1d501, 0xf661d601, + 0x66f0d700, 0x6180d800, 0xf111d901, 0xf0a1da01, 0x6030db00, + 0xf3c1dc01, 0x6350dd00, 0x62e0de00, 0xf271df01, 0xee01e001, + 0x7e90e100, 0x7f20e200, 0xefb1e301, 0x7c40e400, 0xecd1e501, + 0xed61e601, 0x7df0e700, 0x7a80e800, 0xea11e901, 0xeba1ea01, + 0x7b30eb00, 0xe8c1ec01, 0x7850ed00, 0x79e0ee00, 0xe971ef01, + 0x7700f000, 0xe791f101, 0xe621f201, 0x76b0f300, 0xe541f401, + 0x75d0f500, 0x7460f600, 0xe4f1f701, 0xe381f801, 0x7310f900, + 0x72a0fa00, 0xe231fb01, 0x71c0fc00, 0xe151fd01, 0xe0e1fe01, + 0x7070ff00}; + +#ifdef W + +#if W == 8 + +static const word_t crc_big_table[] = { + 0x0000000000000000, 0x0101919000000000, 0x0102219100000000, + 0x0003b00100000000, 0x0104419200000000, 0x0005d00200000000, + 0x0006600300000000, 0x0107f19300000000, 0x0108819400000000, + 0x0009100400000000, 0x000aa00500000000, 0x010b319500000000, + 0x000cc00600000000, 0x010d519600000000, 0x010ee19700000000, + 0x000f700700000000, 0x0110019900000000, 0x0011900900000000, + 0x0012200800000000, 0x0113b19800000000, 0x0014400b00000000, + 0x0115d19b00000000, 0x0116619a00000000, 0x0017f00a00000000, + 0x0018800d00000000, 0x0119119d00000000, 0x011aa19c00000000, + 0x001b300c00000000, 0x011cc19f00000000, 0x001d500f00000000, + 0x001ee00e00000000, 0x011f719e00000000, 0x0120018200000000, + 0x0021901200000000, 0x0022201300000000, 0x0123b18300000000, + 0x0024401000000000, 0x0125d18000000000, 0x0126618100000000, + 0x0027f01100000000, 0x0028801600000000, 0x0129118600000000, + 0x012aa18700000000, 0x002b301700000000, 0x012cc18400000000, + 0x002d501400000000, 0x002ee01500000000, 0x012f718500000000, + 0x0030001b00000000, 0x0131918b00000000, 0x0132218a00000000, + 0x0033b01a00000000, 0x0134418900000000, 0x0035d01900000000, + 0x0036601800000000, 0x0137f18800000000, 0x0138818f00000000, + 0x0039101f00000000, 0x003aa01e00000000, 0x013b318e00000000, + 0x003cc01d00000000, 0x013d518d00000000, 0x013ee18c00000000, + 0x003f701c00000000, 0x014001b400000000, 0x0041902400000000, + 0x0042202500000000, 0x0143b1b500000000, 0x0044402600000000, + 0x0145d1b600000000, 0x014661b700000000, 0x0047f02700000000, + 0x0048802000000000, 0x014911b000000000, 0x014aa1b100000000, + 0x004b302100000000, 0x014cc1b200000000, 0x004d502200000000, + 0x004ee02300000000, 0x014f71b300000000, 0x0050002d00000000, + 0x015191bd00000000, 0x015221bc00000000, 0x0053b02c00000000, + 0x015441bf00000000, 0x0055d02f00000000, 0x0056602e00000000, + 0x0157f1be00000000, 0x015881b900000000, 0x0059102900000000, + 0x005aa02800000000, 0x015b31b800000000, 0x005cc02b00000000, + 0x015d51bb00000000, 0x015ee1ba00000000, 0x005f702a00000000, + 0x0060003600000000, 0x016191a600000000, 0x016221a700000000, + 0x0063b03700000000, 0x016441a400000000, 0x0065d03400000000, + 0x0066603500000000, 0x0167f1a500000000, 0x016881a200000000, + 0x0069103200000000, 0x006aa03300000000, 0x016b31a300000000, + 0x006cc03000000000, 0x016d51a000000000, 0x016ee1a100000000, + 0x006f703100000000, 0x017001af00000000, 0x0071903f00000000, + 0x0072203e00000000, 0x0173b1ae00000000, 0x0074403d00000000, + 0x0175d1ad00000000, 0x017661ac00000000, 0x0077f03c00000000, + 0x0078803b00000000, 0x017911ab00000000, 0x017aa1aa00000000, + 0x007b303a00000000, 0x017cc1a900000000, 0x007d503900000000, + 0x007ee03800000000, 0x017f71a800000000, 0x018001d800000000, + 0x0081904800000000, 0x0082204900000000, 0x0183b1d900000000, + 0x0084404a00000000, 0x0185d1da00000000, 0x018661db00000000, + 0x0087f04b00000000, 0x0088804c00000000, 0x018911dc00000000, + 0x018aa1dd00000000, 0x008b304d00000000, 0x018cc1de00000000, + 0x008d504e00000000, 0x008ee04f00000000, 0x018f71df00000000, + 0x0090004100000000, 0x019191d100000000, 0x019221d000000000, + 0x0093b04000000000, 0x019441d300000000, 0x0095d04300000000, + 0x0096604200000000, 0x0197f1d200000000, 0x019881d500000000, + 0x0099104500000000, 0x009aa04400000000, 0x019b31d400000000, + 0x009cc04700000000, 0x019d51d700000000, 0x019ee1d600000000, + 0x009f704600000000, 0x00a0005a00000000, 0x01a191ca00000000, + 0x01a221cb00000000, 0x00a3b05b00000000, 0x01a441c800000000, + 0x00a5d05800000000, 0x00a6605900000000, 0x01a7f1c900000000, + 0x01a881ce00000000, 0x00a9105e00000000, 0x00aaa05f00000000, + 0x01ab31cf00000000, 0x00acc05c00000000, 0x01ad51cc00000000, + 0x01aee1cd00000000, 0x00af705d00000000, 0x01b001c300000000, + 0x00b1905300000000, 0x00b2205200000000, 0x01b3b1c200000000, + 0x00b4405100000000, 0x01b5d1c100000000, 0x01b661c000000000, + 0x00b7f05000000000, 0x00b8805700000000, 0x01b911c700000000, + 0x01baa1c600000000, 0x00bb305600000000, 0x01bcc1c500000000, + 0x00bd505500000000, 0x00bee05400000000, 0x01bf71c400000000, + 0x00c0006c00000000, 0x01c191fc00000000, 0x01c221fd00000000, + 0x00c3b06d00000000, 0x01c441fe00000000, 0x00c5d06e00000000, + 0x00c6606f00000000, 0x01c7f1ff00000000, 0x01c881f800000000, + 0x00c9106800000000, 0x00caa06900000000, 0x01cb31f900000000, + 0x00ccc06a00000000, 0x01cd51fa00000000, 0x01cee1fb00000000, + 0x00cf706b00000000, 0x01d001f500000000, 0x00d1906500000000, + 0x00d2206400000000, 0x01d3b1f400000000, 0x00d4406700000000, + 0x01d5d1f700000000, 0x01d661f600000000, 0x00d7f06600000000, + 0x00d8806100000000, 0x01d911f100000000, 0x01daa1f000000000, + 0x00db306000000000, 0x01dcc1f300000000, 0x00dd506300000000, + 0x00dee06200000000, 0x01df71f200000000, 0x01e001ee00000000, + 0x00e1907e00000000, 0x00e2207f00000000, 0x01e3b1ef00000000, + 0x00e4407c00000000, 0x01e5d1ec00000000, 0x01e661ed00000000, + 0x00e7f07d00000000, 0x00e8807a00000000, 0x01e911ea00000000, + 0x01eaa1eb00000000, 0x00eb307b00000000, 0x01ecc1e800000000, + 0x00ed507800000000, 0x00eee07900000000, 0x01ef71e900000000, + 0x00f0007700000000, 0x01f191e700000000, 0x01f221e600000000, + 0x00f3b07600000000, 0x01f441e500000000, 0x00f5d07500000000, + 0x00f6607400000000, 0x01f7f1e400000000, 0x01f881e300000000, + 0x00f9107300000000, 0x00faa07200000000, 0x01fb31e200000000, + 0x00fcc07100000000, 0x01fd51e100000000, 0x01fee1e000000000, + 0x00ff707000000000}; + +#else /* W == 4 */ + +static const word_t crc_big_table[] = { + 0x00000000, 0x01019190, 0x01022191, 0x0003b001, 0x01044192, + 0x0005d002, 0x00066003, 0x0107f193, 0x01088194, 0x00091004, + 0x000aa005, 0x010b3195, 0x000cc006, 0x010d5196, 0x010ee197, + 0x000f7007, 0x01100199, 0x00119009, 0x00122008, 0x0113b198, + 0x0014400b, 0x0115d19b, 0x0116619a, 0x0017f00a, 0x0018800d, + 0x0119119d, 0x011aa19c, 0x001b300c, 0x011cc19f, 0x001d500f, + 0x001ee00e, 0x011f719e, 0x01200182, 0x00219012, 0x00222013, + 0x0123b183, 0x00244010, 0x0125d180, 0x01266181, 0x0027f011, + 0x00288016, 0x01291186, 0x012aa187, 0x002b3017, 0x012cc184, + 0x002d5014, 0x002ee015, 0x012f7185, 0x0030001b, 0x0131918b, + 0x0132218a, 0x0033b01a, 0x01344189, 0x0035d019, 0x00366018, + 0x0137f188, 0x0138818f, 0x0039101f, 0x003aa01e, 0x013b318e, + 0x003cc01d, 0x013d518d, 0x013ee18c, 0x003f701c, 0x014001b4, + 0x00419024, 0x00422025, 0x0143b1b5, 0x00444026, 0x0145d1b6, + 0x014661b7, 0x0047f027, 0x00488020, 0x014911b0, 0x014aa1b1, + 0x004b3021, 0x014cc1b2, 0x004d5022, 0x004ee023, 0x014f71b3, + 0x0050002d, 0x015191bd, 0x015221bc, 0x0053b02c, 0x015441bf, + 0x0055d02f, 0x0056602e, 0x0157f1be, 0x015881b9, 0x00591029, + 0x005aa028, 0x015b31b8, 0x005cc02b, 0x015d51bb, 0x015ee1ba, + 0x005f702a, 0x00600036, 0x016191a6, 0x016221a7, 0x0063b037, + 0x016441a4, 0x0065d034, 0x00666035, 0x0167f1a5, 0x016881a2, + 0x00691032, 0x006aa033, 0x016b31a3, 0x006cc030, 0x016d51a0, + 0x016ee1a1, 0x006f7031, 0x017001af, 0x0071903f, 0x0072203e, + 0x0173b1ae, 0x0074403d, 0x0175d1ad, 0x017661ac, 0x0077f03c, + 0x0078803b, 0x017911ab, 0x017aa1aa, 0x007b303a, 0x017cc1a9, + 0x007d5039, 0x007ee038, 0x017f71a8, 0x018001d8, 0x00819048, + 0x00822049, 0x0183b1d9, 0x0084404a, 0x0185d1da, 0x018661db, + 0x0087f04b, 0x0088804c, 0x018911dc, 0x018aa1dd, 0x008b304d, + 0x018cc1de, 0x008d504e, 0x008ee04f, 0x018f71df, 0x00900041, + 0x019191d1, 0x019221d0, 0x0093b040, 0x019441d3, 0x0095d043, + 0x00966042, 0x0197f1d2, 0x019881d5, 0x00991045, 0x009aa044, + 0x019b31d4, 0x009cc047, 0x019d51d7, 0x019ee1d6, 0x009f7046, + 0x00a0005a, 0x01a191ca, 0x01a221cb, 0x00a3b05b, 0x01a441c8, + 0x00a5d058, 0x00a66059, 0x01a7f1c9, 0x01a881ce, 0x00a9105e, + 0x00aaa05f, 0x01ab31cf, 0x00acc05c, 0x01ad51cc, 0x01aee1cd, + 0x00af705d, 0x01b001c3, 0x00b19053, 0x00b22052, 0x01b3b1c2, + 0x00b44051, 0x01b5d1c1, 0x01b661c0, 0x00b7f050, 0x00b88057, + 0x01b911c7, 0x01baa1c6, 0x00bb3056, 0x01bcc1c5, 0x00bd5055, + 0x00bee054, 0x01bf71c4, 0x00c0006c, 0x01c191fc, 0x01c221fd, + 0x00c3b06d, 0x01c441fe, 0x00c5d06e, 0x00c6606f, 0x01c7f1ff, + 0x01c881f8, 0x00c91068, 0x00caa069, 0x01cb31f9, 0x00ccc06a, + 0x01cd51fa, 0x01cee1fb, 0x00cf706b, 0x01d001f5, 0x00d19065, + 0x00d22064, 0x01d3b1f4, 0x00d44067, 0x01d5d1f7, 0x01d661f6, + 0x00d7f066, 0x00d88061, 0x01d911f1, 0x01daa1f0, 0x00db3060, + 0x01dcc1f3, 0x00dd5063, 0x00dee062, 0x01df71f2, 0x01e001ee, + 0x00e1907e, 0x00e2207f, 0x01e3b1ef, 0x00e4407c, 0x01e5d1ec, + 0x01e661ed, 0x00e7f07d, 0x00e8807a, 0x01e911ea, 0x01eaa1eb, + 0x00eb307b, 0x01ecc1e8, 0x00ed5078, 0x00eee079, 0x01ef71e9, + 0x00f00077, 0x01f191e7, 0x01f221e6, 0x00f3b076, 0x01f441e5, + 0x00f5d075, 0x00f66074, 0x01f7f1e4, 0x01f881e3, 0x00f91073, + 0x00faa072, 0x01fb31e2, 0x00fcc071, 0x01fd51e1, 0x01fee1e0, + 0x00ff7070}; + +#endif + +#if N == 1 + +#if W == 8 + +static const crc_t crc_braid_table[][256] = { + {0x00000000, 0x65904101, 0xcb208202, 0xaeb0c303, 0x26420407, + 0x43d24506, 0xed628605, 0x88f2c704, 0x4c84080e, 0x2914490f, + 0x87a48a0c, 0xe234cb0d, 0x6ac60c09, 0x0f564d08, 0xa1e68e0b, + 0xc476cf0a, 0x9908101c, 0xfc98511d, 0x5228921e, 0x37b8d31f, + 0xbf4a141b, 0xdada551a, 0x746a9619, 0x11fad718, 0xd58c1812, + 0xb01c5913, 0x1eac9a10, 0x7b3cdb11, 0xf3ce1c15, 0x965e5d14, + 0x38ee9e17, 0x5d7edf16, 0x8213203b, 0xe783613a, 0x4933a239, + 0x2ca3e338, 0xa451243c, 0xc1c1653d, 0x6f71a63e, 0x0ae1e73f, + 0xce972835, 0xab076934, 0x05b7aa37, 0x6027eb36, 0xe8d52c32, + 0x8d456d33, 0x23f5ae30, 0x4665ef31, 0x1b1b3027, 0x7e8b7126, + 0xd03bb225, 0xb5abf324, 0x3d593420, 0x58c97521, 0xf679b622, + 0x93e9f723, 0x579f3829, 0x320f7928, 0x9cbfba2b, 0xf92ffb2a, + 0x71dd3c2e, 0x144d7d2f, 0xbafdbe2c, 0xdf6dff2d, 0xb4254075, + 0xd1b50174, 0x7f05c277, 0x1a958376, 0x92674472, 0xf7f70573, + 0x5947c670, 0x3cd78771, 0xf8a1487b, 0x9d31097a, 0x3381ca79, + 0x56118b78, 0xdee34c7c, 0xbb730d7d, 0x15c3ce7e, 0x70538f7f, + 0x2d2d5069, 0x48bd1168, 0xe60dd26b, 0x839d936a, 0x0b6f546e, + 0x6eff156f, 0xc04fd66c, 0xa5df976d, 0x61a95867, 0x04391966, + 0xaa89da65, 0xcf199b64, 0x47eb5c60, 0x227b1d61, 0x8ccbde62, + 0xe95b9f63, 0x3636604e, 0x53a6214f, 0xfd16e24c, 0x9886a34d, + 0x10746449, 0x75e42548, 0xdb54e64b, 0xbec4a74a, 0x7ab26840, + 0x1f222941, 0xb192ea42, 0xd402ab43, 0x5cf06c47, 0x39602d46, + 0x97d0ee45, 0xf240af44, 0xaf3e7052, 0xcaae3153, 0x641ef250, + 0x018eb351, 0x897c7455, 0xecec3554, 0x425cf657, 0x27ccb756, + 0xe3ba785c, 0x862a395d, 0x289afa5e, 0x4d0abb5f, 0xc5f87c5b, + 0xa0683d5a, 0x0ed8fe59, 0x6b48bf58, 0xd84980e9, 0xbdd9c1e8, + 0x136902eb, 0x76f943ea, 0xfe0b84ee, 0x9b9bc5ef, 0x352b06ec, + 0x50bb47ed, 0x94cd88e7, 0xf15dc9e6, 0x5fed0ae5, 0x3a7d4be4, + 0xb28f8ce0, 0xd71fcde1, 0x79af0ee2, 0x1c3f4fe3, 0x414190f5, + 0x24d1d1f4, 0x8a6112f7, 0xeff153f6, 0x670394f2, 0x0293d5f3, + 0xac2316f0, 0xc9b357f1, 0x0dc598fb, 0x6855d9fa, 0xc6e51af9, + 0xa3755bf8, 0x2b879cfc, 0x4e17ddfd, 0xe0a71efe, 0x85375fff, + 0x5a5aa0d2, 0x3fcae1d3, 0x917a22d0, 0xf4ea63d1, 0x7c18a4d5, + 0x1988e5d4, 0xb73826d7, 0xd2a867d6, 0x16dea8dc, 0x734ee9dd, + 0xddfe2ade, 0xb86e6bdf, 0x309cacdb, 0x550cedda, 0xfbbc2ed9, + 0x9e2c6fd8, 0xc352b0ce, 0xa6c2f1cf, 0x087232cc, 0x6de273cd, + 0xe510b4c9, 0x8080f5c8, 0x2e3036cb, 0x4ba077ca, 0x8fd6b8c0, + 0xea46f9c1, 0x44f63ac2, 0x21667bc3, 0xa994bcc7, 0xcc04fdc6, + 0x62b43ec5, 0x07247fc4, 0x6c6cc09c, 0x09fc819d, 0xa74c429e, + 0xc2dc039f, 0x4a2ec49b, 0x2fbe859a, 0x810e4699, 0xe49e0798, + 0x20e8c892, 0x45788993, 0xebc84a90, 0x8e580b91, 0x06aacc95, + 0x633a8d94, 0xcd8a4e97, 0xa81a0f96, 0xf564d080, 0x90f49181, + 0x3e445282, 0x5bd41383, 0xd326d487, 0xb6b69586, 0x18065685, + 0x7d961784, 0xb9e0d88e, 0xdc70998f, 0x72c05a8c, 0x17501b8d, + 0x9fa2dc89, 0xfa329d88, 0x54825e8b, 0x31121f8a, 0xee7fe0a7, + 0x8befa1a6, 0x255f62a5, 0x40cf23a4, 0xc83de4a0, 0xadada5a1, + 0x031d66a2, 0x668d27a3, 0xa2fbe8a9, 0xc76ba9a8, 0x69db6aab, + 0x0c4b2baa, 0x84b9ecae, 0xe129adaf, 0x4f996eac, 0x2a092fad, + 0x7777f0bb, 0x12e7b1ba, 0xbc5772b9, 0xd9c733b8, 0x5135f4bc, + 0x34a5b5bd, 0x9a1576be, 0xff8537bf, 0x3bf3f8b5, 0x5e63b9b4, + 0xf0d37ab7, 0x95433bb6, 0x1db1fcb2, 0x7821bdb3, 0xd6917eb0, + 0xb3013fb1}, + {0x00000000, 0x009001d1, 0x012003a2, 0x01b00273, 0x02400744, + 0x02d00695, 0x036004e6, 0x03f00537, 0x04800e88, 0x04100f59, + 0x05a00d2a, 0x05300cfb, 0x06c009cc, 0x0650081d, 0x07e00a6e, + 0x07700bbf, 0x09001d10, 0x09901cc1, 0x08201eb2, 0x08b01f63, + 0x0b401a54, 0x0bd01b85, 0x0a6019f6, 0x0af01827, 0x0d801398, + 0x0d101249, 0x0ca0103a, 0x0c3011eb, 0x0fc014dc, 0x0f50150d, + 0x0ee0177e, 0x0e7016af, 0x12003a20, 0x12903bf1, 0x13203982, + 0x13b03853, 0x10403d64, 0x10d03cb5, 0x11603ec6, 0x11f03f17, + 0x168034a8, 0x16103579, 0x17a0370a, 0x173036db, 0x14c033ec, + 0x1450323d, 0x15e0304e, 0x1570319f, 0x1b002730, 0x1b9026e1, + 0x1a202492, 0x1ab02543, 0x19402074, 0x19d021a5, 0x186023d6, + 0x18f02207, 0x1f8029b8, 0x1f102869, 0x1ea02a1a, 0x1e302bcb, + 0x1dc02efc, 0x1d502f2d, 0x1ce02d5e, 0x1c702c8f, 0x24007440, + 0x24907591, 0x252077e2, 0x25b07633, 0x26407304, 0x26d072d5, + 0x276070a6, 0x27f07177, 0x20807ac8, 0x20107b19, 0x21a0796a, + 0x213078bb, 0x22c07d8c, 0x22507c5d, 0x23e07e2e, 0x23707fff, + 0x2d006950, 0x2d906881, 0x2c206af2, 0x2cb06b23, 0x2f406e14, + 0x2fd06fc5, 0x2e606db6, 0x2ef06c67, 0x298067d8, 0x29106609, + 0x28a0647a, 0x283065ab, 0x2bc0609c, 0x2b50614d, 0x2ae0633e, + 0x2a7062ef, 0x36004e60, 0x36904fb1, 0x37204dc2, 0x37b04c13, + 0x34404924, 0x34d048f5, 0x35604a86, 0x35f04b57, 0x328040e8, + 0x32104139, 0x33a0434a, 0x3330429b, 0x30c047ac, 0x3050467d, + 0x31e0440e, 0x317045df, 0x3f005370, 0x3f9052a1, 0x3e2050d2, + 0x3eb05103, 0x3d405434, 0x3dd055e5, 0x3c605796, 0x3cf05647, + 0x3b805df8, 0x3b105c29, 0x3aa05e5a, 0x3a305f8b, 0x39c05abc, + 0x39505b6d, 0x38e0591e, 0x387058cf, 0x4800e880, 0x4890e951, + 0x4920eb22, 0x49b0eaf3, 0x4a40efc4, 0x4ad0ee15, 0x4b60ec66, + 0x4bf0edb7, 0x4c80e608, 0x4c10e7d9, 0x4da0e5aa, 0x4d30e47b, + 0x4ec0e14c, 0x4e50e09d, 0x4fe0e2ee, 0x4f70e33f, 0x4100f590, + 0x4190f441, 0x4020f632, 0x40b0f7e3, 0x4340f2d4, 0x43d0f305, + 0x4260f176, 0x42f0f0a7, 0x4580fb18, 0x4510fac9, 0x44a0f8ba, + 0x4430f96b, 0x47c0fc5c, 0x4750fd8d, 0x46e0fffe, 0x4670fe2f, + 0x5a00d2a0, 0x5a90d371, 0x5b20d102, 0x5bb0d0d3, 0x5840d5e4, + 0x58d0d435, 0x5960d646, 0x59f0d797, 0x5e80dc28, 0x5e10ddf9, + 0x5fa0df8a, 0x5f30de5b, 0x5cc0db6c, 0x5c50dabd, 0x5de0d8ce, + 0x5d70d91f, 0x5300cfb0, 0x5390ce61, 0x5220cc12, 0x52b0cdc3, + 0x5140c8f4, 0x51d0c925, 0x5060cb56, 0x50f0ca87, 0x5780c138, + 0x5710c0e9, 0x56a0c29a, 0x5630c34b, 0x55c0c67c, 0x5550c7ad, + 0x54e0c5de, 0x5470c40f, 0x6c009cc0, 0x6c909d11, 0x6d209f62, + 0x6db09eb3, 0x6e409b84, 0x6ed09a55, 0x6f609826, 0x6ff099f7, + 0x68809248, 0x68109399, 0x69a091ea, 0x6930903b, 0x6ac0950c, + 0x6a5094dd, 0x6be096ae, 0x6b70977f, 0x650081d0, 0x65908001, + 0x64208272, 0x64b083a3, 0x67408694, 0x67d08745, 0x66608536, + 0x66f084e7, 0x61808f58, 0x61108e89, 0x60a08cfa, 0x60308d2b, + 0x63c0881c, 0x635089cd, 0x62e08bbe, 0x62708a6f, 0x7e00a6e0, + 0x7e90a731, 0x7f20a542, 0x7fb0a493, 0x7c40a1a4, 0x7cd0a075, + 0x7d60a206, 0x7df0a3d7, 0x7a80a868, 0x7a10a9b9, 0x7ba0abca, + 0x7b30aa1b, 0x78c0af2c, 0x7850aefd, 0x79e0ac8e, 0x7970ad5f, + 0x7700bbf0, 0x7790ba21, 0x7620b852, 0x76b0b983, 0x7540bcb4, + 0x75d0bd65, 0x7460bf16, 0x74f0bec7, 0x7380b578, 0x7310b4a9, + 0x72a0b6da, 0x7230b70b, 0x71c0b23c, 0x7150b3ed, 0x70e0b19e, + 0x7070b04f}, + {0x00000000, 0x9001d100, 0x9000a203, 0x00017303, 0x90024405, + 0x00039505, 0x0002e606, 0x90033706, 0x90078809, 0x00065909, + 0x00072a0a, 0x9006fb0a, 0x0005cc0c, 0x90041d0c, 0x90056e0f, + 0x0004bf0f, 0x900c1011, 0x000dc111, 0x000cb212, 0x900d6312, + 0x000e5414, 0x900f8514, 0x900ef617, 0x000f2717, 0x000b9818, + 0x900a4918, 0x900b3a1b, 0x000aeb1b, 0x9009dc1d, 0x00080d1d, + 0x00097e1e, 0x9008af1e, 0x901b2021, 0x001af121, 0x001b8222, + 0x901a5322, 0x00196424, 0x9018b524, 0x9019c627, 0x00181727, + 0x001ca828, 0x901d7928, 0x901c0a2b, 0x001ddb2b, 0x901eec2d, + 0x001f3d2d, 0x001e4e2e, 0x901f9f2e, 0x00173030, 0x9016e130, + 0x90179233, 0x00164333, 0x90157435, 0x0014a535, 0x0015d636, + 0x90140736, 0x9010b839, 0x00116939, 0x00101a3a, 0x9011cb3a, + 0x0012fc3c, 0x90132d3c, 0x90125e3f, 0x00138f3f, 0x90354041, + 0x00349141, 0x0035e242, 0x90343342, 0x00370444, 0x9036d544, + 0x9037a647, 0x00367747, 0x0032c848, 0x90331948, 0x90326a4b, + 0x0033bb4b, 0x90308c4d, 0x00315d4d, 0x00302e4e, 0x9031ff4e, + 0x00395050, 0x90388150, 0x9039f253, 0x00382353, 0x903b1455, + 0x003ac555, 0x003bb656, 0x903a6756, 0x903ed859, 0x003f0959, + 0x003e7a5a, 0x903fab5a, 0x003c9c5c, 0x903d4d5c, 0x903c3e5f, + 0x003def5f, 0x002e6060, 0x902fb160, 0x902ec263, 0x002f1363, + 0x902c2465, 0x002df565, 0x002c8666, 0x902d5766, 0x9029e869, + 0x00283969, 0x00294a6a, 0x90289b6a, 0x002bac6c, 0x902a7d6c, + 0x902b0e6f, 0x002adf6f, 0x90227071, 0x0023a171, 0x0022d272, + 0x90230372, 0x00203474, 0x9021e574, 0x90209677, 0x00214777, + 0x0025f878, 0x90242978, 0x90255a7b, 0x00248b7b, 0x9027bc7d, + 0x00266d7d, 0x00271e7e, 0x9026cf7e, 0x90698081, 0x00685181, + 0x00692282, 0x9068f382, 0x006bc484, 0x906a1584, 0x906b6687, + 0x006ab787, 0x006e0888, 0x906fd988, 0x906eaa8b, 0x006f7b8b, + 0x906c4c8d, 0x006d9d8d, 0x006cee8e, 0x906d3f8e, 0x00659090, + 0x90644190, 0x90653293, 0x0064e393, 0x9067d495, 0x00660595, + 0x00677696, 0x9066a796, 0x90621899, 0x0063c999, 0x0062ba9a, + 0x90636b9a, 0x00605c9c, 0x90618d9c, 0x9060fe9f, 0x00612f9f, + 0x0072a0a0, 0x907371a0, 0x907202a3, 0x0073d3a3, 0x9070e4a5, + 0x007135a5, 0x007046a6, 0x907197a6, 0x907528a9, 0x0074f9a9, + 0x00758aaa, 0x90745baa, 0x00776cac, 0x9076bdac, 0x9077ceaf, + 0x00761faf, 0x907eb0b1, 0x007f61b1, 0x007e12b2, 0x907fc3b2, + 0x007cf4b4, 0x907d25b4, 0x907c56b7, 0x007d87b7, 0x007938b8, + 0x9078e9b8, 0x90799abb, 0x00784bbb, 0x907b7cbd, 0x007aadbd, + 0x007bdebe, 0x907a0fbe, 0x005cc0c0, 0x905d11c0, 0x905c62c3, + 0x005db3c3, 0x905e84c5, 0x005f55c5, 0x005e26c6, 0x905ff7c6, + 0x905b48c9, 0x005a99c9, 0x005beaca, 0x905a3bca, 0x00590ccc, + 0x9058ddcc, 0x9059aecf, 0x00587fcf, 0x9050d0d1, 0x005101d1, + 0x005072d2, 0x9051a3d2, 0x005294d4, 0x905345d4, 0x905236d7, + 0x0053e7d7, 0x005758d8, 0x905689d8, 0x9057fadb, 0x00562bdb, + 0x90551cdd, 0x0054cddd, 0x0055bede, 0x90546fde, 0x9047e0e1, + 0x004631e1, 0x004742e2, 0x904693e2, 0x0045a4e4, 0x904475e4, + 0x904506e7, 0x0044d7e7, 0x004068e8, 0x9041b9e8, 0x9040caeb, + 0x00411beb, 0x90422ced, 0x0043fded, 0x00428eee, 0x90435fee, + 0x004bf0f0, 0x904a21f0, 0x904b52f3, 0x004a83f3, 0x9049b4f5, + 0x004865f5, 0x004916f6, 0x9048c7f6, 0x904c78f9, 0x004da9f9, + 0x004cdafa, 0x904d0bfa, 0x004e3cfc, 0x904fedfc, 0x904e9eff, + 0x004f4fff}, + {0x00000000, 0x90d00101, 0x91a30201, 0x01730300, 0x93450401, + 0x03950500, 0x02e60600, 0x92360701, 0x96890801, 0x06590900, + 0x072a0a00, 0x97fa0b01, 0x05cc0c00, 0x951c0d01, 0x946f0e01, + 0x04bf0f00, 0x9d111001, 0x0dc11100, 0x0cb21200, 0x9c621301, + 0x0e541400, 0x9e841501, 0x9ff71601, 0x0f271700, 0x0b981800, + 0x9b481901, 0x9a3b1a01, 0x0aeb1b00, 0x98dd1c01, 0x080d1d00, + 0x097e1e00, 0x99ae1f01, 0x8a212001, 0x1af12100, 0x1b822200, + 0x8b522301, 0x19642400, 0x89b42501, 0x88c72601, 0x18172700, + 0x1ca82800, 0x8c782901, 0x8d0b2a01, 0x1ddb2b00, 0x8fed2c01, + 0x1f3d2d00, 0x1e4e2e00, 0x8e9e2f01, 0x17303000, 0x87e03101, + 0x86933201, 0x16433300, 0x84753401, 0x14a53500, 0x15d63600, + 0x85063701, 0x81b93801, 0x11693900, 0x101a3a00, 0x80ca3b01, + 0x12fc3c00, 0x822c3d01, 0x835f3e01, 0x138f3f00, 0xa4414001, + 0x34914100, 0x35e24200, 0xa5324301, 0x37044400, 0xa7d44501, + 0xa6a74601, 0x36774700, 0x32c84800, 0xa2184901, 0xa36b4a01, + 0x33bb4b00, 0xa18d4c01, 0x315d4d00, 0x302e4e00, 0xa0fe4f01, + 0x39505000, 0xa9805101, 0xa8f35201, 0x38235300, 0xaa155401, + 0x3ac55500, 0x3bb65600, 0xab665701, 0xafd95801, 0x3f095900, + 0x3e7a5a00, 0xaeaa5b01, 0x3c9c5c00, 0xac4c5d01, 0xad3f5e01, + 0x3def5f00, 0x2e606000, 0xbeb06101, 0xbfc36201, 0x2f136300, + 0xbd256401, 0x2df56500, 0x2c866600, 0xbc566701, 0xb8e96801, + 0x28396900, 0x294a6a00, 0xb99a6b01, 0x2bac6c00, 0xbb7c6d01, + 0xba0f6e01, 0x2adf6f00, 0xb3717001, 0x23a17100, 0x22d27200, + 0xb2027301, 0x20347400, 0xb0e47501, 0xb1977601, 0x21477700, + 0x25f87800, 0xb5287901, 0xb45b7a01, 0x248b7b00, 0xb6bd7c01, + 0x266d7d00, 0x271e7e00, 0xb7ce7f01, 0xf8818001, 0x68518100, + 0x69228200, 0xf9f28301, 0x6bc48400, 0xfb148501, 0xfa678601, + 0x6ab78700, 0x6e088800, 0xfed88901, 0xffab8a01, 0x6f7b8b00, + 0xfd4d8c01, 0x6d9d8d00, 0x6cee8e00, 0xfc3e8f01, 0x65909000, + 0xf5409101, 0xf4339201, 0x64e39300, 0xf6d59401, 0x66059500, + 0x67769600, 0xf7a69701, 0xf3199801, 0x63c99900, 0x62ba9a00, + 0xf26a9b01, 0x605c9c00, 0xf08c9d01, 0xf1ff9e01, 0x612f9f00, + 0x72a0a000, 0xe270a101, 0xe303a201, 0x73d3a300, 0xe1e5a401, + 0x7135a500, 0x7046a600, 0xe096a701, 0xe429a801, 0x74f9a900, + 0x758aaa00, 0xe55aab01, 0x776cac00, 0xe7bcad01, 0xe6cfae01, + 0x761faf00, 0xefb1b001, 0x7f61b100, 0x7e12b200, 0xeec2b301, + 0x7cf4b400, 0xec24b501, 0xed57b601, 0x7d87b700, 0x7938b800, + 0xe9e8b901, 0xe89bba01, 0x784bbb00, 0xea7dbc01, 0x7aadbd00, + 0x7bdebe00, 0xeb0ebf01, 0x5cc0c000, 0xcc10c101, 0xcd63c201, + 0x5db3c300, 0xcf85c401, 0x5f55c500, 0x5e26c600, 0xcef6c701, + 0xca49c801, 0x5a99c900, 0x5beaca00, 0xcb3acb01, 0x590ccc00, + 0xc9dccd01, 0xc8afce01, 0x587fcf00, 0xc1d1d001, 0x5101d100, + 0x5072d200, 0xc0a2d301, 0x5294d400, 0xc244d501, 0xc337d601, + 0x53e7d700, 0x5758d800, 0xc788d901, 0xc6fbda01, 0x562bdb00, + 0xc41ddc01, 0x54cddd00, 0x55bede00, 0xc56edf01, 0xd6e1e001, + 0x4631e100, 0x4742e200, 0xd792e301, 0x45a4e400, 0xd574e501, + 0xd407e601, 0x44d7e700, 0x4068e800, 0xd0b8e901, 0xd1cbea01, + 0x411beb00, 0xd32dec01, 0x43fded00, 0x428eee00, 0xd25eef01, + 0x4bf0f000, 0xdb20f101, 0xda53f201, 0x4a83f300, 0xd8b5f401, + 0x4865f500, 0x4916f600, 0xd9c6f701, 0xdd79f801, 0x4da9f900, + 0x4cdafa00, 0xdc0afb01, 0x4e3cfc00, 0xdeecfd01, 0xdf9ffe01, + 0x4f4fff00}, + {0x00000000, 0x41000001, 0x82000002, 0xc3000003, 0xb4030007, + 0xf5030006, 0x36030005, 0x77030004, 0xd805000d, 0x9905000c, + 0x5a05000f, 0x1b05000e, 0x6c06000a, 0x2d06000b, 0xee060008, + 0xaf060009, 0x00090019, 0x41090018, 0x8209001b, 0xc309001a, + 0xb40a001e, 0xf50a001f, 0x360a001c, 0x770a001d, 0xd80c0014, + 0x990c0015, 0x5a0c0016, 0x1b0c0017, 0x6c0f0013, 0x2d0f0012, + 0xee0f0011, 0xaf0f0010, 0x00120032, 0x41120033, 0x82120030, + 0xc3120031, 0xb4110035, 0xf5110034, 0x36110037, 0x77110036, + 0xd817003f, 0x9917003e, 0x5a17003d, 0x1b17003c, 0x6c140038, + 0x2d140039, 0xee14003a, 0xaf14003b, 0x001b002b, 0x411b002a, + 0x821b0029, 0xc31b0028, 0xb418002c, 0xf518002d, 0x3618002e, + 0x7718002f, 0xd81e0026, 0x991e0027, 0x5a1e0024, 0x1b1e0025, + 0x6c1d0021, 0x2d1d0020, 0xee1d0023, 0xaf1d0022, 0x00240064, + 0x41240065, 0x82240066, 0xc3240067, 0xb4270063, 0xf5270062, + 0x36270061, 0x77270060, 0xd8210069, 0x99210068, 0x5a21006b, + 0x1b21006a, 0x6c22006e, 0x2d22006f, 0xee22006c, 0xaf22006d, + 0x002d007d, 0x412d007c, 0x822d007f, 0xc32d007e, 0xb42e007a, + 0xf52e007b, 0x362e0078, 0x772e0079, 0xd8280070, 0x99280071, + 0x5a280072, 0x1b280073, 0x6c2b0077, 0x2d2b0076, 0xee2b0075, + 0xaf2b0074, 0x00360056, 0x41360057, 0x82360054, 0xc3360055, + 0xb4350051, 0xf5350050, 0x36350053, 0x77350052, 0xd833005b, + 0x9933005a, 0x5a330059, 0x1b330058, 0x6c30005c, 0x2d30005d, + 0xee30005e, 0xaf30005f, 0x003f004f, 0x413f004e, 0x823f004d, + 0xc33f004c, 0xb43c0048, 0xf53c0049, 0x363c004a, 0x773c004b, + 0xd83a0042, 0x993a0043, 0x5a3a0040, 0x1b3a0041, 0x6c390045, + 0x2d390044, 0xee390047, 0xaf390046, 0x004800c8, 0x414800c9, + 0x824800ca, 0xc34800cb, 0xb44b00cf, 0xf54b00ce, 0x364b00cd, + 0x774b00cc, 0xd84d00c5, 0x994d00c4, 0x5a4d00c7, 0x1b4d00c6, + 0x6c4e00c2, 0x2d4e00c3, 0xee4e00c0, 0xaf4e00c1, 0x004100d1, + 0x414100d0, 0x824100d3, 0xc34100d2, 0xb44200d6, 0xf54200d7, + 0x364200d4, 0x774200d5, 0xd84400dc, 0x994400dd, 0x5a4400de, + 0x1b4400df, 0x6c4700db, 0x2d4700da, 0xee4700d9, 0xaf4700d8, + 0x005a00fa, 0x415a00fb, 0x825a00f8, 0xc35a00f9, 0xb45900fd, + 0xf55900fc, 0x365900ff, 0x775900fe, 0xd85f00f7, 0x995f00f6, + 0x5a5f00f5, 0x1b5f00f4, 0x6c5c00f0, 0x2d5c00f1, 0xee5c00f2, + 0xaf5c00f3, 0x005300e3, 0x415300e2, 0x825300e1, 0xc35300e0, + 0xb45000e4, 0xf55000e5, 0x365000e6, 0x775000e7, 0xd85600ee, + 0x995600ef, 0x5a5600ec, 0x1b5600ed, 0x6c5500e9, 0x2d5500e8, + 0xee5500eb, 0xaf5500ea, 0x006c00ac, 0x416c00ad, 0x826c00ae, + 0xc36c00af, 0xb46f00ab, 0xf56f00aa, 0x366f00a9, 0x776f00a8, + 0xd86900a1, 0x996900a0, 0x5a6900a3, 0x1b6900a2, 0x6c6a00a6, + 0x2d6a00a7, 0xee6a00a4, 0xaf6a00a5, 0x006500b5, 0x416500b4, + 0x826500b7, 0xc36500b6, 0xb46600b2, 0xf56600b3, 0x366600b0, + 0x776600b1, 0xd86000b8, 0x996000b9, 0x5a6000ba, 0x1b6000bb, + 0x6c6300bf, 0x2d6300be, 0xee6300bd, 0xaf6300bc, 0x007e009e, + 0x417e009f, 0x827e009c, 0xc37e009d, 0xb47d0099, 0xf57d0098, + 0x367d009b, 0x777d009a, 0xd87b0093, 0x997b0092, 0x5a7b0091, + 0x1b7b0090, 0x6c780094, 0x2d780095, 0xee780096, 0xaf780097, + 0x00770087, 0x41770086, 0x82770085, 0xc3770084, 0xb4740080, + 0xf5740081, 0x36740082, 0x77740083, 0xd872008a, 0x9972008b, + 0x5a720088, 0x1b720089, 0x6c71008d, 0x2d71008c, 0xee71008f, + 0xaf71008e}, + {0x00000000, 0x00900190, 0x01200320, 0x01b002b0, 0x02400640, + 0x02d007d0, 0x03600560, 0x03f004f0, 0x04800c80, 0x04100d10, + 0x05a00fa0, 0x05300e30, 0x06c00ac0, 0x06500b50, 0x07e009e0, + 0x07700870, 0x09001900, 0x09901890, 0x08201a20, 0x08b01bb0, + 0x0b401f40, 0x0bd01ed0, 0x0a601c60, 0x0af01df0, 0x0d801580, + 0x0d101410, 0x0ca016a0, 0x0c301730, 0x0fc013c0, 0x0f501250, + 0x0ee010e0, 0x0e701170, 0x12003200, 0x12903390, 0x13203120, + 0x13b030b0, 0x10403440, 0x10d035d0, 0x11603760, 0x11f036f0, + 0x16803e80, 0x16103f10, 0x17a03da0, 0x17303c30, 0x14c038c0, + 0x14503950, 0x15e03be0, 0x15703a70, 0x1b002b00, 0x1b902a90, + 0x1a202820, 0x1ab029b0, 0x19402d40, 0x19d02cd0, 0x18602e60, + 0x18f02ff0, 0x1f802780, 0x1f102610, 0x1ea024a0, 0x1e302530, + 0x1dc021c0, 0x1d502050, 0x1ce022e0, 0x1c702370, 0x24006400, + 0x24906590, 0x25206720, 0x25b066b0, 0x26406240, 0x26d063d0, + 0x27606160, 0x27f060f0, 0x20806880, 0x20106910, 0x21a06ba0, + 0x21306a30, 0x22c06ec0, 0x22506f50, 0x23e06de0, 0x23706c70, + 0x2d007d00, 0x2d907c90, 0x2c207e20, 0x2cb07fb0, 0x2f407b40, + 0x2fd07ad0, 0x2e607860, 0x2ef079f0, 0x29807180, 0x29107010, + 0x28a072a0, 0x28307330, 0x2bc077c0, 0x2b507650, 0x2ae074e0, + 0x2a707570, 0x36005600, 0x36905790, 0x37205520, 0x37b054b0, + 0x34405040, 0x34d051d0, 0x35605360, 0x35f052f0, 0x32805a80, + 0x32105b10, 0x33a059a0, 0x33305830, 0x30c05cc0, 0x30505d50, + 0x31e05fe0, 0x31705e70, 0x3f004f00, 0x3f904e90, 0x3e204c20, + 0x3eb04db0, 0x3d404940, 0x3dd048d0, 0x3c604a60, 0x3cf04bf0, + 0x3b804380, 0x3b104210, 0x3aa040a0, 0x3a304130, 0x39c045c0, + 0x39504450, 0x38e046e0, 0x38704770, 0x4800c800, 0x4890c990, + 0x4920cb20, 0x49b0cab0, 0x4a40ce40, 0x4ad0cfd0, 0x4b60cd60, + 0x4bf0ccf0, 0x4c80c480, 0x4c10c510, 0x4da0c7a0, 0x4d30c630, + 0x4ec0c2c0, 0x4e50c350, 0x4fe0c1e0, 0x4f70c070, 0x4100d100, + 0x4190d090, 0x4020d220, 0x40b0d3b0, 0x4340d740, 0x43d0d6d0, + 0x4260d460, 0x42f0d5f0, 0x4580dd80, 0x4510dc10, 0x44a0dea0, + 0x4430df30, 0x47c0dbc0, 0x4750da50, 0x46e0d8e0, 0x4670d970, + 0x5a00fa00, 0x5a90fb90, 0x5b20f920, 0x5bb0f8b0, 0x5840fc40, + 0x58d0fdd0, 0x5960ff60, 0x59f0fef0, 0x5e80f680, 0x5e10f710, + 0x5fa0f5a0, 0x5f30f430, 0x5cc0f0c0, 0x5c50f150, 0x5de0f3e0, + 0x5d70f270, 0x5300e300, 0x5390e290, 0x5220e020, 0x52b0e1b0, + 0x5140e540, 0x51d0e4d0, 0x5060e660, 0x50f0e7f0, 0x5780ef80, + 0x5710ee10, 0x56a0eca0, 0x5630ed30, 0x55c0e9c0, 0x5550e850, + 0x54e0eae0, 0x5470eb70, 0x6c00ac00, 0x6c90ad90, 0x6d20af20, + 0x6db0aeb0, 0x6e40aa40, 0x6ed0abd0, 0x6f60a960, 0x6ff0a8f0, + 0x6880a080, 0x6810a110, 0x69a0a3a0, 0x6930a230, 0x6ac0a6c0, + 0x6a50a750, 0x6be0a5e0, 0x6b70a470, 0x6500b500, 0x6590b490, + 0x6420b620, 0x64b0b7b0, 0x6740b340, 0x67d0b2d0, 0x6660b060, + 0x66f0b1f0, 0x6180b980, 0x6110b810, 0x60a0baa0, 0x6030bb30, + 0x63c0bfc0, 0x6350be50, 0x62e0bce0, 0x6270bd70, 0x7e009e00, + 0x7e909f90, 0x7f209d20, 0x7fb09cb0, 0x7c409840, 0x7cd099d0, + 0x7d609b60, 0x7df09af0, 0x7a809280, 0x7a109310, 0x7ba091a0, + 0x7b309030, 0x78c094c0, 0x78509550, 0x79e097e0, 0x79709670, + 0x77008700, 0x77908690, 0x76208420, 0x76b085b0, 0x75408140, + 0x75d080d0, 0x74608260, 0x74f083f0, 0x73808b80, 0x73108a10, + 0x72a088a0, 0x72308930, 0x71c08dc0, 0x71508c50, 0x70e08ee0, + 0x70708f70}, + {0x00000000, 0x90019000, 0x90002003, 0x0001b003, 0x90034005, + 0x0002d005, 0x00036006, 0x9002f006, 0x90058009, 0x00041009, + 0x0005a00a, 0x9004300a, 0x0006c00c, 0x9007500c, 0x9006e00f, + 0x0007700f, 0x90080011, 0x00099011, 0x00082012, 0x9009b012, + 0x000b4014, 0x900ad014, 0x900b6017, 0x000af017, 0x000d8018, + 0x900c1018, 0x900da01b, 0x000c301b, 0x900ec01d, 0x000f501d, + 0x000ee01e, 0x900f701e, 0x90130021, 0x00129021, 0x00132022, + 0x9012b022, 0x00104024, 0x9011d024, 0x90106027, 0x0011f027, + 0x00168028, 0x90171028, 0x9016a02b, 0x0017302b, 0x9015c02d, + 0x0014502d, 0x0015e02e, 0x9014702e, 0x001b0030, 0x901a9030, + 0x901b2033, 0x001ab033, 0x90184035, 0x0019d035, 0x00186036, + 0x9019f036, 0x901e8039, 0x001f1039, 0x001ea03a, 0x901f303a, + 0x001dc03c, 0x901c503c, 0x901de03f, 0x001c703f, 0x90250041, + 0x00249041, 0x00252042, 0x9024b042, 0x00264044, 0x9027d044, + 0x90266047, 0x0027f047, 0x00208048, 0x90211048, 0x9020a04b, + 0x0021304b, 0x9023c04d, 0x0022504d, 0x0023e04e, 0x9022704e, + 0x002d0050, 0x902c9050, 0x902d2053, 0x002cb053, 0x902e4055, + 0x002fd055, 0x002e6056, 0x902ff056, 0x90288059, 0x00291059, + 0x0028a05a, 0x9029305a, 0x002bc05c, 0x902a505c, 0x902be05f, + 0x002a705f, 0x00360060, 0x90379060, 0x90362063, 0x0037b063, + 0x90354065, 0x0034d065, 0x00356066, 0x9034f066, 0x90338069, + 0x00321069, 0x0033a06a, 0x9032306a, 0x0030c06c, 0x9031506c, + 0x9030e06f, 0x0031706f, 0x903e0071, 0x003f9071, 0x003e2072, + 0x903fb072, 0x003d4074, 0x903cd074, 0x903d6077, 0x003cf077, + 0x003b8078, 0x903a1078, 0x903ba07b, 0x003a307b, 0x9038c07d, + 0x0039507d, 0x0038e07e, 0x9039707e, 0x90490081, 0x00489081, + 0x00492082, 0x9048b082, 0x004a4084, 0x904bd084, 0x904a6087, + 0x004bf087, 0x004c8088, 0x904d1088, 0x904ca08b, 0x004d308b, + 0x904fc08d, 0x004e508d, 0x004fe08e, 0x904e708e, 0x00410090, + 0x90409090, 0x90412093, 0x0040b093, 0x90424095, 0x0043d095, + 0x00426096, 0x9043f096, 0x90448099, 0x00451099, 0x0044a09a, + 0x9045309a, 0x0047c09c, 0x9046509c, 0x9047e09f, 0x0046709f, + 0x005a00a0, 0x905b90a0, 0x905a20a3, 0x005bb0a3, 0x905940a5, + 0x0058d0a5, 0x005960a6, 0x9058f0a6, 0x905f80a9, 0x005e10a9, + 0x005fa0aa, 0x905e30aa, 0x005cc0ac, 0x905d50ac, 0x905ce0af, + 0x005d70af, 0x905200b1, 0x005390b1, 0x005220b2, 0x9053b0b2, + 0x005140b4, 0x9050d0b4, 0x905160b7, 0x0050f0b7, 0x005780b8, + 0x905610b8, 0x9057a0bb, 0x005630bb, 0x9054c0bd, 0x005550bd, + 0x0054e0be, 0x905570be, 0x006c00c0, 0x906d90c0, 0x906c20c3, + 0x006db0c3, 0x906f40c5, 0x006ed0c5, 0x006f60c6, 0x906ef0c6, + 0x906980c9, 0x006810c9, 0x0069a0ca, 0x906830ca, 0x006ac0cc, + 0x906b50cc, 0x906ae0cf, 0x006b70cf, 0x906400d1, 0x006590d1, + 0x006420d2, 0x9065b0d2, 0x006740d4, 0x9066d0d4, 0x906760d7, + 0x0066f0d7, 0x006180d8, 0x906010d8, 0x9061a0db, 0x006030db, + 0x9062c0dd, 0x006350dd, 0x0062e0de, 0x906370de, 0x907f00e1, + 0x007e90e1, 0x007f20e2, 0x907eb0e2, 0x007c40e4, 0x907dd0e4, + 0x907c60e7, 0x007df0e7, 0x007a80e8, 0x907b10e8, 0x907aa0eb, + 0x007b30eb, 0x9079c0ed, 0x007850ed, 0x0079e0ee, 0x907870ee, + 0x007700f0, 0x907690f0, 0x907720f3, 0x0076b0f3, 0x907440f5, + 0x0075d0f5, 0x007460f6, 0x9075f0f6, 0x907280f9, 0x007310f9, + 0x0072a0fa, 0x907330fa, 0x0071c0fc, 0x907050fc, 0x9071e0ff, + 0x007070ff}, + {0x00000000, 0x90910101, 0x91210201, 0x01b00300, 0x92410401, + 0x02d00500, 0x03600600, 0x93f10701, 0x94810801, 0x04100900, + 0x05a00a00, 0x95310b01, 0x06c00c00, 0x96510d01, 0x97e10e01, + 0x07700f00, 0x99011001, 0x09901100, 0x08201200, 0x98b11301, + 0x0b401400, 0x9bd11501, 0x9a611601, 0x0af01700, 0x0d801800, + 0x9d111901, 0x9ca11a01, 0x0c301b00, 0x9fc11c01, 0x0f501d00, + 0x0ee01e00, 0x9e711f01, 0x82012001, 0x12902100, 0x13202200, + 0x83b12301, 0x10402400, 0x80d12501, 0x81612601, 0x11f02700, + 0x16802800, 0x86112901, 0x87a12a01, 0x17302b00, 0x84c12c01, + 0x14502d00, 0x15e02e00, 0x85712f01, 0x1b003000, 0x8b913101, + 0x8a213201, 0x1ab03300, 0x89413401, 0x19d03500, 0x18603600, + 0x88f13701, 0x8f813801, 0x1f103900, 0x1ea03a00, 0x8e313b01, + 0x1dc03c00, 0x8d513d01, 0x8ce13e01, 0x1c703f00, 0xb4014001, + 0x24904100, 0x25204200, 0xb5b14301, 0x26404400, 0xb6d14501, + 0xb7614601, 0x27f04700, 0x20804800, 0xb0114901, 0xb1a14a01, + 0x21304b00, 0xb2c14c01, 0x22504d00, 0x23e04e00, 0xb3714f01, + 0x2d005000, 0xbd915101, 0xbc215201, 0x2cb05300, 0xbf415401, + 0x2fd05500, 0x2e605600, 0xbef15701, 0xb9815801, 0x29105900, + 0x28a05a00, 0xb8315b01, 0x2bc05c00, 0xbb515d01, 0xbae15e01, + 0x2a705f00, 0x36006000, 0xa6916101, 0xa7216201, 0x37b06300, + 0xa4416401, 0x34d06500, 0x35606600, 0xa5f16701, 0xa2816801, + 0x32106900, 0x33a06a00, 0xa3316b01, 0x30c06c00, 0xa0516d01, + 0xa1e16e01, 0x31706f00, 0xaf017001, 0x3f907100, 0x3e207200, + 0xaeb17301, 0x3d407400, 0xadd17501, 0xac617601, 0x3cf07700, + 0x3b807800, 0xab117901, 0xaaa17a01, 0x3a307b00, 0xa9c17c01, + 0x39507d00, 0x38e07e00, 0xa8717f01, 0xd8018001, 0x48908100, + 0x49208200, 0xd9b18301, 0x4a408400, 0xdad18501, 0xdb618601, + 0x4bf08700, 0x4c808800, 0xdc118901, 0xdda18a01, 0x4d308b00, + 0xdec18c01, 0x4e508d00, 0x4fe08e00, 0xdf718f01, 0x41009000, + 0xd1919101, 0xd0219201, 0x40b09300, 0xd3419401, 0x43d09500, + 0x42609600, 0xd2f19701, 0xd5819801, 0x45109900, 0x44a09a00, + 0xd4319b01, 0x47c09c00, 0xd7519d01, 0xd6e19e01, 0x46709f00, + 0x5a00a000, 0xca91a101, 0xcb21a201, 0x5bb0a300, 0xc841a401, + 0x58d0a500, 0x5960a600, 0xc9f1a701, 0xce81a801, 0x5e10a900, + 0x5fa0aa00, 0xcf31ab01, 0x5cc0ac00, 0xcc51ad01, 0xcde1ae01, + 0x5d70af00, 0xc301b001, 0x5390b100, 0x5220b200, 0xc2b1b301, + 0x5140b400, 0xc1d1b501, 0xc061b601, 0x50f0b700, 0x5780b800, + 0xc711b901, 0xc6a1ba01, 0x5630bb00, 0xc5c1bc01, 0x5550bd00, + 0x54e0be00, 0xc471bf01, 0x6c00c000, 0xfc91c101, 0xfd21c201, + 0x6db0c300, 0xfe41c401, 0x6ed0c500, 0x6f60c600, 0xfff1c701, + 0xf881c801, 0x6810c900, 0x69a0ca00, 0xf931cb01, 0x6ac0cc00, + 0xfa51cd01, 0xfbe1ce01, 0x6b70cf00, 0xf501d001, 0x6590d100, + 0x6420d200, 0xf4b1d301, 0x6740d400, 0xf7d1d501, 0xf661d601, + 0x66f0d700, 0x6180d800, 0xf111d901, 0xf0a1da01, 0x6030db00, + 0xf3c1dc01, 0x6350dd00, 0x62e0de00, 0xf271df01, 0xee01e001, + 0x7e90e100, 0x7f20e200, 0xefb1e301, 0x7c40e400, 0xecd1e501, + 0xed61e601, 0x7df0e700, 0x7a80e800, 0xea11e901, 0xeba1ea01, + 0x7b30eb00, 0xe8c1ec01, 0x7850ed00, 0x79e0ee00, 0xe971ef01, + 0x7700f000, 0xe791f101, 0xe621f201, 0x76b0f300, 0xe541f401, + 0x75d0f500, 0x7460f600, 0xe4f1f701, 0xe381f801, 0x7310f900, + 0x72a0fa00, 0xe231fb01, 0x71c0fc00, 0xe151fd01, 0xe0e1fe01, + 0x7070ff00}}; + +static const word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x0101919000000000, 0x0102219100000000, + 0x0003b00100000000, 0x0104419200000000, 0x0005d00200000000, + 0x0006600300000000, 0x0107f19300000000, 0x0108819400000000, + 0x0009100400000000, 0x000aa00500000000, 0x010b319500000000, + 0x000cc00600000000, 0x010d519600000000, 0x010ee19700000000, + 0x000f700700000000, 0x0110019900000000, 0x0011900900000000, + 0x0012200800000000, 0x0113b19800000000, 0x0014400b00000000, + 0x0115d19b00000000, 0x0116619a00000000, 0x0017f00a00000000, + 0x0018800d00000000, 0x0119119d00000000, 0x011aa19c00000000, + 0x001b300c00000000, 0x011cc19f00000000, 0x001d500f00000000, + 0x001ee00e00000000, 0x011f719e00000000, 0x0120018200000000, + 0x0021901200000000, 0x0022201300000000, 0x0123b18300000000, + 0x0024401000000000, 0x0125d18000000000, 0x0126618100000000, + 0x0027f01100000000, 0x0028801600000000, 0x0129118600000000, + 0x012aa18700000000, 0x002b301700000000, 0x012cc18400000000, + 0x002d501400000000, 0x002ee01500000000, 0x012f718500000000, + 0x0030001b00000000, 0x0131918b00000000, 0x0132218a00000000, + 0x0033b01a00000000, 0x0134418900000000, 0x0035d01900000000, + 0x0036601800000000, 0x0137f18800000000, 0x0138818f00000000, + 0x0039101f00000000, 0x003aa01e00000000, 0x013b318e00000000, + 0x003cc01d00000000, 0x013d518d00000000, 0x013ee18c00000000, + 0x003f701c00000000, 0x014001b400000000, 0x0041902400000000, + 0x0042202500000000, 0x0143b1b500000000, 0x0044402600000000, + 0x0145d1b600000000, 0x014661b700000000, 0x0047f02700000000, + 0x0048802000000000, 0x014911b000000000, 0x014aa1b100000000, + 0x004b302100000000, 0x014cc1b200000000, 0x004d502200000000, + 0x004ee02300000000, 0x014f71b300000000, 0x0050002d00000000, + 0x015191bd00000000, 0x015221bc00000000, 0x0053b02c00000000, + 0x015441bf00000000, 0x0055d02f00000000, 0x0056602e00000000, + 0x0157f1be00000000, 0x015881b900000000, 0x0059102900000000, + 0x005aa02800000000, 0x015b31b800000000, 0x005cc02b00000000, + 0x015d51bb00000000, 0x015ee1ba00000000, 0x005f702a00000000, + 0x0060003600000000, 0x016191a600000000, 0x016221a700000000, + 0x0063b03700000000, 0x016441a400000000, 0x0065d03400000000, + 0x0066603500000000, 0x0167f1a500000000, 0x016881a200000000, + 0x0069103200000000, 0x006aa03300000000, 0x016b31a300000000, + 0x006cc03000000000, 0x016d51a000000000, 0x016ee1a100000000, + 0x006f703100000000, 0x017001af00000000, 0x0071903f00000000, + 0x0072203e00000000, 0x0173b1ae00000000, 0x0074403d00000000, + 0x0175d1ad00000000, 0x017661ac00000000, 0x0077f03c00000000, + 0x0078803b00000000, 0x017911ab00000000, 0x017aa1aa00000000, + 0x007b303a00000000, 0x017cc1a900000000, 0x007d503900000000, + 0x007ee03800000000, 0x017f71a800000000, 0x018001d800000000, + 0x0081904800000000, 0x0082204900000000, 0x0183b1d900000000, + 0x0084404a00000000, 0x0185d1da00000000, 0x018661db00000000, + 0x0087f04b00000000, 0x0088804c00000000, 0x018911dc00000000, + 0x018aa1dd00000000, 0x008b304d00000000, 0x018cc1de00000000, + 0x008d504e00000000, 0x008ee04f00000000, 0x018f71df00000000, + 0x0090004100000000, 0x019191d100000000, 0x019221d000000000, + 0x0093b04000000000, 0x019441d300000000, 0x0095d04300000000, + 0x0096604200000000, 0x0197f1d200000000, 0x019881d500000000, + 0x0099104500000000, 0x009aa04400000000, 0x019b31d400000000, + 0x009cc04700000000, 0x019d51d700000000, 0x019ee1d600000000, + 0x009f704600000000, 0x00a0005a00000000, 0x01a191ca00000000, + 0x01a221cb00000000, 0x00a3b05b00000000, 0x01a441c800000000, + 0x00a5d05800000000, 0x00a6605900000000, 0x01a7f1c900000000, + 0x01a881ce00000000, 0x00a9105e00000000, 0x00aaa05f00000000, + 0x01ab31cf00000000, 0x00acc05c00000000, 0x01ad51cc00000000, + 0x01aee1cd00000000, 0x00af705d00000000, 0x01b001c300000000, + 0x00b1905300000000, 0x00b2205200000000, 0x01b3b1c200000000, + 0x00b4405100000000, 0x01b5d1c100000000, 0x01b661c000000000, + 0x00b7f05000000000, 0x00b8805700000000, 0x01b911c700000000, + 0x01baa1c600000000, 0x00bb305600000000, 0x01bcc1c500000000, + 0x00bd505500000000, 0x00bee05400000000, 0x01bf71c400000000, + 0x00c0006c00000000, 0x01c191fc00000000, 0x01c221fd00000000, + 0x00c3b06d00000000, 0x01c441fe00000000, 0x00c5d06e00000000, + 0x00c6606f00000000, 0x01c7f1ff00000000, 0x01c881f800000000, + 0x00c9106800000000, 0x00caa06900000000, 0x01cb31f900000000, + 0x00ccc06a00000000, 0x01cd51fa00000000, 0x01cee1fb00000000, + 0x00cf706b00000000, 0x01d001f500000000, 0x00d1906500000000, + 0x00d2206400000000, 0x01d3b1f400000000, 0x00d4406700000000, + 0x01d5d1f700000000, 0x01d661f600000000, 0x00d7f06600000000, + 0x00d8806100000000, 0x01d911f100000000, 0x01daa1f000000000, + 0x00db306000000000, 0x01dcc1f300000000, 0x00dd506300000000, + 0x00dee06200000000, 0x01df71f200000000, 0x01e001ee00000000, + 0x00e1907e00000000, 0x00e2207f00000000, 0x01e3b1ef00000000, + 0x00e4407c00000000, 0x01e5d1ec00000000, 0x01e661ed00000000, + 0x00e7f07d00000000, 0x00e8807a00000000, 0x01e911ea00000000, + 0x01eaa1eb00000000, 0x00eb307b00000000, 0x01ecc1e800000000, + 0x00ed507800000000, 0x00eee07900000000, 0x01ef71e900000000, + 0x00f0007700000000, 0x01f191e700000000, 0x01f221e600000000, + 0x00f3b07600000000, 0x01f441e500000000, 0x00f5d07500000000, + 0x00f6607400000000, 0x01f7f1e400000000, 0x01f881e300000000, + 0x00f9107300000000, 0x00faa07200000000, 0x01fb31e200000000, + 0x00fcc07100000000, 0x01fd51e100000000, 0x01fee1e000000000, + 0x00ff707000000000}, + {0x0000000000000000, 0x0090019000000000, 0x0320009000000000, + 0x03b0010000000000, 0x0540039000000000, 0x05d0020000000000, + 0x0660030000000000, 0x06f0029000000000, 0x0980059000000000, + 0x0910040000000000, 0x0aa0050000000000, 0x0a30049000000000, + 0x0cc0060000000000, 0x0c50079000000000, 0x0fe0069000000000, + 0x0f70070000000000, 0x1100089000000000, 0x1190090000000000, + 0x1220080000000000, 0x12b0099000000000, 0x14400b0000000000, + 0x14d00a9000000000, 0x17600b9000000000, 0x17f00a0000000000, + 0x18800d0000000000, 0x18100c9000000000, 0x1ba00d9000000000, + 0x1b300c0000000000, 0x1dc00e9000000000, 0x1d500f0000000000, + 0x1ee00e0000000000, 0x1e700f9000000000, 0x2100139000000000, + 0x2190120000000000, 0x2220130000000000, 0x22b0129000000000, + 0x2440100000000000, 0x24d0119000000000, 0x2760109000000000, + 0x27f0110000000000, 0x2880160000000000, 0x2810179000000000, + 0x2ba0169000000000, 0x2b30170000000000, 0x2dc0159000000000, + 0x2d50140000000000, 0x2ee0150000000000, 0x2e70149000000000, + 0x30001b0000000000, 0x30901a9000000000, 0x33201b9000000000, + 0x33b01a0000000000, 0x3540189000000000, 0x35d0190000000000, + 0x3660180000000000, 0x36f0199000000000, 0x39801e9000000000, + 0x39101f0000000000, 0x3aa01e0000000000, 0x3a301f9000000000, + 0x3cc01d0000000000, 0x3c501c9000000000, 0x3fe01d9000000000, + 0x3f701c0000000000, 0x4100259000000000, 0x4190240000000000, + 0x4220250000000000, 0x42b0249000000000, 0x4440260000000000, + 0x44d0279000000000, 0x4760269000000000, 0x47f0270000000000, + 0x4880200000000000, 0x4810219000000000, 0x4ba0209000000000, + 0x4b30210000000000, 0x4dc0239000000000, 0x4d50220000000000, + 0x4ee0230000000000, 0x4e70229000000000, 0x50002d0000000000, + 0x50902c9000000000, 0x53202d9000000000, 0x53b02c0000000000, + 0x55402e9000000000, 0x55d02f0000000000, 0x56602e0000000000, + 0x56f02f9000000000, 0x5980289000000000, 0x5910290000000000, + 0x5aa0280000000000, 0x5a30299000000000, 0x5cc02b0000000000, + 0x5c502a9000000000, 0x5fe02b9000000000, 0x5f702a0000000000, + 0x6000360000000000, 0x6090379000000000, 0x6320369000000000, + 0x63b0370000000000, 0x6540359000000000, 0x65d0340000000000, + 0x6660350000000000, 0x66f0349000000000, 0x6980339000000000, + 0x6910320000000000, 0x6aa0330000000000, 0x6a30329000000000, + 0x6cc0300000000000, 0x6c50319000000000, 0x6fe0309000000000, + 0x6f70310000000000, 0x71003e9000000000, 0x71903f0000000000, + 0x72203e0000000000, 0x72b03f9000000000, 0x74403d0000000000, + 0x74d03c9000000000, 0x77603d9000000000, 0x77f03c0000000000, + 0x78803b0000000000, 0x78103a9000000000, 0x7ba03b9000000000, + 0x7b303a0000000000, 0x7dc0389000000000, 0x7d50390000000000, + 0x7ee0380000000000, 0x7e70399000000000, 0x8100499000000000, + 0x8190480000000000, 0x8220490000000000, 0x82b0489000000000, + 0x84404a0000000000, 0x84d04b9000000000, 0x87604a9000000000, + 0x87f04b0000000000, 0x88804c0000000000, 0x88104d9000000000, + 0x8ba04c9000000000, 0x8b304d0000000000, 0x8dc04f9000000000, + 0x8d504e0000000000, 0x8ee04f0000000000, 0x8e704e9000000000, + 0x9000410000000000, 0x9090409000000000, 0x9320419000000000, + 0x93b0400000000000, 0x9540429000000000, 0x95d0430000000000, + 0x9660420000000000, 0x96f0439000000000, 0x9980449000000000, + 0x9910450000000000, 0x9aa0440000000000, 0x9a30459000000000, + 0x9cc0470000000000, 0x9c50469000000000, 0x9fe0479000000000, + 0x9f70460000000000, 0xa0005a0000000000, 0xa0905b9000000000, + 0xa3205a9000000000, 0xa3b05b0000000000, 0xa540599000000000, + 0xa5d0580000000000, 0xa660590000000000, 0xa6f0589000000000, + 0xa9805f9000000000, 0xa9105e0000000000, 0xaaa05f0000000000, + 0xaa305e9000000000, 0xacc05c0000000000, 0xac505d9000000000, + 0xafe05c9000000000, 0xaf705d0000000000, 0xb100529000000000, + 0xb190530000000000, 0xb220520000000000, 0xb2b0539000000000, + 0xb440510000000000, 0xb4d0509000000000, 0xb760519000000000, + 0xb7f0500000000000, 0xb880570000000000, 0xb810569000000000, + 0xbba0579000000000, 0xbb30560000000000, 0xbdc0549000000000, + 0xbd50550000000000, 0xbee0540000000000, 0xbe70559000000000, + 0xc0006c0000000000, 0xc0906d9000000000, 0xc3206c9000000000, + 0xc3b06d0000000000, 0xc5406f9000000000, 0xc5d06e0000000000, + 0xc6606f0000000000, 0xc6f06e9000000000, 0xc980699000000000, + 0xc910680000000000, 0xcaa0690000000000, 0xca30689000000000, + 0xccc06a0000000000, 0xcc506b9000000000, 0xcfe06a9000000000, + 0xcf706b0000000000, 0xd100649000000000, 0xd190650000000000, + 0xd220640000000000, 0xd2b0659000000000, 0xd440670000000000, + 0xd4d0669000000000, 0xd760679000000000, 0xd7f0660000000000, + 0xd880610000000000, 0xd810609000000000, 0xdba0619000000000, + 0xdb30600000000000, 0xddc0629000000000, 0xdd50630000000000, + 0xdee0620000000000, 0xde70639000000000, 0xe1007f9000000000, + 0xe1907e0000000000, 0xe2207f0000000000, 0xe2b07e9000000000, + 0xe4407c0000000000, 0xe4d07d9000000000, 0xe7607c9000000000, + 0xe7f07d0000000000, 0xe8807a0000000000, 0xe8107b9000000000, + 0xeba07a9000000000, 0xeb307b0000000000, 0xedc0799000000000, + 0xed50780000000000, 0xeee0790000000000, 0xee70789000000000, + 0xf000770000000000, 0xf090769000000000, 0xf320779000000000, + 0xf3b0760000000000, 0xf540749000000000, 0xf5d0750000000000, + 0xf660740000000000, 0xf6f0759000000000, 0xf980729000000000, + 0xf910730000000000, 0xfaa0720000000000, 0xfa30739000000000, + 0xfcc0710000000000, 0xfc50709000000000, 0xffe0719000000000, + 0xff70700000000000}, + {0x0000000000000000, 0x9001900000000000, 0x2003200100000000, + 0xb002b00100000000, 0x4006400200000000, 0xd007d00200000000, + 0x6005600300000000, 0xf004f00300000000, 0x800c800400000000, + 0x100d100400000000, 0xa00fa00500000000, 0x300e300500000000, + 0xc00ac00600000000, 0x500b500600000000, 0xe009e00700000000, + 0x7008700700000000, 0x0019000900000000, 0x9018900900000000, + 0x201a200800000000, 0xb01bb00800000000, 0x401f400b00000000, + 0xd01ed00b00000000, 0x601c600a00000000, 0xf01df00a00000000, + 0x8015800d00000000, 0x1014100d00000000, 0xa016a00c00000000, + 0x3017300c00000000, 0xc013c00f00000000, 0x5012500f00000000, + 0xe010e00e00000000, 0x7011700e00000000, 0x0032001200000000, + 0x9033901200000000, 0x2031201300000000, 0xb030b01300000000, + 0x4034401000000000, 0xd035d01000000000, 0x6037601100000000, + 0xf036f01100000000, 0x803e801600000000, 0x103f101600000000, + 0xa03da01700000000, 0x303c301700000000, 0xc038c01400000000, + 0x5039501400000000, 0xe03be01500000000, 0x703a701500000000, + 0x002b001b00000000, 0x902a901b00000000, 0x2028201a00000000, + 0xb029b01a00000000, 0x402d401900000000, 0xd02cd01900000000, + 0x602e601800000000, 0xf02ff01800000000, 0x8027801f00000000, + 0x1026101f00000000, 0xa024a01e00000000, 0x3025301e00000000, + 0xc021c01d00000000, 0x5020501d00000000, 0xe022e01c00000000, + 0x7023701c00000000, 0x0064002400000000, 0x9065902400000000, + 0x2067202500000000, 0xb066b02500000000, 0x4062402600000000, + 0xd063d02600000000, 0x6061602700000000, 0xf060f02700000000, + 0x8068802000000000, 0x1069102000000000, 0xa06ba02100000000, + 0x306a302100000000, 0xc06ec02200000000, 0x506f502200000000, + 0xe06de02300000000, 0x706c702300000000, 0x007d002d00000000, + 0x907c902d00000000, 0x207e202c00000000, 0xb07fb02c00000000, + 0x407b402f00000000, 0xd07ad02f00000000, 0x6078602e00000000, + 0xf079f02e00000000, 0x8071802900000000, 0x1070102900000000, + 0xa072a02800000000, 0x3073302800000000, 0xc077c02b00000000, + 0x5076502b00000000, 0xe074e02a00000000, 0x7075702a00000000, + 0x0056003600000000, 0x9057903600000000, 0x2055203700000000, + 0xb054b03700000000, 0x4050403400000000, 0xd051d03400000000, + 0x6053603500000000, 0xf052f03500000000, 0x805a803200000000, + 0x105b103200000000, 0xa059a03300000000, 0x3058303300000000, + 0xc05cc03000000000, 0x505d503000000000, 0xe05fe03100000000, + 0x705e703100000000, 0x004f003f00000000, 0x904e903f00000000, + 0x204c203e00000000, 0xb04db03e00000000, 0x4049403d00000000, + 0xd048d03d00000000, 0x604a603c00000000, 0xf04bf03c00000000, + 0x8043803b00000000, 0x1042103b00000000, 0xa040a03a00000000, + 0x3041303a00000000, 0xc045c03900000000, 0x5044503900000000, + 0xe046e03800000000, 0x7047703800000000, 0x00c8004800000000, + 0x90c9904800000000, 0x20cb204900000000, 0xb0cab04900000000, + 0x40ce404a00000000, 0xd0cfd04a00000000, 0x60cd604b00000000, + 0xf0ccf04b00000000, 0x80c4804c00000000, 0x10c5104c00000000, + 0xa0c7a04d00000000, 0x30c6304d00000000, 0xc0c2c04e00000000, + 0x50c3504e00000000, 0xe0c1e04f00000000, 0x70c0704f00000000, + 0x00d1004100000000, 0x90d0904100000000, 0x20d2204000000000, + 0xb0d3b04000000000, 0x40d7404300000000, 0xd0d6d04300000000, + 0x60d4604200000000, 0xf0d5f04200000000, 0x80dd804500000000, + 0x10dc104500000000, 0xa0dea04400000000, 0x30df304400000000, + 0xc0dbc04700000000, 0x50da504700000000, 0xe0d8e04600000000, + 0x70d9704600000000, 0x00fa005a00000000, 0x90fb905a00000000, + 0x20f9205b00000000, 0xb0f8b05b00000000, 0x40fc405800000000, + 0xd0fdd05800000000, 0x60ff605900000000, 0xf0fef05900000000, + 0x80f6805e00000000, 0x10f7105e00000000, 0xa0f5a05f00000000, + 0x30f4305f00000000, 0xc0f0c05c00000000, 0x50f1505c00000000, + 0xe0f3e05d00000000, 0x70f2705d00000000, 0x00e3005300000000, + 0x90e2905300000000, 0x20e0205200000000, 0xb0e1b05200000000, + 0x40e5405100000000, 0xd0e4d05100000000, 0x60e6605000000000, + 0xf0e7f05000000000, 0x80ef805700000000, 0x10ee105700000000, + 0xa0eca05600000000, 0x30ed305600000000, 0xc0e9c05500000000, + 0x50e8505500000000, 0xe0eae05400000000, 0x70eb705400000000, + 0x00ac006c00000000, 0x90ad906c00000000, 0x20af206d00000000, + 0xb0aeb06d00000000, 0x40aa406e00000000, 0xd0abd06e00000000, + 0x60a9606f00000000, 0xf0a8f06f00000000, 0x80a0806800000000, + 0x10a1106800000000, 0xa0a3a06900000000, 0x30a2306900000000, + 0xc0a6c06a00000000, 0x50a7506a00000000, 0xe0a5e06b00000000, + 0x70a4706b00000000, 0x00b5006500000000, 0x90b4906500000000, + 0x20b6206400000000, 0xb0b7b06400000000, 0x40b3406700000000, + 0xd0b2d06700000000, 0x60b0606600000000, 0xf0b1f06600000000, + 0x80b9806100000000, 0x10b8106100000000, 0xa0baa06000000000, + 0x30bb306000000000, 0xc0bfc06300000000, 0x50be506300000000, + 0xe0bce06200000000, 0x70bd706200000000, 0x009e007e00000000, + 0x909f907e00000000, 0x209d207f00000000, 0xb09cb07f00000000, + 0x4098407c00000000, 0xd099d07c00000000, 0x609b607d00000000, + 0xf09af07d00000000, 0x8092807a00000000, 0x1093107a00000000, + 0xa091a07b00000000, 0x3090307b00000000, 0xc094c07800000000, + 0x5095507800000000, 0xe097e07900000000, 0x7096707900000000, + 0x0087007700000000, 0x9086907700000000, 0x2084207600000000, + 0xb085b07600000000, 0x4081407500000000, 0xd080d07500000000, + 0x6082607400000000, 0xf083f07400000000, 0x808b807300000000, + 0x108a107300000000, 0xa088a07200000000, 0x3089307200000000, + 0xc08dc07100000000, 0x508c507100000000, 0xe08ee07000000000, + 0x708f707000000000}, + {0x0000000000000000, 0x0100004100000000, 0x0200008200000000, + 0x030000c300000000, 0x070003b400000000, 0x060003f500000000, + 0x0500033600000000, 0x0400037700000000, 0x0d0005d800000000, + 0x0c00059900000000, 0x0f00055a00000000, 0x0e00051b00000000, + 0x0a00066c00000000, 0x0b00062d00000000, 0x080006ee00000000, + 0x090006af00000000, 0x1900090000000000, 0x1800094100000000, + 0x1b00098200000000, 0x1a0009c300000000, 0x1e000ab400000000, + 0x1f000af500000000, 0x1c000a3600000000, 0x1d000a7700000000, + 0x14000cd800000000, 0x15000c9900000000, 0x16000c5a00000000, + 0x17000c1b00000000, 0x13000f6c00000000, 0x12000f2d00000000, + 0x11000fee00000000, 0x10000faf00000000, 0x3200120000000000, + 0x3300124100000000, 0x3000128200000000, 0x310012c300000000, + 0x350011b400000000, 0x340011f500000000, 0x3700113600000000, + 0x3600117700000000, 0x3f0017d800000000, 0x3e00179900000000, + 0x3d00175a00000000, 0x3c00171b00000000, 0x3800146c00000000, + 0x3900142d00000000, 0x3a0014ee00000000, 0x3b0014af00000000, + 0x2b001b0000000000, 0x2a001b4100000000, 0x29001b8200000000, + 0x28001bc300000000, 0x2c0018b400000000, 0x2d0018f500000000, + 0x2e00183600000000, 0x2f00187700000000, 0x26001ed800000000, + 0x27001e9900000000, 0x24001e5a00000000, 0x25001e1b00000000, + 0x21001d6c00000000, 0x20001d2d00000000, 0x23001dee00000000, + 0x22001daf00000000, 0x6400240000000000, 0x6500244100000000, + 0x6600248200000000, 0x670024c300000000, 0x630027b400000000, + 0x620027f500000000, 0x6100273600000000, 0x6000277700000000, + 0x690021d800000000, 0x6800219900000000, 0x6b00215a00000000, + 0x6a00211b00000000, 0x6e00226c00000000, 0x6f00222d00000000, + 0x6c0022ee00000000, 0x6d0022af00000000, 0x7d002d0000000000, + 0x7c002d4100000000, 0x7f002d8200000000, 0x7e002dc300000000, + 0x7a002eb400000000, 0x7b002ef500000000, 0x78002e3600000000, + 0x79002e7700000000, 0x700028d800000000, 0x7100289900000000, + 0x7200285a00000000, 0x7300281b00000000, 0x77002b6c00000000, + 0x76002b2d00000000, 0x75002bee00000000, 0x74002baf00000000, + 0x5600360000000000, 0x5700364100000000, 0x5400368200000000, + 0x550036c300000000, 0x510035b400000000, 0x500035f500000000, + 0x5300353600000000, 0x5200357700000000, 0x5b0033d800000000, + 0x5a00339900000000, 0x5900335a00000000, 0x5800331b00000000, + 0x5c00306c00000000, 0x5d00302d00000000, 0x5e0030ee00000000, + 0x5f0030af00000000, 0x4f003f0000000000, 0x4e003f4100000000, + 0x4d003f8200000000, 0x4c003fc300000000, 0x48003cb400000000, + 0x49003cf500000000, 0x4a003c3600000000, 0x4b003c7700000000, + 0x42003ad800000000, 0x43003a9900000000, 0x40003a5a00000000, + 0x41003a1b00000000, 0x4500396c00000000, 0x4400392d00000000, + 0x470039ee00000000, 0x460039af00000000, 0xc800480000000000, + 0xc900484100000000, 0xca00488200000000, 0xcb0048c300000000, + 0xcf004bb400000000, 0xce004bf500000000, 0xcd004b3600000000, + 0xcc004b7700000000, 0xc5004dd800000000, 0xc4004d9900000000, + 0xc7004d5a00000000, 0xc6004d1b00000000, 0xc2004e6c00000000, + 0xc3004e2d00000000, 0xc0004eee00000000, 0xc1004eaf00000000, + 0xd100410000000000, 0xd000414100000000, 0xd300418200000000, + 0xd20041c300000000, 0xd60042b400000000, 0xd70042f500000000, + 0xd400423600000000, 0xd500427700000000, 0xdc0044d800000000, + 0xdd00449900000000, 0xde00445a00000000, 0xdf00441b00000000, + 0xdb00476c00000000, 0xda00472d00000000, 0xd90047ee00000000, + 0xd80047af00000000, 0xfa005a0000000000, 0xfb005a4100000000, + 0xf8005a8200000000, 0xf9005ac300000000, 0xfd0059b400000000, + 0xfc0059f500000000, 0xff00593600000000, 0xfe00597700000000, + 0xf7005fd800000000, 0xf6005f9900000000, 0xf5005f5a00000000, + 0xf4005f1b00000000, 0xf0005c6c00000000, 0xf1005c2d00000000, + 0xf2005cee00000000, 0xf3005caf00000000, 0xe300530000000000, + 0xe200534100000000, 0xe100538200000000, 0xe00053c300000000, + 0xe40050b400000000, 0xe50050f500000000, 0xe600503600000000, + 0xe700507700000000, 0xee0056d800000000, 0xef00569900000000, + 0xec00565a00000000, 0xed00561b00000000, 0xe900556c00000000, + 0xe800552d00000000, 0xeb0055ee00000000, 0xea0055af00000000, + 0xac006c0000000000, 0xad006c4100000000, 0xae006c8200000000, + 0xaf006cc300000000, 0xab006fb400000000, 0xaa006ff500000000, + 0xa9006f3600000000, 0xa8006f7700000000, 0xa10069d800000000, + 0xa000699900000000, 0xa300695a00000000, 0xa200691b00000000, + 0xa6006a6c00000000, 0xa7006a2d00000000, 0xa4006aee00000000, + 0xa5006aaf00000000, 0xb500650000000000, 0xb400654100000000, + 0xb700658200000000, 0xb60065c300000000, 0xb20066b400000000, + 0xb30066f500000000, 0xb000663600000000, 0xb100667700000000, + 0xb80060d800000000, 0xb900609900000000, 0xba00605a00000000, + 0xbb00601b00000000, 0xbf00636c00000000, 0xbe00632d00000000, + 0xbd0063ee00000000, 0xbc0063af00000000, 0x9e007e0000000000, + 0x9f007e4100000000, 0x9c007e8200000000, 0x9d007ec300000000, + 0x99007db400000000, 0x98007df500000000, 0x9b007d3600000000, + 0x9a007d7700000000, 0x93007bd800000000, 0x92007b9900000000, + 0x91007b5a00000000, 0x90007b1b00000000, 0x9400786c00000000, + 0x9500782d00000000, 0x960078ee00000000, 0x970078af00000000, + 0x8700770000000000, 0x8600774100000000, 0x8500778200000000, + 0x840077c300000000, 0x800074b400000000, 0x810074f500000000, + 0x8200743600000000, 0x8300747700000000, 0x8a0072d800000000, + 0x8b00729900000000, 0x8800725a00000000, 0x8900721b00000000, + 0x8d00716c00000000, 0x8c00712d00000000, 0x8f0071ee00000000, + 0x8e0071af00000000}, + {0x0000000000000000, 0x0101d09000000000, 0x0102a39100000000, + 0x0003730100000000, 0x0104459300000000, 0x0005950300000000, + 0x0006e60200000000, 0x0107369200000000, 0x0108899600000000, + 0x0009590600000000, 0x000a2a0700000000, 0x010bfa9700000000, + 0x000ccc0500000000, 0x010d1c9500000000, 0x010e6f9400000000, + 0x000fbf0400000000, 0x0110119d00000000, 0x0011c10d00000000, + 0x0012b20c00000000, 0x0113629c00000000, 0x0014540e00000000, + 0x0115849e00000000, 0x0116f79f00000000, 0x0017270f00000000, + 0x0018980b00000000, 0x0119489b00000000, 0x011a3b9a00000000, + 0x001beb0a00000000, 0x011cdd9800000000, 0x001d0d0800000000, + 0x001e7e0900000000, 0x011fae9900000000, 0x0120218a00000000, + 0x0021f11a00000000, 0x0022821b00000000, 0x0123528b00000000, + 0x0024641900000000, 0x0125b48900000000, 0x0126c78800000000, + 0x0027171800000000, 0x0028a81c00000000, 0x0129788c00000000, + 0x012a0b8d00000000, 0x002bdb1d00000000, 0x012ced8f00000000, + 0x002d3d1f00000000, 0x002e4e1e00000000, 0x012f9e8e00000000, + 0x0030301700000000, 0x0131e08700000000, 0x0132938600000000, + 0x0033431600000000, 0x0134758400000000, 0x0035a51400000000, + 0x0036d61500000000, 0x0137068500000000, 0x0138b98100000000, + 0x0039691100000000, 0x003a1a1000000000, 0x013bca8000000000, + 0x003cfc1200000000, 0x013d2c8200000000, 0x013e5f8300000000, + 0x003f8f1300000000, 0x014041a400000000, 0x0041913400000000, + 0x0042e23500000000, 0x014332a500000000, 0x0044043700000000, + 0x0145d4a700000000, 0x0146a7a600000000, 0x0047773600000000, + 0x0048c83200000000, 0x014918a200000000, 0x014a6ba300000000, + 0x004bbb3300000000, 0x014c8da100000000, 0x004d5d3100000000, + 0x004e2e3000000000, 0x014ffea000000000, 0x0050503900000000, + 0x015180a900000000, 0x0152f3a800000000, 0x0053233800000000, + 0x015415aa00000000, 0x0055c53a00000000, 0x0056b63b00000000, + 0x015766ab00000000, 0x0158d9af00000000, 0x0059093f00000000, + 0x005a7a3e00000000, 0x015baaae00000000, 0x005c9c3c00000000, + 0x015d4cac00000000, 0x015e3fad00000000, 0x005fef3d00000000, + 0x0060602e00000000, 0x0161b0be00000000, 0x0162c3bf00000000, + 0x0063132f00000000, 0x016425bd00000000, 0x0065f52d00000000, + 0x0066862c00000000, 0x016756bc00000000, 0x0168e9b800000000, + 0x0069392800000000, 0x006a4a2900000000, 0x016b9ab900000000, + 0x006cac2b00000000, 0x016d7cbb00000000, 0x016e0fba00000000, + 0x006fdf2a00000000, 0x017071b300000000, 0x0071a12300000000, + 0x0072d22200000000, 0x017302b200000000, 0x0074342000000000, + 0x0175e4b000000000, 0x017697b100000000, 0x0077472100000000, + 0x0078f82500000000, 0x017928b500000000, 0x017a5bb400000000, + 0x007b8b2400000000, 0x017cbdb600000000, 0x007d6d2600000000, + 0x007e1e2700000000, 0x017fceb700000000, 0x018081f800000000, + 0x0081516800000000, 0x0082226900000000, 0x0183f2f900000000, + 0x0084c46b00000000, 0x018514fb00000000, 0x018667fa00000000, + 0x0087b76a00000000, 0x0088086e00000000, 0x0189d8fe00000000, + 0x018aabff00000000, 0x008b7b6f00000000, 0x018c4dfd00000000, + 0x008d9d6d00000000, 0x008eee6c00000000, 0x018f3efc00000000, + 0x0090906500000000, 0x019140f500000000, 0x019233f400000000, + 0x0093e36400000000, 0x0194d5f600000000, 0x0095056600000000, + 0x0096766700000000, 0x0197a6f700000000, 0x019819f300000000, + 0x0099c96300000000, 0x009aba6200000000, 0x019b6af200000000, + 0x009c5c6000000000, 0x019d8cf000000000, 0x019efff100000000, + 0x009f2f6100000000, 0x00a0a07200000000, 0x01a170e200000000, + 0x01a203e300000000, 0x00a3d37300000000, 0x01a4e5e100000000, + 0x00a5357100000000, 0x00a6467000000000, 0x01a796e000000000, + 0x01a829e400000000, 0x00a9f97400000000, 0x00aa8a7500000000, + 0x01ab5ae500000000, 0x00ac6c7700000000, 0x01adbce700000000, + 0x01aecfe600000000, 0x00af1f7600000000, 0x01b0b1ef00000000, + 0x00b1617f00000000, 0x00b2127e00000000, 0x01b3c2ee00000000, + 0x00b4f47c00000000, 0x01b524ec00000000, 0x01b657ed00000000, + 0x00b7877d00000000, 0x00b8387900000000, 0x01b9e8e900000000, + 0x01ba9be800000000, 0x00bb4b7800000000, 0x01bc7dea00000000, + 0x00bdad7a00000000, 0x00bede7b00000000, 0x01bf0eeb00000000, + 0x00c0c05c00000000, 0x01c110cc00000000, 0x01c263cd00000000, + 0x00c3b35d00000000, 0x01c485cf00000000, 0x00c5555f00000000, + 0x00c6265e00000000, 0x01c7f6ce00000000, 0x01c849ca00000000, + 0x00c9995a00000000, 0x00caea5b00000000, 0x01cb3acb00000000, + 0x00cc0c5900000000, 0x01cddcc900000000, 0x01ceafc800000000, + 0x00cf7f5800000000, 0x01d0d1c100000000, 0x00d1015100000000, + 0x00d2725000000000, 0x01d3a2c000000000, 0x00d4945200000000, + 0x01d544c200000000, 0x01d637c300000000, 0x00d7e75300000000, + 0x00d8585700000000, 0x01d988c700000000, 0x01dafbc600000000, + 0x00db2b5600000000, 0x01dc1dc400000000, 0x00ddcd5400000000, + 0x00debe5500000000, 0x01df6ec500000000, 0x01e0e1d600000000, + 0x00e1314600000000, 0x00e2424700000000, 0x01e392d700000000, + 0x00e4a44500000000, 0x01e574d500000000, 0x01e607d400000000, + 0x00e7d74400000000, 0x00e8684000000000, 0x01e9b8d000000000, + 0x01eacbd100000000, 0x00eb1b4100000000, 0x01ec2dd300000000, + 0x00edfd4300000000, 0x00ee8e4200000000, 0x01ef5ed200000000, + 0x00f0f04b00000000, 0x01f120db00000000, 0x01f253da00000000, + 0x00f3834a00000000, 0x01f4b5d800000000, 0x00f5654800000000, + 0x00f6164900000000, 0x01f7c6d900000000, 0x01f879dd00000000, + 0x00f9a94d00000000, 0x00fada4c00000000, 0x01fb0adc00000000, + 0x00fc3c4e00000000, 0x01fdecde00000000, 0x01fe9fdf00000000, + 0x00ff4f4f00000000}, + {0x0000000000000000, 0x00d1019000000000, 0x03a2009000000000, + 0x0373010000000000, 0x0544029000000000, 0x0595030000000000, + 0x06e6020000000000, 0x0637039000000000, 0x0988079000000000, + 0x0959060000000000, 0x0a2a070000000000, 0x0afb069000000000, + 0x0ccc050000000000, 0x0c1d049000000000, 0x0f6e059000000000, + 0x0fbf040000000000, 0x11100c9000000000, 0x11c10d0000000000, + 0x12b20c0000000000, 0x12630d9000000000, 0x14540e0000000000, + 0x14850f9000000000, 0x17f60e9000000000, 0x17270f0000000000, + 0x18980b0000000000, 0x18490a9000000000, 0x1b3a0b9000000000, + 0x1beb0a0000000000, 0x1ddc099000000000, 0x1d0d080000000000, + 0x1e7e090000000000, 0x1eaf089000000000, 0x21201b9000000000, + 0x21f11a0000000000, 0x22821b0000000000, 0x22531a9000000000, + 0x2464190000000000, 0x24b5189000000000, 0x27c6199000000000, + 0x2717180000000000, 0x28a81c0000000000, 0x28791d9000000000, + 0x2b0a1c9000000000, 0x2bdb1d0000000000, 0x2dec1e9000000000, + 0x2d3d1f0000000000, 0x2e4e1e0000000000, 0x2e9f1f9000000000, + 0x3030170000000000, 0x30e1169000000000, 0x3392179000000000, + 0x3343160000000000, 0x3574159000000000, 0x35a5140000000000, + 0x36d6150000000000, 0x3607149000000000, 0x39b8109000000000, + 0x3969110000000000, 0x3a1a100000000000, 0x3acb119000000000, + 0x3cfc120000000000, 0x3c2d139000000000, 0x3f5e129000000000, + 0x3f8f130000000000, 0x4140359000000000, 0x4191340000000000, + 0x42e2350000000000, 0x4233349000000000, 0x4404370000000000, + 0x44d5369000000000, 0x47a6379000000000, 0x4777360000000000, + 0x48c8320000000000, 0x4819339000000000, 0x4b6a329000000000, + 0x4bbb330000000000, 0x4d8c309000000000, 0x4d5d310000000000, + 0x4e2e300000000000, 0x4eff319000000000, 0x5050390000000000, + 0x5081389000000000, 0x53f2399000000000, 0x5323380000000000, + 0x55143b9000000000, 0x55c53a0000000000, 0x56b63b0000000000, + 0x56673a9000000000, 0x59d83e9000000000, 0x59093f0000000000, + 0x5a7a3e0000000000, 0x5aab3f9000000000, 0x5c9c3c0000000000, + 0x5c4d3d9000000000, 0x5f3e3c9000000000, 0x5fef3d0000000000, + 0x60602e0000000000, 0x60b12f9000000000, 0x63c22e9000000000, + 0x63132f0000000000, 0x65242c9000000000, 0x65f52d0000000000, + 0x66862c0000000000, 0x66572d9000000000, 0x69e8299000000000, + 0x6939280000000000, 0x6a4a290000000000, 0x6a9b289000000000, + 0x6cac2b0000000000, 0x6c7d2a9000000000, 0x6f0e2b9000000000, + 0x6fdf2a0000000000, 0x7170229000000000, 0x71a1230000000000, + 0x72d2220000000000, 0x7203239000000000, 0x7434200000000000, + 0x74e5219000000000, 0x7796209000000000, 0x7747210000000000, + 0x78f8250000000000, 0x7829249000000000, 0x7b5a259000000000, + 0x7b8b240000000000, 0x7dbc279000000000, 0x7d6d260000000000, + 0x7e1e270000000000, 0x7ecf269000000000, 0x8180699000000000, + 0x8151680000000000, 0x8222690000000000, 0x82f3689000000000, + 0x84c46b0000000000, 0x84156a9000000000, 0x87666b9000000000, + 0x87b76a0000000000, 0x88086e0000000000, 0x88d96f9000000000, + 0x8baa6e9000000000, 0x8b7b6f0000000000, 0x8d4c6c9000000000, + 0x8d9d6d0000000000, 0x8eee6c0000000000, 0x8e3f6d9000000000, + 0x9090650000000000, 0x9041649000000000, 0x9332659000000000, + 0x93e3640000000000, 0x95d4679000000000, 0x9505660000000000, + 0x9676670000000000, 0x96a7669000000000, 0x9918629000000000, + 0x99c9630000000000, 0x9aba620000000000, 0x9a6b639000000000, + 0x9c5c600000000000, 0x9c8d619000000000, 0x9ffe609000000000, + 0x9f2f610000000000, 0xa0a0720000000000, 0xa071739000000000, + 0xa302729000000000, 0xa3d3730000000000, 0xa5e4709000000000, + 0xa535710000000000, 0xa646700000000000, 0xa697719000000000, + 0xa928759000000000, 0xa9f9740000000000, 0xaa8a750000000000, + 0xaa5b749000000000, 0xac6c770000000000, 0xacbd769000000000, + 0xafce779000000000, 0xaf1f760000000000, 0xb1b07e9000000000, + 0xb1617f0000000000, 0xb2127e0000000000, 0xb2c37f9000000000, + 0xb4f47c0000000000, 0xb4257d9000000000, 0xb7567c9000000000, + 0xb7877d0000000000, 0xb838790000000000, 0xb8e9789000000000, + 0xbb9a799000000000, 0xbb4b780000000000, 0xbd7c7b9000000000, + 0xbdad7a0000000000, 0xbede7b0000000000, 0xbe0f7a9000000000, + 0xc0c05c0000000000, 0xc0115d9000000000, 0xc3625c9000000000, + 0xc3b35d0000000000, 0xc5845e9000000000, 0xc5555f0000000000, + 0xc6265e0000000000, 0xc6f75f9000000000, 0xc9485b9000000000, + 0xc9995a0000000000, 0xcaea5b0000000000, 0xca3b5a9000000000, + 0xcc0c590000000000, 0xccdd589000000000, 0xcfae599000000000, + 0xcf7f580000000000, 0xd1d0509000000000, 0xd101510000000000, + 0xd272500000000000, 0xd2a3519000000000, 0xd494520000000000, + 0xd445539000000000, 0xd736529000000000, 0xd7e7530000000000, + 0xd858570000000000, 0xd889569000000000, 0xdbfa579000000000, + 0xdb2b560000000000, 0xdd1c559000000000, 0xddcd540000000000, + 0xdebe550000000000, 0xde6f549000000000, 0xe1e0479000000000, + 0xe131460000000000, 0xe242470000000000, 0xe293469000000000, + 0xe4a4450000000000, 0xe475449000000000, 0xe706459000000000, + 0xe7d7440000000000, 0xe868400000000000, 0xe8b9419000000000, + 0xebca409000000000, 0xeb1b410000000000, 0xed2c429000000000, + 0xedfd430000000000, 0xee8e420000000000, 0xee5f439000000000, + 0xf0f04b0000000000, 0xf0214a9000000000, 0xf3524b9000000000, + 0xf3834a0000000000, 0xf5b4499000000000, 0xf565480000000000, + 0xf616490000000000, 0xf6c7489000000000, 0xf9784c9000000000, + 0xf9a94d0000000000, 0xfada4c0000000000, 0xfa0b4d9000000000, + 0xfc3c4e0000000000, 0xfced4f9000000000, 0xff9e4e9000000000, + 0xff4f4f0000000000}, + {0x0000000000000000, 0xd101900000000000, 0xa203200100000000, + 0x7302b00100000000, 0x4407400200000000, 0x9506d00200000000, + 0xe604600300000000, 0x3705f00300000000, 0x880e800400000000, + 0x590f100400000000, 0x2a0da00500000000, 0xfb0c300500000000, + 0xcc09c00600000000, 0x1d08500600000000, 0x6e0ae00700000000, + 0xbf0b700700000000, 0x101d000900000000, 0xc11c900900000000, + 0xb21e200800000000, 0x631fb00800000000, 0x541a400b00000000, + 0x851bd00b00000000, 0xf619600a00000000, 0x2718f00a00000000, + 0x9813800d00000000, 0x4912100d00000000, 0x3a10a00c00000000, + 0xeb11300c00000000, 0xdc14c00f00000000, 0x0d15500f00000000, + 0x7e17e00e00000000, 0xaf16700e00000000, 0x203a001200000000, + 0xf13b901200000000, 0x8239201300000000, 0x5338b01300000000, + 0x643d401000000000, 0xb53cd01000000000, 0xc63e601100000000, + 0x173ff01100000000, 0xa834801600000000, 0x7935101600000000, + 0x0a37a01700000000, 0xdb36301700000000, 0xec33c01400000000, + 0x3d32501400000000, 0x4e30e01500000000, 0x9f31701500000000, + 0x3027001b00000000, 0xe126901b00000000, 0x9224201a00000000, + 0x4325b01a00000000, 0x7420401900000000, 0xa521d01900000000, + 0xd623601800000000, 0x0722f01800000000, 0xb829801f00000000, + 0x6928101f00000000, 0x1a2aa01e00000000, 0xcb2b301e00000000, + 0xfc2ec01d00000000, 0x2d2f501d00000000, 0x5e2de01c00000000, + 0x8f2c701c00000000, 0x4074002400000000, 0x9175902400000000, + 0xe277202500000000, 0x3376b02500000000, 0x0473402600000000, + 0xd572d02600000000, 0xa670602700000000, 0x7771f02700000000, + 0xc87a802000000000, 0x197b102000000000, 0x6a79a02100000000, + 0xbb78302100000000, 0x8c7dc02200000000, 0x5d7c502200000000, + 0x2e7ee02300000000, 0xff7f702300000000, 0x5069002d00000000, + 0x8168902d00000000, 0xf26a202c00000000, 0x236bb02c00000000, + 0x146e402f00000000, 0xc56fd02f00000000, 0xb66d602e00000000, + 0x676cf02e00000000, 0xd867802900000000, 0x0966102900000000, + 0x7a64a02800000000, 0xab65302800000000, 0x9c60c02b00000000, + 0x4d61502b00000000, 0x3e63e02a00000000, 0xef62702a00000000, + 0x604e003600000000, 0xb14f903600000000, 0xc24d203700000000, + 0x134cb03700000000, 0x2449403400000000, 0xf548d03400000000, + 0x864a603500000000, 0x574bf03500000000, 0xe840803200000000, + 0x3941103200000000, 0x4a43a03300000000, 0x9b42303300000000, + 0xac47c03000000000, 0x7d46503000000000, 0x0e44e03100000000, + 0xdf45703100000000, 0x7053003f00000000, 0xa152903f00000000, + 0xd250203e00000000, 0x0351b03e00000000, 0x3454403d00000000, + 0xe555d03d00000000, 0x9657603c00000000, 0x4756f03c00000000, + 0xf85d803b00000000, 0x295c103b00000000, 0x5a5ea03a00000000, + 0x8b5f303a00000000, 0xbc5ac03900000000, 0x6d5b503900000000, + 0x1e59e03800000000, 0xcf58703800000000, 0x80e8004800000000, + 0x51e9904800000000, 0x22eb204900000000, 0xf3eab04900000000, + 0xc4ef404a00000000, 0x15eed04a00000000, 0x66ec604b00000000, + 0xb7edf04b00000000, 0x08e6804c00000000, 0xd9e7104c00000000, + 0xaae5a04d00000000, 0x7be4304d00000000, 0x4ce1c04e00000000, + 0x9de0504e00000000, 0xeee2e04f00000000, 0x3fe3704f00000000, + 0x90f5004100000000, 0x41f4904100000000, 0x32f6204000000000, + 0xe3f7b04000000000, 0xd4f2404300000000, 0x05f3d04300000000, + 0x76f1604200000000, 0xa7f0f04200000000, 0x18fb804500000000, + 0xc9fa104500000000, 0xbaf8a04400000000, 0x6bf9304400000000, + 0x5cfcc04700000000, 0x8dfd504700000000, 0xfeffe04600000000, + 0x2ffe704600000000, 0xa0d2005a00000000, 0x71d3905a00000000, + 0x02d1205b00000000, 0xd3d0b05b00000000, 0xe4d5405800000000, + 0x35d4d05800000000, 0x46d6605900000000, 0x97d7f05900000000, + 0x28dc805e00000000, 0xf9dd105e00000000, 0x8adfa05f00000000, + 0x5bde305f00000000, 0x6cdbc05c00000000, 0xbdda505c00000000, + 0xced8e05d00000000, 0x1fd9705d00000000, 0xb0cf005300000000, + 0x61ce905300000000, 0x12cc205200000000, 0xc3cdb05200000000, + 0xf4c8405100000000, 0x25c9d05100000000, 0x56cb605000000000, + 0x87caf05000000000, 0x38c1805700000000, 0xe9c0105700000000, + 0x9ac2a05600000000, 0x4bc3305600000000, 0x7cc6c05500000000, + 0xadc7505500000000, 0xdec5e05400000000, 0x0fc4705400000000, + 0xc09c006c00000000, 0x119d906c00000000, 0x629f206d00000000, + 0xb39eb06d00000000, 0x849b406e00000000, 0x559ad06e00000000, + 0x2698606f00000000, 0xf799f06f00000000, 0x4892806800000000, + 0x9993106800000000, 0xea91a06900000000, 0x3b90306900000000, + 0x0c95c06a00000000, 0xdd94506a00000000, 0xae96e06b00000000, + 0x7f97706b00000000, 0xd081006500000000, 0x0180906500000000, + 0x7282206400000000, 0xa383b06400000000, 0x9486406700000000, + 0x4587d06700000000, 0x3685606600000000, 0xe784f06600000000, + 0x588f806100000000, 0x898e106100000000, 0xfa8ca06000000000, + 0x2b8d306000000000, 0x1c88c06300000000, 0xcd89506300000000, + 0xbe8be06200000000, 0x6f8a706200000000, 0xe0a6007e00000000, + 0x31a7907e00000000, 0x42a5207f00000000, 0x93a4b07f00000000, + 0xa4a1407c00000000, 0x75a0d07c00000000, 0x06a2607d00000000, + 0xd7a3f07d00000000, 0x68a8807a00000000, 0xb9a9107a00000000, + 0xcaaba07b00000000, 0x1baa307b00000000, 0x2cafc07800000000, + 0xfdae507800000000, 0x8eace07900000000, 0x5fad707900000000, + 0xf0bb007700000000, 0x21ba907700000000, 0x52b8207600000000, + 0x83b9b07600000000, 0xb4bc407500000000, 0x65bdd07500000000, + 0x16bf607400000000, 0xc7bef07400000000, 0x78b5807300000000, + 0xa9b4107300000000, 0xdab6a07200000000, 0x0bb7307200000000, + 0x3cb2c07100000000, 0xedb3507100000000, 0x9eb1e07000000000, + 0x4fb0707000000000}, + {0x0000000000000000, 0x0141906500000000, 0x028220cb00000000, + 0x03c3b0ae00000000, 0x0704422600000000, 0x0645d24300000000, + 0x058662ed00000000, 0x04c7f28800000000, 0x0e08844c00000000, + 0x0f49142900000000, 0x0c8aa48700000000, 0x0dcb34e200000000, + 0x090cc66a00000000, 0x084d560f00000000, 0x0b8ee6a100000000, + 0x0acf76c400000000, 0x1c10089900000000, 0x1d5198fc00000000, + 0x1e92285200000000, 0x1fd3b83700000000, 0x1b144abf00000000, + 0x1a55dada00000000, 0x19966a7400000000, 0x18d7fa1100000000, + 0x12188cd500000000, 0x13591cb000000000, 0x109aac1e00000000, + 0x11db3c7b00000000, 0x151ccef300000000, 0x145d5e9600000000, + 0x179eee3800000000, 0x16df7e5d00000000, 0x3b20138200000000, + 0x3a6183e700000000, 0x39a2334900000000, 0x38e3a32c00000000, + 0x3c2451a400000000, 0x3d65c1c100000000, 0x3ea6716f00000000, + 0x3fe7e10a00000000, 0x352897ce00000000, 0x346907ab00000000, + 0x37aab70500000000, 0x36eb276000000000, 0x322cd5e800000000, + 0x336d458d00000000, 0x30aef52300000000, 0x31ef654600000000, + 0x27301b1b00000000, 0x26718b7e00000000, 0x25b23bd000000000, + 0x24f3abb500000000, 0x2034593d00000000, 0x2175c95800000000, + 0x22b679f600000000, 0x23f7e99300000000, 0x29389f5700000000, + 0x28790f3200000000, 0x2bbabf9c00000000, 0x2afb2ff900000000, + 0x2e3cdd7100000000, 0x2f7d4d1400000000, 0x2cbefdba00000000, + 0x2dff6ddf00000000, 0x754025b400000000, 0x7401b5d100000000, + 0x77c2057f00000000, 0x7683951a00000000, 0x7244679200000000, + 0x7305f7f700000000, 0x70c6475900000000, 0x7187d73c00000000, + 0x7b48a1f800000000, 0x7a09319d00000000, 0x79ca813300000000, + 0x788b115600000000, 0x7c4ce3de00000000, 0x7d0d73bb00000000, + 0x7ecec31500000000, 0x7f8f537000000000, 0x69502d2d00000000, + 0x6811bd4800000000, 0x6bd20de600000000, 0x6a939d8300000000, + 0x6e546f0b00000000, 0x6f15ff6e00000000, 0x6cd64fc000000000, + 0x6d97dfa500000000, 0x6758a96100000000, 0x6619390400000000, + 0x65da89aa00000000, 0x649b19cf00000000, 0x605ceb4700000000, + 0x611d7b2200000000, 0x62decb8c00000000, 0x639f5be900000000, + 0x4e60363600000000, 0x4f21a65300000000, 0x4ce216fd00000000, + 0x4da3869800000000, 0x4964741000000000, 0x4825e47500000000, + 0x4be654db00000000, 0x4aa7c4be00000000, 0x4068b27a00000000, + 0x4129221f00000000, 0x42ea92b100000000, 0x43ab02d400000000, + 0x476cf05c00000000, 0x462d603900000000, 0x45eed09700000000, + 0x44af40f200000000, 0x52703eaf00000000, 0x5331aeca00000000, + 0x50f21e6400000000, 0x51b38e0100000000, 0x55747c8900000000, + 0x5435ecec00000000, 0x57f65c4200000000, 0x56b7cc2700000000, + 0x5c78bae300000000, 0x5d392a8600000000, 0x5efa9a2800000000, + 0x5fbb0a4d00000000, 0x5b7cf8c500000000, 0x5a3d68a000000000, + 0x59fed80e00000000, 0x58bf486b00000000, 0xe98049d800000000, + 0xe8c1d9bd00000000, 0xeb02691300000000, 0xea43f97600000000, + 0xee840bfe00000000, 0xefc59b9b00000000, 0xec062b3500000000, + 0xed47bb5000000000, 0xe788cd9400000000, 0xe6c95df100000000, + 0xe50aed5f00000000, 0xe44b7d3a00000000, 0xe08c8fb200000000, + 0xe1cd1fd700000000, 0xe20eaf7900000000, 0xe34f3f1c00000000, + 0xf590414100000000, 0xf4d1d12400000000, 0xf712618a00000000, + 0xf653f1ef00000000, 0xf294036700000000, 0xf3d5930200000000, + 0xf01623ac00000000, 0xf157b3c900000000, 0xfb98c50d00000000, + 0xfad9556800000000, 0xf91ae5c600000000, 0xf85b75a300000000, + 0xfc9c872b00000000, 0xfddd174e00000000, 0xfe1ea7e000000000, + 0xff5f378500000000, 0xd2a05a5a00000000, 0xd3e1ca3f00000000, + 0xd0227a9100000000, 0xd163eaf400000000, 0xd5a4187c00000000, + 0xd4e5881900000000, 0xd72638b700000000, 0xd667a8d200000000, + 0xdca8de1600000000, 0xdde94e7300000000, 0xde2afedd00000000, + 0xdf6b6eb800000000, 0xdbac9c3000000000, 0xdaed0c5500000000, + 0xd92ebcfb00000000, 0xd86f2c9e00000000, 0xceb052c300000000, + 0xcff1c2a600000000, 0xcc32720800000000, 0xcd73e26d00000000, + 0xc9b410e500000000, 0xc8f5808000000000, 0xcb36302e00000000, + 0xca77a04b00000000, 0xc0b8d68f00000000, 0xc1f946ea00000000, + 0xc23af64400000000, 0xc37b662100000000, 0xc7bc94a900000000, + 0xc6fd04cc00000000, 0xc53eb46200000000, 0xc47f240700000000, + 0x9cc06c6c00000000, 0x9d81fc0900000000, 0x9e424ca700000000, + 0x9f03dcc200000000, 0x9bc42e4a00000000, 0x9a85be2f00000000, + 0x99460e8100000000, 0x98079ee400000000, 0x92c8e82000000000, + 0x9389784500000000, 0x904ac8eb00000000, 0x910b588e00000000, + 0x95ccaa0600000000, 0x948d3a6300000000, 0x974e8acd00000000, + 0x960f1aa800000000, 0x80d064f500000000, 0x8191f49000000000, + 0x8252443e00000000, 0x8313d45b00000000, 0x87d426d300000000, + 0x8695b6b600000000, 0x8556061800000000, 0x8417967d00000000, + 0x8ed8e0b900000000, 0x8f9970dc00000000, 0x8c5ac07200000000, + 0x8d1b501700000000, 0x89dca29f00000000, 0x889d32fa00000000, + 0x8b5e825400000000, 0x8a1f123100000000, 0xa7e07fee00000000, + 0xa6a1ef8b00000000, 0xa5625f2500000000, 0xa423cf4000000000, + 0xa0e43dc800000000, 0xa1a5adad00000000, 0xa2661d0300000000, + 0xa3278d6600000000, 0xa9e8fba200000000, 0xa8a96bc700000000, + 0xab6adb6900000000, 0xaa2b4b0c00000000, 0xaeecb98400000000, + 0xafad29e100000000, 0xac6e994f00000000, 0xad2f092a00000000, + 0xbbf0777700000000, 0xbab1e71200000000, 0xb97257bc00000000, + 0xb833c7d900000000, 0xbcf4355100000000, 0xbdb5a53400000000, + 0xbe76159a00000000, 0xbf3785ff00000000, 0xb5f8f33b00000000, + 0xb4b9635e00000000, 0xb77ad3f000000000, 0xb63b439500000000, + 0xb2fcb11d00000000, 0xb3bd217800000000, 0xb07e91d600000000, + 0xb13f01b300000000}}; + +#else /* W == 4 */ + +static const crc_t crc_braid_table[][256] = { + {0x00000000, 0x41000001, 0x82000002, 0xc3000003, 0xb4030007, + 0xf5030006, 0x36030005, 0x77030004, 0xd805000d, 0x9905000c, + 0x5a05000f, 0x1b05000e, 0x6c06000a, 0x2d06000b, 0xee060008, + 0xaf060009, 0x00090019, 0x41090018, 0x8209001b, 0xc309001a, + 0xb40a001e, 0xf50a001f, 0x360a001c, 0x770a001d, 0xd80c0014, + 0x990c0015, 0x5a0c0016, 0x1b0c0017, 0x6c0f0013, 0x2d0f0012, + 0xee0f0011, 0xaf0f0010, 0x00120032, 0x41120033, 0x82120030, + 0xc3120031, 0xb4110035, 0xf5110034, 0x36110037, 0x77110036, + 0xd817003f, 0x9917003e, 0x5a17003d, 0x1b17003c, 0x6c140038, + 0x2d140039, 0xee14003a, 0xaf14003b, 0x001b002b, 0x411b002a, + 0x821b0029, 0xc31b0028, 0xb418002c, 0xf518002d, 0x3618002e, + 0x7718002f, 0xd81e0026, 0x991e0027, 0x5a1e0024, 0x1b1e0025, + 0x6c1d0021, 0x2d1d0020, 0xee1d0023, 0xaf1d0022, 0x00240064, + 0x41240065, 0x82240066, 0xc3240067, 0xb4270063, 0xf5270062, + 0x36270061, 0x77270060, 0xd8210069, 0x99210068, 0x5a21006b, + 0x1b21006a, 0x6c22006e, 0x2d22006f, 0xee22006c, 0xaf22006d, + 0x002d007d, 0x412d007c, 0x822d007f, 0xc32d007e, 0xb42e007a, + 0xf52e007b, 0x362e0078, 0x772e0079, 0xd8280070, 0x99280071, + 0x5a280072, 0x1b280073, 0x6c2b0077, 0x2d2b0076, 0xee2b0075, + 0xaf2b0074, 0x00360056, 0x41360057, 0x82360054, 0xc3360055, + 0xb4350051, 0xf5350050, 0x36350053, 0x77350052, 0xd833005b, + 0x9933005a, 0x5a330059, 0x1b330058, 0x6c30005c, 0x2d30005d, + 0xee30005e, 0xaf30005f, 0x003f004f, 0x413f004e, 0x823f004d, + 0xc33f004c, 0xb43c0048, 0xf53c0049, 0x363c004a, 0x773c004b, + 0xd83a0042, 0x993a0043, 0x5a3a0040, 0x1b3a0041, 0x6c390045, + 0x2d390044, 0xee390047, 0xaf390046, 0x004800c8, 0x414800c9, + 0x824800ca, 0xc34800cb, 0xb44b00cf, 0xf54b00ce, 0x364b00cd, + 0x774b00cc, 0xd84d00c5, 0x994d00c4, 0x5a4d00c7, 0x1b4d00c6, + 0x6c4e00c2, 0x2d4e00c3, 0xee4e00c0, 0xaf4e00c1, 0x004100d1, + 0x414100d0, 0x824100d3, 0xc34100d2, 0xb44200d6, 0xf54200d7, + 0x364200d4, 0x774200d5, 0xd84400dc, 0x994400dd, 0x5a4400de, + 0x1b4400df, 0x6c4700db, 0x2d4700da, 0xee4700d9, 0xaf4700d8, + 0x005a00fa, 0x415a00fb, 0x825a00f8, 0xc35a00f9, 0xb45900fd, + 0xf55900fc, 0x365900ff, 0x775900fe, 0xd85f00f7, 0x995f00f6, + 0x5a5f00f5, 0x1b5f00f4, 0x6c5c00f0, 0x2d5c00f1, 0xee5c00f2, + 0xaf5c00f3, 0x005300e3, 0x415300e2, 0x825300e1, 0xc35300e0, + 0xb45000e4, 0xf55000e5, 0x365000e6, 0x775000e7, 0xd85600ee, + 0x995600ef, 0x5a5600ec, 0x1b5600ed, 0x6c5500e9, 0x2d5500e8, + 0xee5500eb, 0xaf5500ea, 0x006c00ac, 0x416c00ad, 0x826c00ae, + 0xc36c00af, 0xb46f00ab, 0xf56f00aa, 0x366f00a9, 0x776f00a8, + 0xd86900a1, 0x996900a0, 0x5a6900a3, 0x1b6900a2, 0x6c6a00a6, + 0x2d6a00a7, 0xee6a00a4, 0xaf6a00a5, 0x006500b5, 0x416500b4, + 0x826500b7, 0xc36500b6, 0xb46600b2, 0xf56600b3, 0x366600b0, + 0x776600b1, 0xd86000b8, 0x996000b9, 0x5a6000ba, 0x1b6000bb, + 0x6c6300bf, 0x2d6300be, 0xee6300bd, 0xaf6300bc, 0x007e009e, + 0x417e009f, 0x827e009c, 0xc37e009d, 0xb47d0099, 0xf57d0098, + 0x367d009b, 0x777d009a, 0xd87b0093, 0x997b0092, 0x5a7b0091, + 0x1b7b0090, 0x6c780094, 0x2d780095, 0xee780096, 0xaf780097, + 0x00770087, 0x41770086, 0x82770085, 0xc3770084, 0xb4740080, + 0xf5740081, 0x36740082, 0x77740083, 0xd872008a, 0x9972008b, + 0x5a720088, 0x1b720089, 0x6c71008d, 0x2d71008c, 0xee71008f, + 0xaf71008e}, + {0x00000000, 0x00900190, 0x01200320, 0x01b002b0, 0x02400640, + 0x02d007d0, 0x03600560, 0x03f004f0, 0x04800c80, 0x04100d10, + 0x05a00fa0, 0x05300e30, 0x06c00ac0, 0x06500b50, 0x07e009e0, + 0x07700870, 0x09001900, 0x09901890, 0x08201a20, 0x08b01bb0, + 0x0b401f40, 0x0bd01ed0, 0x0a601c60, 0x0af01df0, 0x0d801580, + 0x0d101410, 0x0ca016a0, 0x0c301730, 0x0fc013c0, 0x0f501250, + 0x0ee010e0, 0x0e701170, 0x12003200, 0x12903390, 0x13203120, + 0x13b030b0, 0x10403440, 0x10d035d0, 0x11603760, 0x11f036f0, + 0x16803e80, 0x16103f10, 0x17a03da0, 0x17303c30, 0x14c038c0, + 0x14503950, 0x15e03be0, 0x15703a70, 0x1b002b00, 0x1b902a90, + 0x1a202820, 0x1ab029b0, 0x19402d40, 0x19d02cd0, 0x18602e60, + 0x18f02ff0, 0x1f802780, 0x1f102610, 0x1ea024a0, 0x1e302530, + 0x1dc021c0, 0x1d502050, 0x1ce022e0, 0x1c702370, 0x24006400, + 0x24906590, 0x25206720, 0x25b066b0, 0x26406240, 0x26d063d0, + 0x27606160, 0x27f060f0, 0x20806880, 0x20106910, 0x21a06ba0, + 0x21306a30, 0x22c06ec0, 0x22506f50, 0x23e06de0, 0x23706c70, + 0x2d007d00, 0x2d907c90, 0x2c207e20, 0x2cb07fb0, 0x2f407b40, + 0x2fd07ad0, 0x2e607860, 0x2ef079f0, 0x29807180, 0x29107010, + 0x28a072a0, 0x28307330, 0x2bc077c0, 0x2b507650, 0x2ae074e0, + 0x2a707570, 0x36005600, 0x36905790, 0x37205520, 0x37b054b0, + 0x34405040, 0x34d051d0, 0x35605360, 0x35f052f0, 0x32805a80, + 0x32105b10, 0x33a059a0, 0x33305830, 0x30c05cc0, 0x30505d50, + 0x31e05fe0, 0x31705e70, 0x3f004f00, 0x3f904e90, 0x3e204c20, + 0x3eb04db0, 0x3d404940, 0x3dd048d0, 0x3c604a60, 0x3cf04bf0, + 0x3b804380, 0x3b104210, 0x3aa040a0, 0x3a304130, 0x39c045c0, + 0x39504450, 0x38e046e0, 0x38704770, 0x4800c800, 0x4890c990, + 0x4920cb20, 0x49b0cab0, 0x4a40ce40, 0x4ad0cfd0, 0x4b60cd60, + 0x4bf0ccf0, 0x4c80c480, 0x4c10c510, 0x4da0c7a0, 0x4d30c630, + 0x4ec0c2c0, 0x4e50c350, 0x4fe0c1e0, 0x4f70c070, 0x4100d100, + 0x4190d090, 0x4020d220, 0x40b0d3b0, 0x4340d740, 0x43d0d6d0, + 0x4260d460, 0x42f0d5f0, 0x4580dd80, 0x4510dc10, 0x44a0dea0, + 0x4430df30, 0x47c0dbc0, 0x4750da50, 0x46e0d8e0, 0x4670d970, + 0x5a00fa00, 0x5a90fb90, 0x5b20f920, 0x5bb0f8b0, 0x5840fc40, + 0x58d0fdd0, 0x5960ff60, 0x59f0fef0, 0x5e80f680, 0x5e10f710, + 0x5fa0f5a0, 0x5f30f430, 0x5cc0f0c0, 0x5c50f150, 0x5de0f3e0, + 0x5d70f270, 0x5300e300, 0x5390e290, 0x5220e020, 0x52b0e1b0, + 0x5140e540, 0x51d0e4d0, 0x5060e660, 0x50f0e7f0, 0x5780ef80, + 0x5710ee10, 0x56a0eca0, 0x5630ed30, 0x55c0e9c0, 0x5550e850, + 0x54e0eae0, 0x5470eb70, 0x6c00ac00, 0x6c90ad90, 0x6d20af20, + 0x6db0aeb0, 0x6e40aa40, 0x6ed0abd0, 0x6f60a960, 0x6ff0a8f0, + 0x6880a080, 0x6810a110, 0x69a0a3a0, 0x6930a230, 0x6ac0a6c0, + 0x6a50a750, 0x6be0a5e0, 0x6b70a470, 0x6500b500, 0x6590b490, + 0x6420b620, 0x64b0b7b0, 0x6740b340, 0x67d0b2d0, 0x6660b060, + 0x66f0b1f0, 0x6180b980, 0x6110b810, 0x60a0baa0, 0x6030bb30, + 0x63c0bfc0, 0x6350be50, 0x62e0bce0, 0x6270bd70, 0x7e009e00, + 0x7e909f90, 0x7f209d20, 0x7fb09cb0, 0x7c409840, 0x7cd099d0, + 0x7d609b60, 0x7df09af0, 0x7a809280, 0x7a109310, 0x7ba091a0, + 0x7b309030, 0x78c094c0, 0x78509550, 0x79e097e0, 0x79709670, + 0x77008700, 0x77908690, 0x76208420, 0x76b085b0, 0x75408140, + 0x75d080d0, 0x74608260, 0x74f083f0, 0x73808b80, 0x73108a10, + 0x72a088a0, 0x72308930, 0x71c08dc0, 0x71508c50, 0x70e08ee0, + 0x70708f70}, + {0x00000000, 0x90019000, 0x90002003, 0x0001b003, 0x90034005, + 0x0002d005, 0x00036006, 0x9002f006, 0x90058009, 0x00041009, + 0x0005a00a, 0x9004300a, 0x0006c00c, 0x9007500c, 0x9006e00f, + 0x0007700f, 0x90080011, 0x00099011, 0x00082012, 0x9009b012, + 0x000b4014, 0x900ad014, 0x900b6017, 0x000af017, 0x000d8018, + 0x900c1018, 0x900da01b, 0x000c301b, 0x900ec01d, 0x000f501d, + 0x000ee01e, 0x900f701e, 0x90130021, 0x00129021, 0x00132022, + 0x9012b022, 0x00104024, 0x9011d024, 0x90106027, 0x0011f027, + 0x00168028, 0x90171028, 0x9016a02b, 0x0017302b, 0x9015c02d, + 0x0014502d, 0x0015e02e, 0x9014702e, 0x001b0030, 0x901a9030, + 0x901b2033, 0x001ab033, 0x90184035, 0x0019d035, 0x00186036, + 0x9019f036, 0x901e8039, 0x001f1039, 0x001ea03a, 0x901f303a, + 0x001dc03c, 0x901c503c, 0x901de03f, 0x001c703f, 0x90250041, + 0x00249041, 0x00252042, 0x9024b042, 0x00264044, 0x9027d044, + 0x90266047, 0x0027f047, 0x00208048, 0x90211048, 0x9020a04b, + 0x0021304b, 0x9023c04d, 0x0022504d, 0x0023e04e, 0x9022704e, + 0x002d0050, 0x902c9050, 0x902d2053, 0x002cb053, 0x902e4055, + 0x002fd055, 0x002e6056, 0x902ff056, 0x90288059, 0x00291059, + 0x0028a05a, 0x9029305a, 0x002bc05c, 0x902a505c, 0x902be05f, + 0x002a705f, 0x00360060, 0x90379060, 0x90362063, 0x0037b063, + 0x90354065, 0x0034d065, 0x00356066, 0x9034f066, 0x90338069, + 0x00321069, 0x0033a06a, 0x9032306a, 0x0030c06c, 0x9031506c, + 0x9030e06f, 0x0031706f, 0x903e0071, 0x003f9071, 0x003e2072, + 0x903fb072, 0x003d4074, 0x903cd074, 0x903d6077, 0x003cf077, + 0x003b8078, 0x903a1078, 0x903ba07b, 0x003a307b, 0x9038c07d, + 0x0039507d, 0x0038e07e, 0x9039707e, 0x90490081, 0x00489081, + 0x00492082, 0x9048b082, 0x004a4084, 0x904bd084, 0x904a6087, + 0x004bf087, 0x004c8088, 0x904d1088, 0x904ca08b, 0x004d308b, + 0x904fc08d, 0x004e508d, 0x004fe08e, 0x904e708e, 0x00410090, + 0x90409090, 0x90412093, 0x0040b093, 0x90424095, 0x0043d095, + 0x00426096, 0x9043f096, 0x90448099, 0x00451099, 0x0044a09a, + 0x9045309a, 0x0047c09c, 0x9046509c, 0x9047e09f, 0x0046709f, + 0x005a00a0, 0x905b90a0, 0x905a20a3, 0x005bb0a3, 0x905940a5, + 0x0058d0a5, 0x005960a6, 0x9058f0a6, 0x905f80a9, 0x005e10a9, + 0x005fa0aa, 0x905e30aa, 0x005cc0ac, 0x905d50ac, 0x905ce0af, + 0x005d70af, 0x905200b1, 0x005390b1, 0x005220b2, 0x9053b0b2, + 0x005140b4, 0x9050d0b4, 0x905160b7, 0x0050f0b7, 0x005780b8, + 0x905610b8, 0x9057a0bb, 0x005630bb, 0x9054c0bd, 0x005550bd, + 0x0054e0be, 0x905570be, 0x006c00c0, 0x906d90c0, 0x906c20c3, + 0x006db0c3, 0x906f40c5, 0x006ed0c5, 0x006f60c6, 0x906ef0c6, + 0x906980c9, 0x006810c9, 0x0069a0ca, 0x906830ca, 0x006ac0cc, + 0x906b50cc, 0x906ae0cf, 0x006b70cf, 0x906400d1, 0x006590d1, + 0x006420d2, 0x9065b0d2, 0x006740d4, 0x9066d0d4, 0x906760d7, + 0x0066f0d7, 0x006180d8, 0x906010d8, 0x9061a0db, 0x006030db, + 0x9062c0dd, 0x006350dd, 0x0062e0de, 0x906370de, 0x907f00e1, + 0x007e90e1, 0x007f20e2, 0x907eb0e2, 0x007c40e4, 0x907dd0e4, + 0x907c60e7, 0x007df0e7, 0x007a80e8, 0x907b10e8, 0x907aa0eb, + 0x007b30eb, 0x9079c0ed, 0x007850ed, 0x0079e0ee, 0x907870ee, + 0x007700f0, 0x907690f0, 0x907720f3, 0x0076b0f3, 0x907440f5, + 0x0075d0f5, 0x007460f6, 0x9075f0f6, 0x907280f9, 0x007310f9, + 0x0072a0fa, 0x907330fa, 0x0071c0fc, 0x907050fc, 0x9071e0ff, + 0x007070ff}, + {0x00000000, 0x90910101, 0x91210201, 0x01b00300, 0x92410401, + 0x02d00500, 0x03600600, 0x93f10701, 0x94810801, 0x04100900, + 0x05a00a00, 0x95310b01, 0x06c00c00, 0x96510d01, 0x97e10e01, + 0x07700f00, 0x99011001, 0x09901100, 0x08201200, 0x98b11301, + 0x0b401400, 0x9bd11501, 0x9a611601, 0x0af01700, 0x0d801800, + 0x9d111901, 0x9ca11a01, 0x0c301b00, 0x9fc11c01, 0x0f501d00, + 0x0ee01e00, 0x9e711f01, 0x82012001, 0x12902100, 0x13202200, + 0x83b12301, 0x10402400, 0x80d12501, 0x81612601, 0x11f02700, + 0x16802800, 0x86112901, 0x87a12a01, 0x17302b00, 0x84c12c01, + 0x14502d00, 0x15e02e00, 0x85712f01, 0x1b003000, 0x8b913101, + 0x8a213201, 0x1ab03300, 0x89413401, 0x19d03500, 0x18603600, + 0x88f13701, 0x8f813801, 0x1f103900, 0x1ea03a00, 0x8e313b01, + 0x1dc03c00, 0x8d513d01, 0x8ce13e01, 0x1c703f00, 0xb4014001, + 0x24904100, 0x25204200, 0xb5b14301, 0x26404400, 0xb6d14501, + 0xb7614601, 0x27f04700, 0x20804800, 0xb0114901, 0xb1a14a01, + 0x21304b00, 0xb2c14c01, 0x22504d00, 0x23e04e00, 0xb3714f01, + 0x2d005000, 0xbd915101, 0xbc215201, 0x2cb05300, 0xbf415401, + 0x2fd05500, 0x2e605600, 0xbef15701, 0xb9815801, 0x29105900, + 0x28a05a00, 0xb8315b01, 0x2bc05c00, 0xbb515d01, 0xbae15e01, + 0x2a705f00, 0x36006000, 0xa6916101, 0xa7216201, 0x37b06300, + 0xa4416401, 0x34d06500, 0x35606600, 0xa5f16701, 0xa2816801, + 0x32106900, 0x33a06a00, 0xa3316b01, 0x30c06c00, 0xa0516d01, + 0xa1e16e01, 0x31706f00, 0xaf017001, 0x3f907100, 0x3e207200, + 0xaeb17301, 0x3d407400, 0xadd17501, 0xac617601, 0x3cf07700, + 0x3b807800, 0xab117901, 0xaaa17a01, 0x3a307b00, 0xa9c17c01, + 0x39507d00, 0x38e07e00, 0xa8717f01, 0xd8018001, 0x48908100, + 0x49208200, 0xd9b18301, 0x4a408400, 0xdad18501, 0xdb618601, + 0x4bf08700, 0x4c808800, 0xdc118901, 0xdda18a01, 0x4d308b00, + 0xdec18c01, 0x4e508d00, 0x4fe08e00, 0xdf718f01, 0x41009000, + 0xd1919101, 0xd0219201, 0x40b09300, 0xd3419401, 0x43d09500, + 0x42609600, 0xd2f19701, 0xd5819801, 0x45109900, 0x44a09a00, + 0xd4319b01, 0x47c09c00, 0xd7519d01, 0xd6e19e01, 0x46709f00, + 0x5a00a000, 0xca91a101, 0xcb21a201, 0x5bb0a300, 0xc841a401, + 0x58d0a500, 0x5960a600, 0xc9f1a701, 0xce81a801, 0x5e10a900, + 0x5fa0aa00, 0xcf31ab01, 0x5cc0ac00, 0xcc51ad01, 0xcde1ae01, + 0x5d70af00, 0xc301b001, 0x5390b100, 0x5220b200, 0xc2b1b301, + 0x5140b400, 0xc1d1b501, 0xc061b601, 0x50f0b700, 0x5780b800, + 0xc711b901, 0xc6a1ba01, 0x5630bb00, 0xc5c1bc01, 0x5550bd00, + 0x54e0be00, 0xc471bf01, 0x6c00c000, 0xfc91c101, 0xfd21c201, + 0x6db0c300, 0xfe41c401, 0x6ed0c500, 0x6f60c600, 0xfff1c701, + 0xf881c801, 0x6810c900, 0x69a0ca00, 0xf931cb01, 0x6ac0cc00, + 0xfa51cd01, 0xfbe1ce01, 0x6b70cf00, 0xf501d001, 0x6590d100, + 0x6420d200, 0xf4b1d301, 0x6740d400, 0xf7d1d501, 0xf661d601, + 0x66f0d700, 0x6180d800, 0xf111d901, 0xf0a1da01, 0x6030db00, + 0xf3c1dc01, 0x6350dd00, 0x62e0de00, 0xf271df01, 0xee01e001, + 0x7e90e100, 0x7f20e200, 0xefb1e301, 0x7c40e400, 0xecd1e501, + 0xed61e601, 0x7df0e700, 0x7a80e800, 0xea11e901, 0xeba1ea01, + 0x7b30eb00, 0xe8c1ec01, 0x7850ed00, 0x79e0ee00, 0xe971ef01, + 0x7700f000, 0xe791f101, 0xe621f201, 0x76b0f300, 0xe541f401, + 0x75d0f500, 0x7460f600, 0xe4f1f701, 0xe381f801, 0x7310f900, + 0x72a0fa00, 0xe231fb01, 0x71c0fc00, 0xe151fd01, 0xe0e1fe01, + 0x7070ff00}}; + +static const word_t crc_braid_big_table[][256] = { + {0x00000000, 0x01019190, 0x01022191, 0x0003b001, 0x01044192, + 0x0005d002, 0x00066003, 0x0107f193, 0x01088194, 0x00091004, + 0x000aa005, 0x010b3195, 0x000cc006, 0x010d5196, 0x010ee197, + 0x000f7007, 0x01100199, 0x00119009, 0x00122008, 0x0113b198, + 0x0014400b, 0x0115d19b, 0x0116619a, 0x0017f00a, 0x0018800d, + 0x0119119d, 0x011aa19c, 0x001b300c, 0x011cc19f, 0x001d500f, + 0x001ee00e, 0x011f719e, 0x01200182, 0x00219012, 0x00222013, + 0x0123b183, 0x00244010, 0x0125d180, 0x01266181, 0x0027f011, + 0x00288016, 0x01291186, 0x012aa187, 0x002b3017, 0x012cc184, + 0x002d5014, 0x002ee015, 0x012f7185, 0x0030001b, 0x0131918b, + 0x0132218a, 0x0033b01a, 0x01344189, 0x0035d019, 0x00366018, + 0x0137f188, 0x0138818f, 0x0039101f, 0x003aa01e, 0x013b318e, + 0x003cc01d, 0x013d518d, 0x013ee18c, 0x003f701c, 0x014001b4, + 0x00419024, 0x00422025, 0x0143b1b5, 0x00444026, 0x0145d1b6, + 0x014661b7, 0x0047f027, 0x00488020, 0x014911b0, 0x014aa1b1, + 0x004b3021, 0x014cc1b2, 0x004d5022, 0x004ee023, 0x014f71b3, + 0x0050002d, 0x015191bd, 0x015221bc, 0x0053b02c, 0x015441bf, + 0x0055d02f, 0x0056602e, 0x0157f1be, 0x015881b9, 0x00591029, + 0x005aa028, 0x015b31b8, 0x005cc02b, 0x015d51bb, 0x015ee1ba, + 0x005f702a, 0x00600036, 0x016191a6, 0x016221a7, 0x0063b037, + 0x016441a4, 0x0065d034, 0x00666035, 0x0167f1a5, 0x016881a2, + 0x00691032, 0x006aa033, 0x016b31a3, 0x006cc030, 0x016d51a0, + 0x016ee1a1, 0x006f7031, 0x017001af, 0x0071903f, 0x0072203e, + 0x0173b1ae, 0x0074403d, 0x0175d1ad, 0x017661ac, 0x0077f03c, + 0x0078803b, 0x017911ab, 0x017aa1aa, 0x007b303a, 0x017cc1a9, + 0x007d5039, 0x007ee038, 0x017f71a8, 0x018001d8, 0x00819048, + 0x00822049, 0x0183b1d9, 0x0084404a, 0x0185d1da, 0x018661db, + 0x0087f04b, 0x0088804c, 0x018911dc, 0x018aa1dd, 0x008b304d, + 0x018cc1de, 0x008d504e, 0x008ee04f, 0x018f71df, 0x00900041, + 0x019191d1, 0x019221d0, 0x0093b040, 0x019441d3, 0x0095d043, + 0x00966042, 0x0197f1d2, 0x019881d5, 0x00991045, 0x009aa044, + 0x019b31d4, 0x009cc047, 0x019d51d7, 0x019ee1d6, 0x009f7046, + 0x00a0005a, 0x01a191ca, 0x01a221cb, 0x00a3b05b, 0x01a441c8, + 0x00a5d058, 0x00a66059, 0x01a7f1c9, 0x01a881ce, 0x00a9105e, + 0x00aaa05f, 0x01ab31cf, 0x00acc05c, 0x01ad51cc, 0x01aee1cd, + 0x00af705d, 0x01b001c3, 0x00b19053, 0x00b22052, 0x01b3b1c2, + 0x00b44051, 0x01b5d1c1, 0x01b661c0, 0x00b7f050, 0x00b88057, + 0x01b911c7, 0x01baa1c6, 0x00bb3056, 0x01bcc1c5, 0x00bd5055, + 0x00bee054, 0x01bf71c4, 0x00c0006c, 0x01c191fc, 0x01c221fd, + 0x00c3b06d, 0x01c441fe, 0x00c5d06e, 0x00c6606f, 0x01c7f1ff, + 0x01c881f8, 0x00c91068, 0x00caa069, 0x01cb31f9, 0x00ccc06a, + 0x01cd51fa, 0x01cee1fb, 0x00cf706b, 0x01d001f5, 0x00d19065, + 0x00d22064, 0x01d3b1f4, 0x00d44067, 0x01d5d1f7, 0x01d661f6, + 0x00d7f066, 0x00d88061, 0x01d911f1, 0x01daa1f0, 0x00db3060, + 0x01dcc1f3, 0x00dd5063, 0x00dee062, 0x01df71f2, 0x01e001ee, + 0x00e1907e, 0x00e2207f, 0x01e3b1ef, 0x00e4407c, 0x01e5d1ec, + 0x01e661ed, 0x00e7f07d, 0x00e8807a, 0x01e911ea, 0x01eaa1eb, + 0x00eb307b, 0x01ecc1e8, 0x00ed5078, 0x00eee079, 0x01ef71e9, + 0x00f00077, 0x01f191e7, 0x01f221e6, 0x00f3b076, 0x01f441e5, + 0x00f5d075, 0x00f66074, 0x01f7f1e4, 0x01f881e3, 0x00f91073, + 0x00faa072, 0x01fb31e2, 0x00fcc071, 0x01fd51e1, 0x01fee1e0, + 0x00ff7070}, + {0x00000000, 0x00900190, 0x03200090, 0x03b00100, 0x05400390, + 0x05d00200, 0x06600300, 0x06f00290, 0x09800590, 0x09100400, + 0x0aa00500, 0x0a300490, 0x0cc00600, 0x0c500790, 0x0fe00690, + 0x0f700700, 0x11000890, 0x11900900, 0x12200800, 0x12b00990, + 0x14400b00, 0x14d00a90, 0x17600b90, 0x17f00a00, 0x18800d00, + 0x18100c90, 0x1ba00d90, 0x1b300c00, 0x1dc00e90, 0x1d500f00, + 0x1ee00e00, 0x1e700f90, 0x21001390, 0x21901200, 0x22201300, + 0x22b01290, 0x24401000, 0x24d01190, 0x27601090, 0x27f01100, + 0x28801600, 0x28101790, 0x2ba01690, 0x2b301700, 0x2dc01590, + 0x2d501400, 0x2ee01500, 0x2e701490, 0x30001b00, 0x30901a90, + 0x33201b90, 0x33b01a00, 0x35401890, 0x35d01900, 0x36601800, + 0x36f01990, 0x39801e90, 0x39101f00, 0x3aa01e00, 0x3a301f90, + 0x3cc01d00, 0x3c501c90, 0x3fe01d90, 0x3f701c00, 0x41002590, + 0x41902400, 0x42202500, 0x42b02490, 0x44402600, 0x44d02790, + 0x47602690, 0x47f02700, 0x48802000, 0x48102190, 0x4ba02090, + 0x4b302100, 0x4dc02390, 0x4d502200, 0x4ee02300, 0x4e702290, + 0x50002d00, 0x50902c90, 0x53202d90, 0x53b02c00, 0x55402e90, + 0x55d02f00, 0x56602e00, 0x56f02f90, 0x59802890, 0x59102900, + 0x5aa02800, 0x5a302990, 0x5cc02b00, 0x5c502a90, 0x5fe02b90, + 0x5f702a00, 0x60003600, 0x60903790, 0x63203690, 0x63b03700, + 0x65403590, 0x65d03400, 0x66603500, 0x66f03490, 0x69803390, + 0x69103200, 0x6aa03300, 0x6a303290, 0x6cc03000, 0x6c503190, + 0x6fe03090, 0x6f703100, 0x71003e90, 0x71903f00, 0x72203e00, + 0x72b03f90, 0x74403d00, 0x74d03c90, 0x77603d90, 0x77f03c00, + 0x78803b00, 0x78103a90, 0x7ba03b90, 0x7b303a00, 0x7dc03890, + 0x7d503900, 0x7ee03800, 0x7e703990, 0x81004990, 0x81904800, + 0x82204900, 0x82b04890, 0x84404a00, 0x84d04b90, 0x87604a90, + 0x87f04b00, 0x88804c00, 0x88104d90, 0x8ba04c90, 0x8b304d00, + 0x8dc04f90, 0x8d504e00, 0x8ee04f00, 0x8e704e90, 0x90004100, + 0x90904090, 0x93204190, 0x93b04000, 0x95404290, 0x95d04300, + 0x96604200, 0x96f04390, 0x99804490, 0x99104500, 0x9aa04400, + 0x9a304590, 0x9cc04700, 0x9c504690, 0x9fe04790, 0x9f704600, + 0xa0005a00, 0xa0905b90, 0xa3205a90, 0xa3b05b00, 0xa5405990, + 0xa5d05800, 0xa6605900, 0xa6f05890, 0xa9805f90, 0xa9105e00, + 0xaaa05f00, 0xaa305e90, 0xacc05c00, 0xac505d90, 0xafe05c90, + 0xaf705d00, 0xb1005290, 0xb1905300, 0xb2205200, 0xb2b05390, + 0xb4405100, 0xb4d05090, 0xb7605190, 0xb7f05000, 0xb8805700, + 0xb8105690, 0xbba05790, 0xbb305600, 0xbdc05490, 0xbd505500, + 0xbee05400, 0xbe705590, 0xc0006c00, 0xc0906d90, 0xc3206c90, + 0xc3b06d00, 0xc5406f90, 0xc5d06e00, 0xc6606f00, 0xc6f06e90, + 0xc9806990, 0xc9106800, 0xcaa06900, 0xca306890, 0xccc06a00, + 0xcc506b90, 0xcfe06a90, 0xcf706b00, 0xd1006490, 0xd1906500, + 0xd2206400, 0xd2b06590, 0xd4406700, 0xd4d06690, 0xd7606790, + 0xd7f06600, 0xd8806100, 0xd8106090, 0xdba06190, 0xdb306000, + 0xddc06290, 0xdd506300, 0xdee06200, 0xde706390, 0xe1007f90, + 0xe1907e00, 0xe2207f00, 0xe2b07e90, 0xe4407c00, 0xe4d07d90, + 0xe7607c90, 0xe7f07d00, 0xe8807a00, 0xe8107b90, 0xeba07a90, + 0xeb307b00, 0xedc07990, 0xed507800, 0xeee07900, 0xee707890, + 0xf0007700, 0xf0907690, 0xf3207790, 0xf3b07600, 0xf5407490, + 0xf5d07500, 0xf6607400, 0xf6f07590, 0xf9807290, 0xf9107300, + 0xfaa07200, 0xfa307390, 0xfcc07100, 0xfc507090, 0xffe07190, + 0xff707000}, + {0x00000000, 0x90019000, 0x20032001, 0xb002b001, 0x40064002, + 0xd007d002, 0x60056003, 0xf004f003, 0x800c8004, 0x100d1004, + 0xa00fa005, 0x300e3005, 0xc00ac006, 0x500b5006, 0xe009e007, + 0x70087007, 0x00190009, 0x90189009, 0x201a2008, 0xb01bb008, + 0x401f400b, 0xd01ed00b, 0x601c600a, 0xf01df00a, 0x8015800d, + 0x1014100d, 0xa016a00c, 0x3017300c, 0xc013c00f, 0x5012500f, + 0xe010e00e, 0x7011700e, 0x00320012, 0x90339012, 0x20312013, + 0xb030b013, 0x40344010, 0xd035d010, 0x60376011, 0xf036f011, + 0x803e8016, 0x103f1016, 0xa03da017, 0x303c3017, 0xc038c014, + 0x50395014, 0xe03be015, 0x703a7015, 0x002b001b, 0x902a901b, + 0x2028201a, 0xb029b01a, 0x402d4019, 0xd02cd019, 0x602e6018, + 0xf02ff018, 0x8027801f, 0x1026101f, 0xa024a01e, 0x3025301e, + 0xc021c01d, 0x5020501d, 0xe022e01c, 0x7023701c, 0x00640024, + 0x90659024, 0x20672025, 0xb066b025, 0x40624026, 0xd063d026, + 0x60616027, 0xf060f027, 0x80688020, 0x10691020, 0xa06ba021, + 0x306a3021, 0xc06ec022, 0x506f5022, 0xe06de023, 0x706c7023, + 0x007d002d, 0x907c902d, 0x207e202c, 0xb07fb02c, 0x407b402f, + 0xd07ad02f, 0x6078602e, 0xf079f02e, 0x80718029, 0x10701029, + 0xa072a028, 0x30733028, 0xc077c02b, 0x5076502b, 0xe074e02a, + 0x7075702a, 0x00560036, 0x90579036, 0x20552037, 0xb054b037, + 0x40504034, 0xd051d034, 0x60536035, 0xf052f035, 0x805a8032, + 0x105b1032, 0xa059a033, 0x30583033, 0xc05cc030, 0x505d5030, + 0xe05fe031, 0x705e7031, 0x004f003f, 0x904e903f, 0x204c203e, + 0xb04db03e, 0x4049403d, 0xd048d03d, 0x604a603c, 0xf04bf03c, + 0x8043803b, 0x1042103b, 0xa040a03a, 0x3041303a, 0xc045c039, + 0x50445039, 0xe046e038, 0x70477038, 0x00c80048, 0x90c99048, + 0x20cb2049, 0xb0cab049, 0x40ce404a, 0xd0cfd04a, 0x60cd604b, + 0xf0ccf04b, 0x80c4804c, 0x10c5104c, 0xa0c7a04d, 0x30c6304d, + 0xc0c2c04e, 0x50c3504e, 0xe0c1e04f, 0x70c0704f, 0x00d10041, + 0x90d09041, 0x20d22040, 0xb0d3b040, 0x40d74043, 0xd0d6d043, + 0x60d46042, 0xf0d5f042, 0x80dd8045, 0x10dc1045, 0xa0dea044, + 0x30df3044, 0xc0dbc047, 0x50da5047, 0xe0d8e046, 0x70d97046, + 0x00fa005a, 0x90fb905a, 0x20f9205b, 0xb0f8b05b, 0x40fc4058, + 0xd0fdd058, 0x60ff6059, 0xf0fef059, 0x80f6805e, 0x10f7105e, + 0xa0f5a05f, 0x30f4305f, 0xc0f0c05c, 0x50f1505c, 0xe0f3e05d, + 0x70f2705d, 0x00e30053, 0x90e29053, 0x20e02052, 0xb0e1b052, + 0x40e54051, 0xd0e4d051, 0x60e66050, 0xf0e7f050, 0x80ef8057, + 0x10ee1057, 0xa0eca056, 0x30ed3056, 0xc0e9c055, 0x50e85055, + 0xe0eae054, 0x70eb7054, 0x00ac006c, 0x90ad906c, 0x20af206d, + 0xb0aeb06d, 0x40aa406e, 0xd0abd06e, 0x60a9606f, 0xf0a8f06f, + 0x80a08068, 0x10a11068, 0xa0a3a069, 0x30a23069, 0xc0a6c06a, + 0x50a7506a, 0xe0a5e06b, 0x70a4706b, 0x00b50065, 0x90b49065, + 0x20b62064, 0xb0b7b064, 0x40b34067, 0xd0b2d067, 0x60b06066, + 0xf0b1f066, 0x80b98061, 0x10b81061, 0xa0baa060, 0x30bb3060, + 0xc0bfc063, 0x50be5063, 0xe0bce062, 0x70bd7062, 0x009e007e, + 0x909f907e, 0x209d207f, 0xb09cb07f, 0x4098407c, 0xd099d07c, + 0x609b607d, 0xf09af07d, 0x8092807a, 0x1093107a, 0xa091a07b, + 0x3090307b, 0xc094c078, 0x50955078, 0xe097e079, 0x70967079, + 0x00870077, 0x90869077, 0x20842076, 0xb085b076, 0x40814075, + 0xd080d075, 0x60826074, 0xf083f074, 0x808b8073, 0x108a1073, + 0xa088a072, 0x30893072, 0xc08dc071, 0x508c5071, 0xe08ee070, + 0x708f7070}, + {0x00000000, 0x01000041, 0x02000082, 0x030000c3, 0x070003b4, + 0x060003f5, 0x05000336, 0x04000377, 0x0d0005d8, 0x0c000599, + 0x0f00055a, 0x0e00051b, 0x0a00066c, 0x0b00062d, 0x080006ee, + 0x090006af, 0x19000900, 0x18000941, 0x1b000982, 0x1a0009c3, + 0x1e000ab4, 0x1f000af5, 0x1c000a36, 0x1d000a77, 0x14000cd8, + 0x15000c99, 0x16000c5a, 0x17000c1b, 0x13000f6c, 0x12000f2d, + 0x11000fee, 0x10000faf, 0x32001200, 0x33001241, 0x30001282, + 0x310012c3, 0x350011b4, 0x340011f5, 0x37001136, 0x36001177, + 0x3f0017d8, 0x3e001799, 0x3d00175a, 0x3c00171b, 0x3800146c, + 0x3900142d, 0x3a0014ee, 0x3b0014af, 0x2b001b00, 0x2a001b41, + 0x29001b82, 0x28001bc3, 0x2c0018b4, 0x2d0018f5, 0x2e001836, + 0x2f001877, 0x26001ed8, 0x27001e99, 0x24001e5a, 0x25001e1b, + 0x21001d6c, 0x20001d2d, 0x23001dee, 0x22001daf, 0x64002400, + 0x65002441, 0x66002482, 0x670024c3, 0x630027b4, 0x620027f5, + 0x61002736, 0x60002777, 0x690021d8, 0x68002199, 0x6b00215a, + 0x6a00211b, 0x6e00226c, 0x6f00222d, 0x6c0022ee, 0x6d0022af, + 0x7d002d00, 0x7c002d41, 0x7f002d82, 0x7e002dc3, 0x7a002eb4, + 0x7b002ef5, 0x78002e36, 0x79002e77, 0x700028d8, 0x71002899, + 0x7200285a, 0x7300281b, 0x77002b6c, 0x76002b2d, 0x75002bee, + 0x74002baf, 0x56003600, 0x57003641, 0x54003682, 0x550036c3, + 0x510035b4, 0x500035f5, 0x53003536, 0x52003577, 0x5b0033d8, + 0x5a003399, 0x5900335a, 0x5800331b, 0x5c00306c, 0x5d00302d, + 0x5e0030ee, 0x5f0030af, 0x4f003f00, 0x4e003f41, 0x4d003f82, + 0x4c003fc3, 0x48003cb4, 0x49003cf5, 0x4a003c36, 0x4b003c77, + 0x42003ad8, 0x43003a99, 0x40003a5a, 0x41003a1b, 0x4500396c, + 0x4400392d, 0x470039ee, 0x460039af, 0xc8004800, 0xc9004841, + 0xca004882, 0xcb0048c3, 0xcf004bb4, 0xce004bf5, 0xcd004b36, + 0xcc004b77, 0xc5004dd8, 0xc4004d99, 0xc7004d5a, 0xc6004d1b, + 0xc2004e6c, 0xc3004e2d, 0xc0004eee, 0xc1004eaf, 0xd1004100, + 0xd0004141, 0xd3004182, 0xd20041c3, 0xd60042b4, 0xd70042f5, + 0xd4004236, 0xd5004277, 0xdc0044d8, 0xdd004499, 0xde00445a, + 0xdf00441b, 0xdb00476c, 0xda00472d, 0xd90047ee, 0xd80047af, + 0xfa005a00, 0xfb005a41, 0xf8005a82, 0xf9005ac3, 0xfd0059b4, + 0xfc0059f5, 0xff005936, 0xfe005977, 0xf7005fd8, 0xf6005f99, + 0xf5005f5a, 0xf4005f1b, 0xf0005c6c, 0xf1005c2d, 0xf2005cee, + 0xf3005caf, 0xe3005300, 0xe2005341, 0xe1005382, 0xe00053c3, + 0xe40050b4, 0xe50050f5, 0xe6005036, 0xe7005077, 0xee0056d8, + 0xef005699, 0xec00565a, 0xed00561b, 0xe900556c, 0xe800552d, + 0xeb0055ee, 0xea0055af, 0xac006c00, 0xad006c41, 0xae006c82, + 0xaf006cc3, 0xab006fb4, 0xaa006ff5, 0xa9006f36, 0xa8006f77, + 0xa10069d8, 0xa0006999, 0xa300695a, 0xa200691b, 0xa6006a6c, + 0xa7006a2d, 0xa4006aee, 0xa5006aaf, 0xb5006500, 0xb4006541, + 0xb7006582, 0xb60065c3, 0xb20066b4, 0xb30066f5, 0xb0006636, + 0xb1006677, 0xb80060d8, 0xb9006099, 0xba00605a, 0xbb00601b, + 0xbf00636c, 0xbe00632d, 0xbd0063ee, 0xbc0063af, 0x9e007e00, + 0x9f007e41, 0x9c007e82, 0x9d007ec3, 0x99007db4, 0x98007df5, + 0x9b007d36, 0x9a007d77, 0x93007bd8, 0x92007b99, 0x91007b5a, + 0x90007b1b, 0x9400786c, 0x9500782d, 0x960078ee, 0x970078af, + 0x87007700, 0x86007741, 0x85007782, 0x840077c3, 0x800074b4, + 0x810074f5, 0x82007436, 0x83007477, 0x8a0072d8, 0x8b007299, + 0x8800725a, 0x8900721b, 0x8d00716c, 0x8c00712d, 0x8f0071ee, + 0x8e0071af}}; + +#endif + +#endif + +#if N == 2 + +#if W == 8 + +static const crc_t crc_braid_table[][256] = { + {0x00000000, 0x6c90c100, 0xd9218200, 0xb5b14300, 0x02400403, + 0x6ed0c503, 0xdb618603, 0xb7f14703, 0x04800806, 0x6810c906, + 0xdda18a06, 0xb1314b06, 0x06c00c05, 0x6a50cd05, 0xdfe18e05, + 0xb3714f05, 0x0900100c, 0x6590d10c, 0xd021920c, 0xbcb1530c, + 0x0b40140f, 0x67d0d50f, 0xd261960f, 0xbef1570f, 0x0d80180a, + 0x6110d90a, 0xd4a19a0a, 0xb8315b0a, 0x0fc01c09, 0x6350dd09, + 0xd6e19e09, 0xba715f09, 0x12002018, 0x7e90e118, 0xcb21a218, + 0xa7b16318, 0x1040241b, 0x7cd0e51b, 0xc961a61b, 0xa5f1671b, + 0x1680281e, 0x7a10e91e, 0xcfa1aa1e, 0xa3316b1e, 0x14c02c1d, + 0x7850ed1d, 0xcde1ae1d, 0xa1716f1d, 0x1b003014, 0x7790f114, + 0xc221b214, 0xaeb17314, 0x19403417, 0x75d0f517, 0xc061b617, + 0xacf17717, 0x1f803812, 0x7310f912, 0xc6a1ba12, 0xaa317b12, + 0x1dc03c11, 0x7150fd11, 0xc4e1be11, 0xa8717f11, 0x24004030, + 0x48908130, 0xfd21c230, 0x91b10330, 0x26404433, 0x4ad08533, + 0xff61c633, 0x93f10733, 0x20804836, 0x4c108936, 0xf9a1ca36, + 0x95310b36, 0x22c04c35, 0x4e508d35, 0xfbe1ce35, 0x97710f35, + 0x2d00503c, 0x4190913c, 0xf421d23c, 0x98b1133c, 0x2f40543f, + 0x43d0953f, 0xf661d63f, 0x9af1173f, 0x2980583a, 0x4510993a, + 0xf0a1da3a, 0x9c311b3a, 0x2bc05c39, 0x47509d39, 0xf2e1de39, + 0x9e711f39, 0x36006028, 0x5a90a128, 0xef21e228, 0x83b12328, + 0x3440642b, 0x58d0a52b, 0xed61e62b, 0x81f1272b, 0x3280682e, + 0x5e10a92e, 0xeba1ea2e, 0x87312b2e, 0x30c06c2d, 0x5c50ad2d, + 0xe9e1ee2d, 0x85712f2d, 0x3f007024, 0x5390b124, 0xe621f224, + 0x8ab13324, 0x3d407427, 0x51d0b527, 0xe461f627, 0x88f13727, + 0x3b807822, 0x5710b922, 0xe2a1fa22, 0x8e313b22, 0x39c07c21, + 0x5550bd21, 0xe0e1fe21, 0x8c713f21, 0x48008060, 0x24904160, + 0x91210260, 0xfdb1c360, 0x4a408463, 0x26d04563, 0x93610663, + 0xfff1c763, 0x4c808866, 0x20104966, 0x95a10a66, 0xf931cb66, + 0x4ec08c65, 0x22504d65, 0x97e10e65, 0xfb71cf65, 0x4100906c, + 0x2d90516c, 0x9821126c, 0xf4b1d36c, 0x4340946f, 0x2fd0556f, + 0x9a61166f, 0xf6f1d76f, 0x4580986a, 0x2910596a, 0x9ca11a6a, + 0xf031db6a, 0x47c09c69, 0x2b505d69, 0x9ee11e69, 0xf271df69, + 0x5a00a078, 0x36906178, 0x83212278, 0xefb1e378, 0x5840a47b, + 0x34d0657b, 0x8161267b, 0xedf1e77b, 0x5e80a87e, 0x3210697e, + 0x87a12a7e, 0xeb31eb7e, 0x5cc0ac7d, 0x30506d7d, 0x85e12e7d, + 0xe971ef7d, 0x5300b074, 0x3f907174, 0x8a213274, 0xe6b1f374, + 0x5140b477, 0x3dd07577, 0x88613677, 0xe4f1f777, 0x5780b872, + 0x3b107972, 0x8ea13a72, 0xe231fb72, 0x55c0bc71, 0x39507d71, + 0x8ce13e71, 0xe071ff71, 0x6c00c050, 0x00900150, 0xb5214250, + 0xd9b18350, 0x6e40c453, 0x02d00553, 0xb7614653, 0xdbf18753, + 0x6880c856, 0x04100956, 0xb1a14a56, 0xdd318b56, 0x6ac0cc55, + 0x06500d55, 0xb3e14e55, 0xdf718f55, 0x6500d05c, 0x0990115c, + 0xbc21525c, 0xd0b1935c, 0x6740d45f, 0x0bd0155f, 0xbe61565f, + 0xd2f1975f, 0x6180d85a, 0x0d10195a, 0xb8a15a5a, 0xd4319b5a, + 0x63c0dc59, 0x0f501d59, 0xbae15e59, 0xd6719f59, 0x7e00e048, + 0x12902148, 0xa7216248, 0xcbb1a348, 0x7c40e44b, 0x10d0254b, + 0xa561664b, 0xc9f1a74b, 0x7a80e84e, 0x1610294e, 0xa3a16a4e, + 0xcf31ab4e, 0x78c0ec4d, 0x14502d4d, 0xa1e16e4d, 0xcd71af4d, + 0x7700f044, 0x1b903144, 0xae217244, 0xc2b1b344, 0x7540f447, + 0x19d03547, 0xac617647, 0xc0f1b747, 0x7380f842, 0x1f103942, + 0xaaa17a42, 0xc631bb42, 0x71c0fc41, 0x1d503d41, 0xa8e17e41, + 0xc471bf41}, + {0x00000000, 0x900100c0, 0x90010183, 0x00000143, 0x90010305, + 0x000003c5, 0x00000286, 0x90010246, 0x90010609, 0x000006c9, + 0x0000078a, 0x9001074a, 0x0000050c, 0x900105cc, 0x9001048f, + 0x0000044f, 0x90010c11, 0x00000cd1, 0x00000d92, 0x90010d52, + 0x00000f14, 0x90010fd4, 0x90010e97, 0x00000e57, 0x00000a18, + 0x90010ad8, 0x90010b9b, 0x00000b5b, 0x9001091d, 0x000009dd, + 0x0000089e, 0x9001085e, 0x90011821, 0x000018e1, 0x000019a2, + 0x90011962, 0x00001b24, 0x90011be4, 0x90011aa7, 0x00001a67, + 0x00001e28, 0x90011ee8, 0x90011fab, 0x00001f6b, 0x90011d2d, + 0x00001ded, 0x00001cae, 0x90011c6e, 0x00001430, 0x900114f0, + 0x900115b3, 0x00001573, 0x90011735, 0x000017f5, 0x000016b6, + 0x90011676, 0x90011239, 0x000012f9, 0x000013ba, 0x9001137a, + 0x0000113c, 0x900111fc, 0x900110bf, 0x0000107f, 0x90013041, + 0x00003081, 0x000031c2, 0x90013102, 0x00003344, 0x90013384, + 0x900132c7, 0x00003207, 0x00003648, 0x90013688, 0x900137cb, + 0x0000370b, 0x9001354d, 0x0000358d, 0x000034ce, 0x9001340e, + 0x00003c50, 0x90013c90, 0x90013dd3, 0x00003d13, 0x90013f55, + 0x00003f95, 0x00003ed6, 0x90013e16, 0x90013a59, 0x00003a99, + 0x00003bda, 0x90013b1a, 0x0000395c, 0x9001399c, 0x900138df, + 0x0000381f, 0x00002860, 0x900128a0, 0x900129e3, 0x00002923, + 0x90012b65, 0x00002ba5, 0x00002ae6, 0x90012a26, 0x90012e69, + 0x00002ea9, 0x00002fea, 0x90012f2a, 0x00002d6c, 0x90012dac, + 0x90012cef, 0x00002c2f, 0x90012471, 0x000024b1, 0x000025f2, + 0x90012532, 0x00002774, 0x900127b4, 0x900126f7, 0x00002637, + 0x00002278, 0x900122b8, 0x900123fb, 0x0000233b, 0x9001217d, + 0x000021bd, 0x000020fe, 0x9001203e, 0x90016081, 0x00006041, + 0x00006102, 0x900161c2, 0x00006384, 0x90016344, 0x90016207, + 0x000062c7, 0x00006688, 0x90016648, 0x9001670b, 0x000067cb, + 0x9001658d, 0x0000654d, 0x0000640e, 0x900164ce, 0x00006c90, + 0x90016c50, 0x90016d13, 0x00006dd3, 0x90016f95, 0x00006f55, + 0x00006e16, 0x90016ed6, 0x90016a99, 0x00006a59, 0x00006b1a, + 0x90016bda, 0x0000699c, 0x9001695c, 0x9001681f, 0x000068df, + 0x000078a0, 0x90017860, 0x90017923, 0x000079e3, 0x90017ba5, + 0x00007b65, 0x00007a26, 0x90017ae6, 0x90017ea9, 0x00007e69, + 0x00007f2a, 0x90017fea, 0x00007dac, 0x90017d6c, 0x90017c2f, + 0x00007cef, 0x900174b1, 0x00007471, 0x00007532, 0x900175f2, + 0x000077b4, 0x90017774, 0x90017637, 0x000076f7, 0x000072b8, + 0x90017278, 0x9001733b, 0x000073fb, 0x900171bd, 0x0000717d, + 0x0000703e, 0x900170fe, 0x000050c0, 0x90015000, 0x90015143, + 0x00005183, 0x900153c5, 0x00005305, 0x00005246, 0x90015286, + 0x900156c9, 0x00005609, 0x0000574a, 0x9001578a, 0x000055cc, + 0x9001550c, 0x9001544f, 0x0000548f, 0x90015cd1, 0x00005c11, + 0x00005d52, 0x90015d92, 0x00005fd4, 0x90015f14, 0x90015e57, + 0x00005e97, 0x00005ad8, 0x90015a18, 0x90015b5b, 0x00005b9b, + 0x900159dd, 0x0000591d, 0x0000585e, 0x9001589e, 0x900148e1, + 0x00004821, 0x00004962, 0x900149a2, 0x00004be4, 0x90014b24, + 0x90014a67, 0x00004aa7, 0x00004ee8, 0x90014e28, 0x90014f6b, + 0x00004fab, 0x90014ded, 0x00004d2d, 0x00004c6e, 0x90014cae, + 0x000044f0, 0x90014430, 0x90014573, 0x000045b3, 0x900147f5, + 0x00004735, 0x00004676, 0x900146b6, 0x900142f9, 0x00004239, + 0x0000437a, 0x900143ba, 0x000041fc, 0x9001413c, 0x9001407f, + 0x000040bf}, + {0x00000000, 0x9001c101, 0x90008201, 0x00014300, 0x90020401, + 0x0003c500, 0x00028600, 0x90034701, 0x90070801, 0x0006c900, + 0x00078a00, 0x90064b01, 0x00050c00, 0x9004cd01, 0x90058e01, + 0x00044f00, 0x900d1001, 0x000cd100, 0x000d9200, 0x900c5301, + 0x000f1400, 0x900ed501, 0x900f9601, 0x000e5700, 0x000a1800, + 0x900bd901, 0x900a9a01, 0x000b5b00, 0x90081c01, 0x0009dd00, + 0x00089e00, 0x90095f01, 0x90192001, 0x0018e100, 0x0019a200, + 0x90186301, 0x001b2400, 0x901ae501, 0x901ba601, 0x001a6700, + 0x001e2800, 0x901fe901, 0x901eaa01, 0x001f6b00, 0x901c2c01, + 0x001ded00, 0x001cae00, 0x901d6f01, 0x00143000, 0x9015f101, + 0x9014b201, 0x00157300, 0x90163401, 0x0017f500, 0x0016b600, + 0x90177701, 0x90133801, 0x0012f900, 0x0013ba00, 0x90127b01, + 0x00113c00, 0x9010fd01, 0x9011be01, 0x00107f00, 0x90314001, + 0x00308100, 0x0031c200, 0x90300301, 0x00334400, 0x90328501, + 0x9033c601, 0x00320700, 0x00364800, 0x90378901, 0x9036ca01, + 0x00370b00, 0x90344c01, 0x00358d00, 0x0034ce00, 0x90350f01, + 0x003c5000, 0x903d9101, 0x903cd201, 0x003d1300, 0x903e5401, + 0x003f9500, 0x003ed600, 0x903f1701, 0x903b5801, 0x003a9900, + 0x003bda00, 0x903a1b01, 0x00395c00, 0x90389d01, 0x9039de01, + 0x00381f00, 0x00286000, 0x9029a101, 0x9028e201, 0x00292300, + 0x902a6401, 0x002ba500, 0x002ae600, 0x902b2701, 0x902f6801, + 0x002ea900, 0x002fea00, 0x902e2b01, 0x002d6c00, 0x902cad01, + 0x902dee01, 0x002c2f00, 0x90257001, 0x0024b100, 0x0025f200, + 0x90243301, 0x00277400, 0x9026b501, 0x9027f601, 0x00263700, + 0x00227800, 0x9023b901, 0x9022fa01, 0x00233b00, 0x90207c01, + 0x0021bd00, 0x0020fe00, 0x90213f01, 0x90618001, 0x00604100, + 0x00610200, 0x9060c301, 0x00638400, 0x90624501, 0x90630601, + 0x0062c700, 0x00668800, 0x90674901, 0x90660a01, 0x0067cb00, + 0x90648c01, 0x00654d00, 0x00640e00, 0x9065cf01, 0x006c9000, + 0x906d5101, 0x906c1201, 0x006dd300, 0x906e9401, 0x006f5500, + 0x006e1600, 0x906fd701, 0x906b9801, 0x006a5900, 0x006b1a00, + 0x906adb01, 0x00699c00, 0x90685d01, 0x90691e01, 0x0068df00, + 0x0078a000, 0x90796101, 0x90782201, 0x0079e300, 0x907aa401, + 0x007b6500, 0x007a2600, 0x907be701, 0x907fa801, 0x007e6900, + 0x007f2a00, 0x907eeb01, 0x007dac00, 0x907c6d01, 0x907d2e01, + 0x007cef00, 0x9075b001, 0x00747100, 0x00753200, 0x9074f301, + 0x0077b400, 0x90767501, 0x90773601, 0x0076f700, 0x0072b800, + 0x90737901, 0x90723a01, 0x0073fb00, 0x9070bc01, 0x00717d00, + 0x00703e00, 0x9071ff01, 0x0050c000, 0x90510101, 0x90504201, + 0x00518300, 0x9052c401, 0x00530500, 0x00524600, 0x90538701, + 0x9057c801, 0x00560900, 0x00574a00, 0x90568b01, 0x0055cc00, + 0x90540d01, 0x90554e01, 0x00548f00, 0x905dd001, 0x005c1100, + 0x005d5200, 0x905c9301, 0x005fd400, 0x905e1501, 0x905f5601, + 0x005e9700, 0x005ad800, 0x905b1901, 0x905a5a01, 0x005b9b00, + 0x9058dc01, 0x00591d00, 0x00585e00, 0x90599f01, 0x9049e001, + 0x00482100, 0x00496200, 0x9048a301, 0x004be400, 0x904a2501, + 0x904b6601, 0x004aa700, 0x004ee800, 0x904f2901, 0x904e6a01, + 0x004fab00, 0x904cec01, 0x004d2d00, 0x004c6e00, 0x904daf01, + 0x0044f000, 0x90453101, 0x90447201, 0x0045b300, 0x9046f401, + 0x00473500, 0x00467600, 0x9047b701, 0x9043f801, 0x00423900, + 0x00437a00, 0x9042bb01, 0x0041fc00, 0x90403d01, 0x90417e01, + 0x0040bf00}, + {0x00000000, 0x90c00001, 0x91830001, 0x01430000, 0x93050001, + 0x03c50000, 0x02860000, 0x92460001, 0x96090001, 0x06c90000, + 0x078a0000, 0x974a0001, 0x050c0000, 0x95cc0001, 0x948f0001, + 0x044f0000, 0x9c110001, 0x0cd10000, 0x0d920000, 0x9d520001, + 0x0f140000, 0x9fd40001, 0x9e970001, 0x0e570000, 0x0a180000, + 0x9ad80001, 0x9b9b0001, 0x0b5b0000, 0x991d0001, 0x09dd0000, + 0x089e0000, 0x985e0001, 0x88210001, 0x18e10000, 0x19a20000, + 0x89620001, 0x1b240000, 0x8be40001, 0x8aa70001, 0x1a670000, + 0x1e280000, 0x8ee80001, 0x8fab0001, 0x1f6b0000, 0x8d2d0001, + 0x1ded0000, 0x1cae0000, 0x8c6e0001, 0x14300000, 0x84f00001, + 0x85b30001, 0x15730000, 0x87350001, 0x17f50000, 0x16b60000, + 0x86760001, 0x82390001, 0x12f90000, 0x13ba0000, 0x837a0001, + 0x113c0000, 0x81fc0001, 0x80bf0001, 0x107f0000, 0xa0410001, + 0x30810000, 0x31c20000, 0xa1020001, 0x33440000, 0xa3840001, + 0xa2c70001, 0x32070000, 0x36480000, 0xa6880001, 0xa7cb0001, + 0x370b0000, 0xa54d0001, 0x358d0000, 0x34ce0000, 0xa40e0001, + 0x3c500000, 0xac900001, 0xadd30001, 0x3d130000, 0xaf550001, + 0x3f950000, 0x3ed60000, 0xae160001, 0xaa590001, 0x3a990000, + 0x3bda0000, 0xab1a0001, 0x395c0000, 0xa99c0001, 0xa8df0001, + 0x381f0000, 0x28600000, 0xb8a00001, 0xb9e30001, 0x29230000, + 0xbb650001, 0x2ba50000, 0x2ae60000, 0xba260001, 0xbe690001, + 0x2ea90000, 0x2fea0000, 0xbf2a0001, 0x2d6c0000, 0xbdac0001, + 0xbcef0001, 0x2c2f0000, 0xb4710001, 0x24b10000, 0x25f20000, + 0xb5320001, 0x27740000, 0xb7b40001, 0xb6f70001, 0x26370000, + 0x22780000, 0xb2b80001, 0xb3fb0001, 0x233b0000, 0xb17d0001, + 0x21bd0000, 0x20fe0000, 0xb03e0001, 0xf0810001, 0x60410000, + 0x61020000, 0xf1c20001, 0x63840000, 0xf3440001, 0xf2070001, + 0x62c70000, 0x66880000, 0xf6480001, 0xf70b0001, 0x67cb0000, + 0xf58d0001, 0x654d0000, 0x640e0000, 0xf4ce0001, 0x6c900000, + 0xfc500001, 0xfd130001, 0x6dd30000, 0xff950001, 0x6f550000, + 0x6e160000, 0xfed60001, 0xfa990001, 0x6a590000, 0x6b1a0000, + 0xfbda0001, 0x699c0000, 0xf95c0001, 0xf81f0001, 0x68df0000, + 0x78a00000, 0xe8600001, 0xe9230001, 0x79e30000, 0xeba50001, + 0x7b650000, 0x7a260000, 0xeae60001, 0xeea90001, 0x7e690000, + 0x7f2a0000, 0xefea0001, 0x7dac0000, 0xed6c0001, 0xec2f0001, + 0x7cef0000, 0xe4b10001, 0x74710000, 0x75320000, 0xe5f20001, + 0x77b40000, 0xe7740001, 0xe6370001, 0x76f70000, 0x72b80000, + 0xe2780001, 0xe33b0001, 0x73fb0000, 0xe1bd0001, 0x717d0000, + 0x703e0000, 0xe0fe0001, 0x50c00000, 0xc0000001, 0xc1430001, + 0x51830000, 0xc3c50001, 0x53050000, 0x52460000, 0xc2860001, + 0xc6c90001, 0x56090000, 0x574a0000, 0xc78a0001, 0x55cc0000, + 0xc50c0001, 0xc44f0001, 0x548f0000, 0xccd10001, 0x5c110000, + 0x5d520000, 0xcd920001, 0x5fd40000, 0xcf140001, 0xce570001, + 0x5e970000, 0x5ad80000, 0xca180001, 0xcb5b0001, 0x5b9b0000, + 0xc9dd0001, 0x591d0000, 0x585e0000, 0xc89e0001, 0xd8e10001, + 0x48210000, 0x49620000, 0xd9a20001, 0x4be40000, 0xdb240001, + 0xda670001, 0x4aa70000, 0x4ee80000, 0xde280001, 0xdf6b0001, + 0x4fab0000, 0xdded0001, 0x4d2d0000, 0x4c6e0000, 0xdcae0001, + 0x44f00000, 0xd4300001, 0xd5730001, 0x45b30000, 0xd7f50001, + 0x47350000, 0x46760000, 0xd6b60001, 0xd2f90001, 0x42390000, + 0x437a0000, 0xd3ba0001, 0x41fc0000, 0xd13c0001, 0xd07f0001, + 0x40bf0000}, + {0x00000000, 0x51010001, 0xa2020002, 0xf3030003, 0xf4070007, + 0xa5060006, 0x56050005, 0x07040004, 0x580d000d, 0x090c000c, + 0xfa0f000f, 0xab0e000e, 0xac0a000a, 0xfd0b000b, 0x0e080008, + 0x5f090009, 0xb01a001a, 0xe11b001b, 0x12180018, 0x43190019, + 0x441d001d, 0x151c001c, 0xe61f001f, 0xb71e001e, 0xe8170017, + 0xb9160016, 0x4a150015, 0x1b140014, 0x1c100010, 0x4d110011, + 0xbe120012, 0xef130013, 0xd0370037, 0x81360036, 0x72350035, + 0x23340034, 0x24300030, 0x75310031, 0x86320032, 0xd7330033, + 0x883a003a, 0xd93b003b, 0x2a380038, 0x7b390039, 0x7c3d003d, + 0x2d3c003c, 0xde3f003f, 0x8f3e003e, 0x602d002d, 0x312c002c, + 0xc22f002f, 0x932e002e, 0x942a002a, 0xc52b002b, 0x36280028, + 0x67290029, 0x38200020, 0x69210021, 0x9a220022, 0xcb230023, + 0xcc270027, 0x9d260026, 0x6e250025, 0x3f240024, 0x106d006d, + 0x416c006c, 0xb26f006f, 0xe36e006e, 0xe46a006a, 0xb56b006b, + 0x46680068, 0x17690069, 0x48600060, 0x19610061, 0xea620062, + 0xbb630063, 0xbc670067, 0xed660066, 0x1e650065, 0x4f640064, + 0xa0770077, 0xf1760076, 0x02750075, 0x53740074, 0x54700070, + 0x05710071, 0xf6720072, 0xa7730073, 0xf87a007a, 0xa97b007b, + 0x5a780078, 0x0b790079, 0x0c7d007d, 0x5d7c007c, 0xae7f007f, + 0xff7e007e, 0xc05a005a, 0x915b005b, 0x62580058, 0x33590059, + 0x345d005d, 0x655c005c, 0x965f005f, 0xc75e005e, 0x98570057, + 0xc9560056, 0x3a550055, 0x6b540054, 0x6c500050, 0x3d510051, + 0xce520052, 0x9f530053, 0x70400040, 0x21410041, 0xd2420042, + 0x83430043, 0x84470047, 0xd5460046, 0x26450045, 0x77440044, + 0x284d004d, 0x794c004c, 0x8a4f004f, 0xdb4e004e, 0xdc4a004a, + 0x8d4b004b, 0x7e480048, 0x2f490049, 0x20da00da, 0x71db00db, + 0x82d800d8, 0xd3d900d9, 0xd4dd00dd, 0x85dc00dc, 0x76df00df, + 0x27de00de, 0x78d700d7, 0x29d600d6, 0xdad500d5, 0x8bd400d4, + 0x8cd000d0, 0xddd100d1, 0x2ed200d2, 0x7fd300d3, 0x90c000c0, + 0xc1c100c1, 0x32c200c2, 0x63c300c3, 0x64c700c7, 0x35c600c6, + 0xc6c500c5, 0x97c400c4, 0xc8cd00cd, 0x99cc00cc, 0x6acf00cf, + 0x3bce00ce, 0x3cca00ca, 0x6dcb00cb, 0x9ec800c8, 0xcfc900c9, + 0xf0ed00ed, 0xa1ec00ec, 0x52ef00ef, 0x03ee00ee, 0x04ea00ea, + 0x55eb00eb, 0xa6e800e8, 0xf7e900e9, 0xa8e000e0, 0xf9e100e1, + 0x0ae200e2, 0x5be300e3, 0x5ce700e7, 0x0de600e6, 0xfee500e5, + 0xafe400e4, 0x40f700f7, 0x11f600f6, 0xe2f500f5, 0xb3f400f4, + 0xb4f000f0, 0xe5f100f1, 0x16f200f2, 0x47f300f3, 0x18fa00fa, + 0x49fb00fb, 0xbaf800f8, 0xebf900f9, 0xecfd00fd, 0xbdfc00fc, + 0x4eff00ff, 0x1ffe00fe, 0x30b700b7, 0x61b600b6, 0x92b500b5, + 0xc3b400b4, 0xc4b000b0, 0x95b100b1, 0x66b200b2, 0x37b300b3, + 0x68ba00ba, 0x39bb00bb, 0xcab800b8, 0x9bb900b9, 0x9cbd00bd, + 0xcdbc00bc, 0x3ebf00bf, 0x6fbe00be, 0x80ad00ad, 0xd1ac00ac, + 0x22af00af, 0x73ae00ae, 0x74aa00aa, 0x25ab00ab, 0xd6a800a8, + 0x87a900a9, 0xd8a000a0, 0x89a100a1, 0x7aa200a2, 0x2ba300a3, + 0x2ca700a7, 0x7da600a6, 0x8ea500a5, 0xdfa400a4, 0xe0800080, + 0xb1810081, 0x42820082, 0x13830083, 0x14870087, 0x45860086, + 0xb6850085, 0xe7840084, 0xb88d008d, 0xe98c008c, 0x1a8f008f, + 0x4b8e008e, 0x4c8a008a, 0x1d8b008b, 0xee880088, 0xbf890089, + 0x509a009a, 0x019b009b, 0xf2980098, 0xa3990099, 0xa49d009d, + 0xf59c009c, 0x069f009f, 0x579e009e, 0x08970097, 0x59960096, + 0xaa950095, 0xfb940094, 0xfc900090, 0xad910091, 0x5e920092, + 0x0f930093}, + {0x00000000, 0x41b401b4, 0x83680368, 0xc2dc02dc, 0xb6d306d3, + 0xf7670767, 0x35bb05bb, 0x740f040f, 0xdda50da5, 0x9c110c11, + 0x5ecd0ecd, 0x1f790f79, 0x6b760b76, 0x2ac20ac2, 0xe81e081e, + 0xa9aa09aa, 0x0b491b49, 0x4afd1afd, 0x88211821, 0xc9951995, + 0xbd9a1d9a, 0xfc2e1c2e, 0x3ef21ef2, 0x7f461f46, 0xd6ec16ec, + 0x97581758, 0x55841584, 0x14301430, 0x603f103f, 0x218b118b, + 0xe3571357, 0xa2e312e3, 0x16923692, 0x57263726, 0x95fa35fa, + 0xd44e344e, 0xa0413041, 0xe1f531f5, 0x23293329, 0x629d329d, + 0xcb373b37, 0x8a833a83, 0x485f385f, 0x09eb39eb, 0x7de43de4, + 0x3c503c50, 0xfe8c3e8c, 0xbf383f38, 0x1ddb2ddb, 0x5c6f2c6f, + 0x9eb32eb3, 0xdf072f07, 0xab082b08, 0xeabc2abc, 0x28602860, + 0x69d429d4, 0xc07e207e, 0x81ca21ca, 0x43162316, 0x02a222a2, + 0x76ad26ad, 0x37192719, 0xf5c525c5, 0xb4712471, 0x2d246d24, + 0x6c906c90, 0xae4c6e4c, 0xeff86ff8, 0x9bf76bf7, 0xda436a43, + 0x189f689f, 0x592b692b, 0xf0816081, 0xb1356135, 0x73e963e9, + 0x325d625d, 0x46526652, 0x07e667e6, 0xc53a653a, 0x848e648e, + 0x266d766d, 0x67d977d9, 0xa5057505, 0xe4b174b1, 0x90be70be, + 0xd10a710a, 0x13d673d6, 0x52627262, 0xfbc87bc8, 0xba7c7a7c, + 0x78a078a0, 0x39147914, 0x4d1b7d1b, 0x0caf7caf, 0xce737e73, + 0x8fc77fc7, 0x3bb65bb6, 0x7a025a02, 0xb8de58de, 0xf96a596a, + 0x8d655d65, 0xccd15cd1, 0x0e0d5e0d, 0x4fb95fb9, 0xe6135613, + 0xa7a757a7, 0x657b557b, 0x24cf54cf, 0x50c050c0, 0x11745174, + 0xd3a853a8, 0x921c521c, 0x30ff40ff, 0x714b414b, 0xb3974397, + 0xf2234223, 0x862c462c, 0xc7984798, 0x05444544, 0x44f044f0, + 0xed5a4d5a, 0xacee4cee, 0x6e324e32, 0x2f864f86, 0x5b894b89, + 0x1a3d4a3d, 0xd8e148e1, 0x99554955, 0x5a48da48, 0x1bfcdbfc, + 0xd920d920, 0x9894d894, 0xec9bdc9b, 0xad2fdd2f, 0x6ff3dff3, + 0x2e47de47, 0x87edd7ed, 0xc659d659, 0x0485d485, 0x4531d531, + 0x313ed13e, 0x708ad08a, 0xb256d256, 0xf3e2d3e2, 0x5101c101, + 0x10b5c0b5, 0xd269c269, 0x93ddc3dd, 0xe7d2c7d2, 0xa666c666, + 0x64bac4ba, 0x250ec50e, 0x8ca4cca4, 0xcd10cd10, 0x0fcccfcc, + 0x4e78ce78, 0x3a77ca77, 0x7bc3cbc3, 0xb91fc91f, 0xf8abc8ab, + 0x4cdaecda, 0x0d6eed6e, 0xcfb2efb2, 0x8e06ee06, 0xfa09ea09, + 0xbbbdebbd, 0x7961e961, 0x38d5e8d5, 0x917fe17f, 0xd0cbe0cb, + 0x1217e217, 0x53a3e3a3, 0x27ace7ac, 0x6618e618, 0xa4c4e4c4, + 0xe570e570, 0x4793f793, 0x0627f627, 0xc4fbf4fb, 0x854ff54f, + 0xf140f140, 0xb0f4f0f4, 0x7228f228, 0x339cf39c, 0x9a36fa36, + 0xdb82fb82, 0x195ef95e, 0x58eaf8ea, 0x2ce5fce5, 0x6d51fd51, + 0xaf8dff8d, 0xee39fe39, 0x776cb76c, 0x36d8b6d8, 0xf404b404, + 0xb5b0b5b0, 0xc1bfb1bf, 0x800bb00b, 0x42d7b2d7, 0x0363b363, + 0xaac9bac9, 0xeb7dbb7d, 0x29a1b9a1, 0x6815b815, 0x1c1abc1a, + 0x5daebdae, 0x9f72bf72, 0xdec6bec6, 0x7c25ac25, 0x3d91ad91, + 0xff4daf4d, 0xbef9aef9, 0xcaf6aaf6, 0x8b42ab42, 0x499ea99e, + 0x082aa82a, 0xa180a180, 0xe034a034, 0x22e8a2e8, 0x635ca35c, + 0x1753a753, 0x56e7a6e7, 0x943ba43b, 0xd58fa58f, 0x61fe81fe, + 0x204a804a, 0xe2968296, 0xa3228322, 0xd72d872d, 0x96998699, + 0x54458445, 0x15f185f1, 0xbc5b8c5b, 0xfdef8def, 0x3f338f33, + 0x7e878e87, 0x0a888a88, 0x4b3c8b3c, 0x89e089e0, 0xc8548854, + 0x6ab79ab7, 0x2b039b03, 0xe9df99df, 0xa86b986b, 0xdc649c64, + 0x9dd09dd0, 0x5f0c9f0c, 0x1eb89eb8, 0xb7129712, 0xf6a696a6, + 0x347a947a, 0x75ce95ce, 0x01c191c1, 0x40759075, 0x82a992a9, + 0xc31d931d}, + {0x00000000, 0xb491b490, 0xd9206923, 0x6db1ddb3, 0x0243d245, + 0xb6d266d5, 0xdb63bb66, 0x6ff20ff6, 0x0487a48a, 0xb016101a, + 0xdda7cda9, 0x69367939, 0x06c476cf, 0xb255c25f, 0xdfe41fec, + 0x6b75ab7c, 0x090f4914, 0xbd9efd84, 0xd02f2037, 0x64be94a7, + 0x0b4c9b51, 0xbfdd2fc1, 0xd26cf272, 0x66fd46e2, 0x0d88ed9e, + 0xb919590e, 0xd4a884bd, 0x6039302d, 0x0fcb3fdb, 0xbb5a8b4b, + 0xd6eb56f8, 0x627ae268, 0x121e9228, 0xa68f26b8, 0xcb3efb0b, + 0x7faf4f9b, 0x105d406d, 0xa4ccf4fd, 0xc97d294e, 0x7dec9dde, + 0x169936a2, 0xa2088232, 0xcfb95f81, 0x7b28eb11, 0x14dae4e7, + 0xa04b5077, 0xcdfa8dc4, 0x796b3954, 0x1b11db3c, 0xaf806fac, + 0xc231b21f, 0x76a0068f, 0x19520979, 0xadc3bde9, 0xc072605a, + 0x74e3d4ca, 0x1f967fb6, 0xab07cb26, 0xc6b61695, 0x7227a205, + 0x1dd5adf3, 0xa9441963, 0xc4f5c4d0, 0x70647040, 0x243d2450, + 0x90ac90c0, 0xfd1d4d73, 0x498cf9e3, 0x267ef615, 0x92ef4285, + 0xff5e9f36, 0x4bcf2ba6, 0x20ba80da, 0x942b344a, 0xf99ae9f9, + 0x4d0b5d69, 0x22f9529f, 0x9668e60f, 0xfbd93bbc, 0x4f488f2c, + 0x2d326d44, 0x99a3d9d4, 0xf4120467, 0x4083b0f7, 0x2f71bf01, + 0x9be00b91, 0xf651d622, 0x42c062b2, 0x29b5c9ce, 0x9d247d5e, + 0xf095a0ed, 0x4404147d, 0x2bf61b8b, 0x9f67af1b, 0xf2d672a8, + 0x4647c638, 0x3623b678, 0x82b202e8, 0xef03df5b, 0x5b926bcb, + 0x3460643d, 0x80f1d0ad, 0xed400d1e, 0x59d1b98e, 0x32a412f2, + 0x8635a662, 0xeb847bd1, 0x5f15cf41, 0x30e7c0b7, 0x84767427, + 0xe9c7a994, 0x5d561d04, 0x3f2cff6c, 0x8bbd4bfc, 0xe60c964f, + 0x529d22df, 0x3d6f2d29, 0x89fe99b9, 0xe44f440a, 0x50def09a, + 0x3bab5be6, 0x8f3aef76, 0xe28b32c5, 0x561a8655, 0x39e889a3, + 0x8d793d33, 0xe0c8e080, 0x54595410, 0x487a48a0, 0xfcebfc30, + 0x915a2183, 0x25cb9513, 0x4a399ae5, 0xfea82e75, 0x9319f3c6, + 0x27884756, 0x4cfdec2a, 0xf86c58ba, 0x95dd8509, 0x214c3199, + 0x4ebe3e6f, 0xfa2f8aff, 0x979e574c, 0x230fe3dc, 0x417501b4, + 0xf5e4b524, 0x98556897, 0x2cc4dc07, 0x4336d3f1, 0xf7a76761, + 0x9a16bad2, 0x2e870e42, 0x45f2a53e, 0xf16311ae, 0x9cd2cc1d, + 0x2843788d, 0x47b1777b, 0xf320c3eb, 0x9e911e58, 0x2a00aac8, + 0x5a64da88, 0xeef56e18, 0x8344b3ab, 0x37d5073b, 0x582708cd, + 0xecb6bc5d, 0x810761ee, 0x3596d57e, 0x5ee37e02, 0xea72ca92, + 0x87c31721, 0x3352a3b1, 0x5ca0ac47, 0xe83118d7, 0x8580c564, + 0x311171f4, 0x536b939c, 0xe7fa270c, 0x8a4bfabf, 0x3eda4e2f, + 0x512841d9, 0xe5b9f549, 0x880828fa, 0x3c999c6a, 0x57ec3716, + 0xe37d8386, 0x8ecc5e35, 0x3a5deaa5, 0x55afe553, 0xe13e51c3, + 0x8c8f8c70, 0x381e38e0, 0x6c476cf0, 0xd8d6d860, 0xb56705d3, + 0x01f6b143, 0x6e04beb5, 0xda950a25, 0xb724d796, 0x03b56306, + 0x68c0c87a, 0xdc517cea, 0xb1e0a159, 0x057115c9, 0x6a831a3f, + 0xde12aeaf, 0xb3a3731c, 0x0732c78c, 0x654825e4, 0xd1d99174, + 0xbc684cc7, 0x08f9f857, 0x670bf7a1, 0xd39a4331, 0xbe2b9e82, + 0x0aba2a12, 0x61cf816e, 0xd55e35fe, 0xb8efe84d, 0x0c7e5cdd, + 0x638c532b, 0xd71de7bb, 0xbaac3a08, 0x0e3d8e98, 0x7e59fed8, + 0xcac84a48, 0xa77997fb, 0x13e8236b, 0x7c1a2c9d, 0xc88b980d, + 0xa53a45be, 0x11abf12e, 0x7ade5a52, 0xce4feec2, 0xa3fe3371, + 0x176f87e1, 0x789d8817, 0xcc0c3c87, 0xa1bde134, 0x152c55a4, + 0x7756b7cc, 0xc3c7035c, 0xae76deef, 0x1ae76a7f, 0x75156589, + 0xc184d119, 0xac350caa, 0x18a4b83a, 0x73d11346, 0xc740a7d6, + 0xaaf17a65, 0x1e60cef5, 0x7192c103, 0xc5037593, 0xa8b2a820, + 0x1c231cb0}, + {0x00000000, 0x90f49140, 0x91ea2283, 0x011eb3c3, 0x93d74505, + 0x0323d445, 0x023d6786, 0x92c9f6c6, 0x97ad8a09, 0x07591b49, + 0x0647a88a, 0x96b339ca, 0x047acf0c, 0x948e5e4c, 0x9590ed8f, + 0x05647ccf, 0x9f581411, 0x0fac8551, 0x0eb23692, 0x9e46a7d2, + 0x0c8f5114, 0x9c7bc054, 0x9d657397, 0x0d91e2d7, 0x08f59e18, + 0x98010f58, 0x991fbc9b, 0x09eb2ddb, 0x9b22db1d, 0x0bd64a5d, + 0x0ac8f99e, 0x9a3c68de, 0x8eb32821, 0x1e47b961, 0x1f590aa2, + 0x8fad9be2, 0x1d646d24, 0x8d90fc64, 0x8c8e4fa7, 0x1c7adee7, + 0x191ea228, 0x89ea3368, 0x88f480ab, 0x180011eb, 0x8ac9e72d, + 0x1a3d766d, 0x1b23c5ae, 0x8bd754ee, 0x11eb3c30, 0x811fad70, + 0x80011eb3, 0x10f58ff3, 0x823c7935, 0x12c8e875, 0x13d65bb6, + 0x8322caf6, 0x8646b639, 0x16b22779, 0x17ac94ba, 0x875805fa, + 0x1591f33c, 0x8565627c, 0x847bd1bf, 0x148f40ff, 0xad655041, + 0x3d91c101, 0x3c8f72c2, 0xac7be382, 0x3eb21544, 0xae468404, + 0xaf5837c7, 0x3faca687, 0x3ac8da48, 0xaa3c4b08, 0xab22f8cb, + 0x3bd6698b, 0xa91f9f4d, 0x39eb0e0d, 0x38f5bdce, 0xa8012c8e, + 0x323d4450, 0xa2c9d510, 0xa3d766d3, 0x3323f793, 0xa1ea0155, + 0x311e9015, 0x300023d6, 0xa0f4b296, 0xa590ce59, 0x35645f19, + 0x347aecda, 0xa48e7d9a, 0x36478b5c, 0xa6b31a1c, 0xa7ada9df, + 0x3759389f, 0x23d67860, 0xb322e920, 0xb23c5ae3, 0x22c8cba3, + 0xb0013d65, 0x20f5ac25, 0x21eb1fe6, 0xb11f8ea6, 0xb47bf269, + 0x248f6329, 0x2591d0ea, 0xb56541aa, 0x27acb76c, 0xb758262c, + 0xb64695ef, 0x26b204af, 0xbc8e6c71, 0x2c7afd31, 0x2d644ef2, + 0xbd90dfb2, 0x2f592974, 0xbfadb834, 0xbeb30bf7, 0x2e479ab7, + 0x2b23e678, 0xbbd77738, 0xbac9c4fb, 0x2a3d55bb, 0xb8f4a37d, + 0x2800323d, 0x291e81fe, 0xb9ea10be, 0xeac9a081, 0x7a3d31c1, + 0x7b238202, 0xebd71342, 0x791ee584, 0xe9ea74c4, 0xe8f4c707, + 0x78005647, 0x7d642a88, 0xed90bbc8, 0xec8e080b, 0x7c7a994b, + 0xeeb36f8d, 0x7e47fecd, 0x7f594d0e, 0xefaddc4e, 0x7591b490, + 0xe56525d0, 0xe47b9613, 0x748f0753, 0xe646f195, 0x76b260d5, + 0x77acd316, 0xe7584256, 0xe23c3e99, 0x72c8afd9, 0x73d61c1a, + 0xe3228d5a, 0x71eb7b9c, 0xe11feadc, 0xe001591f, 0x70f5c85f, + 0x647a88a0, 0xf48e19e0, 0xf590aa23, 0x65643b63, 0xf7adcda5, + 0x67595ce5, 0x6647ef26, 0xf6b37e66, 0xf3d702a9, 0x632393e9, + 0x623d202a, 0xf2c9b16a, 0x600047ac, 0xf0f4d6ec, 0xf1ea652f, + 0x611ef46f, 0xfb229cb1, 0x6bd60df1, 0x6ac8be32, 0xfa3c2f72, + 0x68f5d9b4, 0xf80148f4, 0xf91ffb37, 0x69eb6a77, 0x6c8f16b8, + 0xfc7b87f8, 0xfd65343b, 0x6d91a57b, 0xff5853bd, 0x6facc2fd, + 0x6eb2713e, 0xfe46e07e, 0x47acf0c0, 0xd7586180, 0xd646d243, + 0x46b24303, 0xd47bb5c5, 0x448f2485, 0x45919746, 0xd5650606, + 0xd0017ac9, 0x40f5eb89, 0x41eb584a, 0xd11fc90a, 0x43d63fcc, + 0xd322ae8c, 0xd23c1d4f, 0x42c88c0f, 0xd8f4e4d1, 0x48007591, + 0x491ec652, 0xd9ea5712, 0x4b23a1d4, 0xdbd73094, 0xdac98357, + 0x4a3d1217, 0x4f596ed8, 0xdfadff98, 0xdeb34c5b, 0x4e47dd1b, + 0xdc8e2bdd, 0x4c7aba9d, 0x4d64095e, 0xdd90981e, 0xc91fd8e1, + 0x59eb49a1, 0x58f5fa62, 0xc8016b22, 0x5ac89de4, 0xca3c0ca4, + 0xcb22bf67, 0x5bd62e27, 0x5eb252e8, 0xce46c3a8, 0xcf58706b, + 0x5face12b, 0xcd6517ed, 0x5d9186ad, 0x5c8f356e, 0xcc7ba42e, + 0x5647ccf0, 0xc6b35db0, 0xc7adee73, 0x57597f33, 0xc59089f5, + 0x556418b5, 0x547aab76, 0xc48e3a36, 0xc1ea46f9, 0x511ed7b9, + 0x5000647a, 0xc0f4f53a, 0x523d03fc, 0xc2c992bc, 0xc3d7217f, + 0x5323b03f}}; + +static const word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x4091f49000000000, 0x8322ea9100000000, + 0xc3b31e0100000000, 0x0545d79300000000, 0x45d4230300000000, + 0x86673d0200000000, 0xc6f6c99200000000, 0x098aad9700000000, + 0x491b590700000000, 0x8aa8470600000000, 0xca39b39600000000, + 0x0ccf7a0400000000, 0x4c5e8e9400000000, 0x8fed909500000000, + 0xcf7c640500000000, 0x1114589f00000000, 0x5185ac0f00000000, + 0x9236b20e00000000, 0xd2a7469e00000000, 0x14518f0c00000000, + 0x54c07b9c00000000, 0x9773659d00000000, 0xd7e2910d00000000, + 0x189ef50800000000, 0x580f019800000000, 0x9bbc1f9900000000, + 0xdb2deb0900000000, 0x1ddb229b00000000, 0x5d4ad60b00000000, + 0x9ef9c80a00000000, 0xde683c9a00000000, 0x2128b38e00000000, + 0x61b9471e00000000, 0xa20a591f00000000, 0xe29bad8f00000000, + 0x246d641d00000000, 0x64fc908d00000000, 0xa74f8e8c00000000, + 0xe7de7a1c00000000, 0x28a21e1900000000, 0x6833ea8900000000, + 0xab80f48800000000, 0xeb11001800000000, 0x2de7c98a00000000, + 0x6d763d1a00000000, 0xaec5231b00000000, 0xee54d78b00000000, + 0x303ceb1100000000, 0x70ad1f8100000000, 0xb31e018000000000, + 0xf38ff51000000000, 0x35793c8200000000, 0x75e8c81200000000, + 0xb65bd61300000000, 0xf6ca228300000000, 0x39b6468600000000, + 0x7927b21600000000, 0xba94ac1700000000, 0xfa05588700000000, + 0x3cf3911500000000, 0x7c62658500000000, 0xbfd17b8400000000, + 0xff408f1400000000, 0x415065ad00000000, 0x01c1913d00000000, + 0xc2728f3c00000000, 0x82e37bac00000000, 0x4415b23e00000000, + 0x048446ae00000000, 0xc73758af00000000, 0x87a6ac3f00000000, + 0x48dac83a00000000, 0x084b3caa00000000, 0xcbf822ab00000000, + 0x8b69d63b00000000, 0x4d9f1fa900000000, 0x0d0eeb3900000000, + 0xcebdf53800000000, 0x8e2c01a800000000, 0x50443d3200000000, + 0x10d5c9a200000000, 0xd366d7a300000000, 0x93f7233300000000, + 0x5501eaa100000000, 0x15901e3100000000, 0xd623003000000000, + 0x96b2f4a000000000, 0x59ce90a500000000, 0x195f643500000000, + 0xdaec7a3400000000, 0x9a7d8ea400000000, 0x5c8b473600000000, + 0x1c1ab3a600000000, 0xdfa9ada700000000, 0x9f38593700000000, + 0x6078d62300000000, 0x20e922b300000000, 0xe35a3cb200000000, + 0xa3cbc82200000000, 0x653d01b000000000, 0x25acf52000000000, + 0xe61feb2100000000, 0xa68e1fb100000000, 0x69f27bb400000000, + 0x29638f2400000000, 0xead0912500000000, 0xaa4165b500000000, + 0x6cb7ac2700000000, 0x2c2658b700000000, 0xef9546b600000000, + 0xaf04b22600000000, 0x716c8ebc00000000, 0x31fd7a2c00000000, + 0xf24e642d00000000, 0xb2df90bd00000000, 0x7429592f00000000, + 0x34b8adbf00000000, 0xf70bb3be00000000, 0xb79a472e00000000, + 0x78e6232b00000000, 0x3877d7bb00000000, 0xfbc4c9ba00000000, + 0xbb553d2a00000000, 0x7da3f4b800000000, 0x3d32002800000000, + 0xfe811e2900000000, 0xbe10eab900000000, 0x81a0c9ea00000000, + 0xc1313d7a00000000, 0x0282237b00000000, 0x4213d7eb00000000, + 0x84e51e7900000000, 0xc474eae900000000, 0x07c7f4e800000000, + 0x4756007800000000, 0x882a647d00000000, 0xc8bb90ed00000000, + 0x0b088eec00000000, 0x4b997a7c00000000, 0x8d6fb3ee00000000, + 0xcdfe477e00000000, 0x0e4d597f00000000, 0x4edcadef00000000, + 0x90b4917500000000, 0xd02565e500000000, 0x13967be400000000, + 0x53078f7400000000, 0x95f146e600000000, 0xd560b27600000000, + 0x16d3ac7700000000, 0x564258e700000000, 0x993e3ce200000000, + 0xd9afc87200000000, 0x1a1cd67300000000, 0x5a8d22e300000000, + 0x9c7beb7100000000, 0xdcea1fe100000000, 0x1f5901e000000000, + 0x5fc8f57000000000, 0xa0887a6400000000, 0xe0198ef400000000, + 0x23aa90f500000000, 0x633b646500000000, 0xa5cdadf700000000, + 0xe55c596700000000, 0x26ef476600000000, 0x667eb3f600000000, + 0xa902d7f300000000, 0xe993236300000000, 0x2a203d6200000000, + 0x6ab1c9f200000000, 0xac47006000000000, 0xecd6f4f000000000, + 0x2f65eaf100000000, 0x6ff41e6100000000, 0xb19c22fb00000000, + 0xf10dd66b00000000, 0x32bec86a00000000, 0x722f3cfa00000000, + 0xb4d9f56800000000, 0xf44801f800000000, 0x37fb1ff900000000, + 0x776aeb6900000000, 0xb8168f6c00000000, 0xf8877bfc00000000, + 0x3b3465fd00000000, 0x7ba5916d00000000, 0xbd5358ff00000000, + 0xfdc2ac6f00000000, 0x3e71b26e00000000, 0x7ee046fe00000000, + 0xc0f0ac4700000000, 0x806158d700000000, 0x43d246d600000000, + 0x0343b24600000000, 0xc5b57bd400000000, 0x85248f4400000000, + 0x4697914500000000, 0x060665d500000000, 0xc97a01d000000000, + 0x89ebf54000000000, 0x4a58eb4100000000, 0x0ac91fd100000000, + 0xcc3fd64300000000, 0x8cae22d300000000, 0x4f1d3cd200000000, + 0x0f8cc84200000000, 0xd1e4f4d800000000, 0x9175004800000000, + 0x52c61e4900000000, 0x1257ead900000000, 0xd4a1234b00000000, + 0x9430d7db00000000, 0x5783c9da00000000, 0x17123d4a00000000, + 0xd86e594f00000000, 0x98ffaddf00000000, 0x5b4cb3de00000000, + 0x1bdd474e00000000, 0xdd2b8edc00000000, 0x9dba7a4c00000000, + 0x5e09644d00000000, 0x1e9890dd00000000, 0xe1d81fc900000000, + 0xa149eb5900000000, 0x62faf55800000000, 0x226b01c800000000, + 0xe49dc85a00000000, 0xa40c3cca00000000, 0x67bf22cb00000000, + 0x272ed65b00000000, 0xe852b25e00000000, 0xa8c346ce00000000, + 0x6b7058cf00000000, 0x2be1ac5f00000000, 0xed1765cd00000000, + 0xad86915d00000000, 0x6e358f5c00000000, 0x2ea47bcc00000000, + 0xf0cc475600000000, 0xb05db3c600000000, 0x73eeadc700000000, + 0x337f595700000000, 0xf58990c500000000, 0xb518645500000000, + 0x76ab7a5400000000, 0x363a8ec400000000, 0xf946eac100000000, + 0xb9d71e5100000000, 0x7a64005000000000, 0x3af5f4c000000000, + 0xfc033d5200000000, 0xbc92c9c200000000, 0x7f21d7c300000000, + 0x3fb0235300000000}, + {0x0000000000000000, 0x90b491b400000000, 0x236920d900000000, + 0xb3ddb16d00000000, 0x45d2430200000000, 0xd566d2b600000000, + 0x66bb63db00000000, 0xf60ff26f00000000, 0x8aa4870400000000, + 0x1a1016b000000000, 0xa9cda7dd00000000, 0x3979366900000000, + 0xcf76c40600000000, 0x5fc255b200000000, 0xec1fe4df00000000, + 0x7cab756b00000000, 0x14490f0900000000, 0x84fd9ebd00000000, + 0x37202fd000000000, 0xa794be6400000000, 0x519b4c0b00000000, + 0xc12fddbf00000000, 0x72f26cd200000000, 0xe246fd6600000000, + 0x9eed880d00000000, 0x0e5919b900000000, 0xbd84a8d400000000, + 0x2d30396000000000, 0xdb3fcb0f00000000, 0x4b8b5abb00000000, + 0xf856ebd600000000, 0x68e27a6200000000, 0x28921e1200000000, + 0xb8268fa600000000, 0x0bfb3ecb00000000, 0x9b4faf7f00000000, + 0x6d405d1000000000, 0xfdf4cca400000000, 0x4e297dc900000000, + 0xde9dec7d00000000, 0xa236991600000000, 0x328208a200000000, + 0x815fb9cf00000000, 0x11eb287b00000000, 0xe7e4da1400000000, + 0x77504ba000000000, 0xc48dfacd00000000, 0x54396b7900000000, + 0x3cdb111b00000000, 0xac6f80af00000000, 0x1fb231c200000000, + 0x8f06a07600000000, 0x7909521900000000, 0xe9bdc3ad00000000, + 0x5a6072c000000000, 0xcad4e37400000000, 0xb67f961f00000000, + 0x26cb07ab00000000, 0x9516b6c600000000, 0x05a2277200000000, + 0xf3add51d00000000, 0x631944a900000000, 0xd0c4f5c400000000, + 0x4070647000000000, 0x50243d2400000000, 0xc090ac9000000000, + 0x734d1dfd00000000, 0xe3f98c4900000000, 0x15f67e2600000000, + 0x8542ef9200000000, 0x369f5eff00000000, 0xa62bcf4b00000000, + 0xda80ba2000000000, 0x4a342b9400000000, 0xf9e99af900000000, + 0x695d0b4d00000000, 0x9f52f92200000000, 0x0fe6689600000000, + 0xbc3bd9fb00000000, 0x2c8f484f00000000, 0x446d322d00000000, + 0xd4d9a39900000000, 0x670412f400000000, 0xf7b0834000000000, + 0x01bf712f00000000, 0x910be09b00000000, 0x22d651f600000000, + 0xb262c04200000000, 0xcec9b52900000000, 0x5e7d249d00000000, + 0xeda095f000000000, 0x7d14044400000000, 0x8b1bf62b00000000, + 0x1baf679f00000000, 0xa872d6f200000000, 0x38c6474600000000, + 0x78b6233600000000, 0xe802b28200000000, 0x5bdf03ef00000000, + 0xcb6b925b00000000, 0x3d64603400000000, 0xadd0f18000000000, + 0x1e0d40ed00000000, 0x8eb9d15900000000, 0xf212a43200000000, + 0x62a6358600000000, 0xd17b84eb00000000, 0x41cf155f00000000, + 0xb7c0e73000000000, 0x2774768400000000, 0x94a9c7e900000000, + 0x041d565d00000000, 0x6cff2c3f00000000, 0xfc4bbd8b00000000, + 0x4f960ce600000000, 0xdf229d5200000000, 0x292d6f3d00000000, + 0xb999fe8900000000, 0x0a444fe400000000, 0x9af0de5000000000, + 0xe65bab3b00000000, 0x76ef3a8f00000000, 0xc5328be200000000, + 0x55861a5600000000, 0xa389e83900000000, 0x333d798d00000000, + 0x80e0c8e000000000, 0x1054595400000000, 0xa0487a4800000000, + 0x30fcebfc00000000, 0x83215a9100000000, 0x1395cb2500000000, + 0xe59a394a00000000, 0x752ea8fe00000000, 0xc6f3199300000000, + 0x5647882700000000, 0x2aecfd4c00000000, 0xba586cf800000000, + 0x0985dd9500000000, 0x99314c2100000000, 0x6f3ebe4e00000000, + 0xff8a2ffa00000000, 0x4c579e9700000000, 0xdce30f2300000000, + 0xb401754100000000, 0x24b5e4f500000000, 0x9768559800000000, + 0x07dcc42c00000000, 0xf1d3364300000000, 0x6167a7f700000000, + 0xd2ba169a00000000, 0x420e872e00000000, 0x3ea5f24500000000, + 0xae1163f100000000, 0x1dccd29c00000000, 0x8d78432800000000, + 0x7b77b14700000000, 0xebc320f300000000, 0x581e919e00000000, + 0xc8aa002a00000000, 0x88da645a00000000, 0x186ef5ee00000000, + 0xabb3448300000000, 0x3b07d53700000000, 0xcd08275800000000, + 0x5dbcb6ec00000000, 0xee61078100000000, 0x7ed5963500000000, + 0x027ee35e00000000, 0x92ca72ea00000000, 0x2117c38700000000, + 0xb1a3523300000000, 0x47aca05c00000000, 0xd71831e800000000, + 0x64c5808500000000, 0xf471113100000000, 0x9c936b5300000000, + 0x0c27fae700000000, 0xbffa4b8a00000000, 0x2f4eda3e00000000, + 0xd941285100000000, 0x49f5b9e500000000, 0xfa28088800000000, + 0x6a9c993c00000000, 0x1637ec5700000000, 0x86837de300000000, + 0x355ecc8e00000000, 0xa5ea5d3a00000000, 0x53e5af5500000000, + 0xc3513ee100000000, 0x708c8f8c00000000, 0xe0381e3800000000, + 0xf06c476c00000000, 0x60d8d6d800000000, 0xd30567b500000000, + 0x43b1f60100000000, 0xb5be046e00000000, 0x250a95da00000000, + 0x96d724b700000000, 0x0663b50300000000, 0x7ac8c06800000000, + 0xea7c51dc00000000, 0x59a1e0b100000000, 0xc915710500000000, + 0x3f1a836a00000000, 0xafae12de00000000, 0x1c73a3b300000000, + 0x8cc7320700000000, 0xe425486500000000, 0x7491d9d100000000, + 0xc74c68bc00000000, 0x57f8f90800000000, 0xa1f70b6700000000, + 0x31439ad300000000, 0x829e2bbe00000000, 0x122aba0a00000000, + 0x6e81cf6100000000, 0xfe355ed500000000, 0x4de8efb800000000, + 0xdd5c7e0c00000000, 0x2b538c6300000000, 0xbbe71dd700000000, + 0x083aacba00000000, 0x988e3d0e00000000, 0xd8fe597e00000000, + 0x484ac8ca00000000, 0xfb9779a700000000, 0x6b23e81300000000, + 0x9d2c1a7c00000000, 0x0d988bc800000000, 0xbe453aa500000000, + 0x2ef1ab1100000000, 0x525ade7a00000000, 0xc2ee4fce00000000, + 0x7133fea300000000, 0xe1876f1700000000, 0x17889d7800000000, + 0x873c0ccc00000000, 0x34e1bda100000000, 0xa4552c1500000000, + 0xccb7567700000000, 0x5c03c7c300000000, 0xefde76ae00000000, + 0x7f6ae71a00000000, 0x8965157500000000, 0x19d184c100000000, + 0xaa0c35ac00000000, 0x3ab8a41800000000, 0x4613d17300000000, + 0xd6a740c700000000, 0x657af1aa00000000, 0xf5ce601e00000000, + 0x03c1927100000000, 0x937503c500000000, 0x20a8b2a800000000, + 0xb01c231c00000000}, + {0x0000000000000000, 0xb401b44100000000, 0x6803688300000000, + 0xdc02dcc200000000, 0xd306d3b600000000, 0x670767f700000000, + 0xbb05bb3500000000, 0x0f040f7400000000, 0xa50da5dd00000000, + 0x110c119c00000000, 0xcd0ecd5e00000000, 0x790f791f00000000, + 0x760b766b00000000, 0xc20ac22a00000000, 0x1e081ee800000000, + 0xaa09aaa900000000, 0x491b490b00000000, 0xfd1afd4a00000000, + 0x2118218800000000, 0x951995c900000000, 0x9a1d9abd00000000, + 0x2e1c2efc00000000, 0xf21ef23e00000000, 0x461f467f00000000, + 0xec16ecd600000000, 0x5817589700000000, 0x8415845500000000, + 0x3014301400000000, 0x3f103f6000000000, 0x8b118b2100000000, + 0x571357e300000000, 0xe312e3a200000000, 0x9236921600000000, + 0x2637265700000000, 0xfa35fa9500000000, 0x4e344ed400000000, + 0x413041a000000000, 0xf531f5e100000000, 0x2933292300000000, + 0x9d329d6200000000, 0x373b37cb00000000, 0x833a838a00000000, + 0x5f385f4800000000, 0xeb39eb0900000000, 0xe43de47d00000000, + 0x503c503c00000000, 0x8c3e8cfe00000000, 0x383f38bf00000000, + 0xdb2ddb1d00000000, 0x6f2c6f5c00000000, 0xb32eb39e00000000, + 0x072f07df00000000, 0x082b08ab00000000, 0xbc2abcea00000000, + 0x6028602800000000, 0xd429d46900000000, 0x7e207ec000000000, + 0xca21ca8100000000, 0x1623164300000000, 0xa222a20200000000, + 0xad26ad7600000000, 0x1927193700000000, 0xc525c5f500000000, + 0x712471b400000000, 0x246d242d00000000, 0x906c906c00000000, + 0x4c6e4cae00000000, 0xf86ff8ef00000000, 0xf76bf79b00000000, + 0x436a43da00000000, 0x9f689f1800000000, 0x2b692b5900000000, + 0x816081f000000000, 0x356135b100000000, 0xe963e97300000000, + 0x5d625d3200000000, 0x5266524600000000, 0xe667e60700000000, + 0x3a653ac500000000, 0x8e648e8400000000, 0x6d766d2600000000, + 0xd977d96700000000, 0x057505a500000000, 0xb174b1e400000000, + 0xbe70be9000000000, 0x0a710ad100000000, 0xd673d61300000000, + 0x6272625200000000, 0xc87bc8fb00000000, 0x7c7a7cba00000000, + 0xa078a07800000000, 0x1479143900000000, 0x1b7d1b4d00000000, + 0xaf7caf0c00000000, 0x737e73ce00000000, 0xc77fc78f00000000, + 0xb65bb63b00000000, 0x025a027a00000000, 0xde58deb800000000, + 0x6a596af900000000, 0x655d658d00000000, 0xd15cd1cc00000000, + 0x0d5e0d0e00000000, 0xb95fb94f00000000, 0x135613e600000000, + 0xa757a7a700000000, 0x7b557b6500000000, 0xcf54cf2400000000, + 0xc050c05000000000, 0x7451741100000000, 0xa853a8d300000000, + 0x1c521c9200000000, 0xff40ff3000000000, 0x4b414b7100000000, + 0x974397b300000000, 0x234223f200000000, 0x2c462c8600000000, + 0x984798c700000000, 0x4445440500000000, 0xf044f04400000000, + 0x5a4d5aed00000000, 0xee4ceeac00000000, 0x324e326e00000000, + 0x864f862f00000000, 0x894b895b00000000, 0x3d4a3d1a00000000, + 0xe148e1d800000000, 0x5549559900000000, 0x48da485a00000000, + 0xfcdbfc1b00000000, 0x20d920d900000000, 0x94d8949800000000, + 0x9bdc9bec00000000, 0x2fdd2fad00000000, 0xf3dff36f00000000, + 0x47de472e00000000, 0xedd7ed8700000000, 0x59d659c600000000, + 0x85d4850400000000, 0x31d5314500000000, 0x3ed13e3100000000, + 0x8ad08a7000000000, 0x56d256b200000000, 0xe2d3e2f300000000, + 0x01c1015100000000, 0xb5c0b51000000000, 0x69c269d200000000, + 0xddc3dd9300000000, 0xd2c7d2e700000000, 0x66c666a600000000, + 0xbac4ba6400000000, 0x0ec50e2500000000, 0xa4cca48c00000000, + 0x10cd10cd00000000, 0xcccfcc0f00000000, 0x78ce784e00000000, + 0x77ca773a00000000, 0xc3cbc37b00000000, 0x1fc91fb900000000, + 0xabc8abf800000000, 0xdaecda4c00000000, 0x6eed6e0d00000000, + 0xb2efb2cf00000000, 0x06ee068e00000000, 0x09ea09fa00000000, + 0xbdebbdbb00000000, 0x61e9617900000000, 0xd5e8d53800000000, + 0x7fe17f9100000000, 0xcbe0cbd000000000, 0x17e2171200000000, + 0xa3e3a35300000000, 0xace7ac2700000000, 0x18e6186600000000, + 0xc4e4c4a400000000, 0x70e570e500000000, 0x93f7934700000000, + 0x27f6270600000000, 0xfbf4fbc400000000, 0x4ff54f8500000000, + 0x40f140f100000000, 0xf4f0f4b000000000, 0x28f2287200000000, + 0x9cf39c3300000000, 0x36fa369a00000000, 0x82fb82db00000000, + 0x5ef95e1900000000, 0xeaf8ea5800000000, 0xe5fce52c00000000, + 0x51fd516d00000000, 0x8dff8daf00000000, 0x39fe39ee00000000, + 0x6cb76c7700000000, 0xd8b6d83600000000, 0x04b404f400000000, + 0xb0b5b0b500000000, 0xbfb1bfc100000000, 0x0bb00b8000000000, + 0xd7b2d74200000000, 0x63b3630300000000, 0xc9bac9aa00000000, + 0x7dbb7deb00000000, 0xa1b9a12900000000, 0x15b8156800000000, + 0x1abc1a1c00000000, 0xaebdae5d00000000, 0x72bf729f00000000, + 0xc6bec6de00000000, 0x25ac257c00000000, 0x91ad913d00000000, + 0x4daf4dff00000000, 0xf9aef9be00000000, 0xf6aaf6ca00000000, + 0x42ab428b00000000, 0x9ea99e4900000000, 0x2aa82a0800000000, + 0x80a180a100000000, 0x34a034e000000000, 0xe8a2e82200000000, + 0x5ca35c6300000000, 0x53a7531700000000, 0xe7a6e75600000000, + 0x3ba43b9400000000, 0x8fa58fd500000000, 0xfe81fe6100000000, + 0x4a804a2000000000, 0x968296e200000000, 0x228322a300000000, + 0x2d872dd700000000, 0x9986999600000000, 0x4584455400000000, + 0xf185f11500000000, 0x5b8c5bbc00000000, 0xef8deffd00000000, + 0x338f333f00000000, 0x878e877e00000000, 0x888a880a00000000, + 0x3c8b3c4b00000000, 0xe089e08900000000, 0x548854c800000000, + 0xb79ab76a00000000, 0x039b032b00000000, 0xdf99dfe900000000, + 0x6b986ba800000000, 0x649c64dc00000000, 0xd09dd09d00000000, + 0x0c9f0c5f00000000, 0xb89eb81e00000000, 0x129712b700000000, + 0xa696a6f600000000, 0x7a947a3400000000, 0xce95ce7500000000, + 0xc191c10100000000, 0x7590754000000000, 0xa992a98200000000, + 0x1d931dc300000000}, + {0x0000000000000000, 0x0100015100000000, 0x020002a200000000, + 0x030003f300000000, 0x070007f400000000, 0x060006a500000000, + 0x0500055600000000, 0x0400040700000000, 0x0d000d5800000000, + 0x0c000c0900000000, 0x0f000ffa00000000, 0x0e000eab00000000, + 0x0a000aac00000000, 0x0b000bfd00000000, 0x0800080e00000000, + 0x0900095f00000000, 0x1a001ab000000000, 0x1b001be100000000, + 0x1800181200000000, 0x1900194300000000, 0x1d001d4400000000, + 0x1c001c1500000000, 0x1f001fe600000000, 0x1e001eb700000000, + 0x170017e800000000, 0x160016b900000000, 0x1500154a00000000, + 0x1400141b00000000, 0x1000101c00000000, 0x1100114d00000000, + 0x120012be00000000, 0x130013ef00000000, 0x370037d000000000, + 0x3600368100000000, 0x3500357200000000, 0x3400342300000000, + 0x3000302400000000, 0x3100317500000000, 0x3200328600000000, + 0x330033d700000000, 0x3a003a8800000000, 0x3b003bd900000000, + 0x3800382a00000000, 0x3900397b00000000, 0x3d003d7c00000000, + 0x3c003c2d00000000, 0x3f003fde00000000, 0x3e003e8f00000000, + 0x2d002d6000000000, 0x2c002c3100000000, 0x2f002fc200000000, + 0x2e002e9300000000, 0x2a002a9400000000, 0x2b002bc500000000, + 0x2800283600000000, 0x2900296700000000, 0x2000203800000000, + 0x2100216900000000, 0x2200229a00000000, 0x230023cb00000000, + 0x270027cc00000000, 0x2600269d00000000, 0x2500256e00000000, + 0x2400243f00000000, 0x6d006d1000000000, 0x6c006c4100000000, + 0x6f006fb200000000, 0x6e006ee300000000, 0x6a006ae400000000, + 0x6b006bb500000000, 0x6800684600000000, 0x6900691700000000, + 0x6000604800000000, 0x6100611900000000, 0x620062ea00000000, + 0x630063bb00000000, 0x670067bc00000000, 0x660066ed00000000, + 0x6500651e00000000, 0x6400644f00000000, 0x770077a000000000, + 0x760076f100000000, 0x7500750200000000, 0x7400745300000000, + 0x7000705400000000, 0x7100710500000000, 0x720072f600000000, + 0x730073a700000000, 0x7a007af800000000, 0x7b007ba900000000, + 0x7800785a00000000, 0x7900790b00000000, 0x7d007d0c00000000, + 0x7c007c5d00000000, 0x7f007fae00000000, 0x7e007eff00000000, + 0x5a005ac000000000, 0x5b005b9100000000, 0x5800586200000000, + 0x5900593300000000, 0x5d005d3400000000, 0x5c005c6500000000, + 0x5f005f9600000000, 0x5e005ec700000000, 0x5700579800000000, + 0x560056c900000000, 0x5500553a00000000, 0x5400546b00000000, + 0x5000506c00000000, 0x5100513d00000000, 0x520052ce00000000, + 0x5300539f00000000, 0x4000407000000000, 0x4100412100000000, + 0x420042d200000000, 0x4300438300000000, 0x4700478400000000, + 0x460046d500000000, 0x4500452600000000, 0x4400447700000000, + 0x4d004d2800000000, 0x4c004c7900000000, 0x4f004f8a00000000, + 0x4e004edb00000000, 0x4a004adc00000000, 0x4b004b8d00000000, + 0x4800487e00000000, 0x4900492f00000000, 0xda00da2000000000, + 0xdb00db7100000000, 0xd800d88200000000, 0xd900d9d300000000, + 0xdd00ddd400000000, 0xdc00dc8500000000, 0xdf00df7600000000, + 0xde00de2700000000, 0xd700d77800000000, 0xd600d62900000000, + 0xd500d5da00000000, 0xd400d48b00000000, 0xd000d08c00000000, + 0xd100d1dd00000000, 0xd200d22e00000000, 0xd300d37f00000000, + 0xc000c09000000000, 0xc100c1c100000000, 0xc200c23200000000, + 0xc300c36300000000, 0xc700c76400000000, 0xc600c63500000000, + 0xc500c5c600000000, 0xc400c49700000000, 0xcd00cdc800000000, + 0xcc00cc9900000000, 0xcf00cf6a00000000, 0xce00ce3b00000000, + 0xca00ca3c00000000, 0xcb00cb6d00000000, 0xc800c89e00000000, + 0xc900c9cf00000000, 0xed00edf000000000, 0xec00eca100000000, + 0xef00ef5200000000, 0xee00ee0300000000, 0xea00ea0400000000, + 0xeb00eb5500000000, 0xe800e8a600000000, 0xe900e9f700000000, + 0xe000e0a800000000, 0xe100e1f900000000, 0xe200e20a00000000, + 0xe300e35b00000000, 0xe700e75c00000000, 0xe600e60d00000000, + 0xe500e5fe00000000, 0xe400e4af00000000, 0xf700f74000000000, + 0xf600f61100000000, 0xf500f5e200000000, 0xf400f4b300000000, + 0xf000f0b400000000, 0xf100f1e500000000, 0xf200f21600000000, + 0xf300f34700000000, 0xfa00fa1800000000, 0xfb00fb4900000000, + 0xf800f8ba00000000, 0xf900f9eb00000000, 0xfd00fdec00000000, + 0xfc00fcbd00000000, 0xff00ff4e00000000, 0xfe00fe1f00000000, + 0xb700b73000000000, 0xb600b66100000000, 0xb500b59200000000, + 0xb400b4c300000000, 0xb000b0c400000000, 0xb100b19500000000, + 0xb200b26600000000, 0xb300b33700000000, 0xba00ba6800000000, + 0xbb00bb3900000000, 0xb800b8ca00000000, 0xb900b99b00000000, + 0xbd00bd9c00000000, 0xbc00bccd00000000, 0xbf00bf3e00000000, + 0xbe00be6f00000000, 0xad00ad8000000000, 0xac00acd100000000, + 0xaf00af2200000000, 0xae00ae7300000000, 0xaa00aa7400000000, + 0xab00ab2500000000, 0xa800a8d600000000, 0xa900a98700000000, + 0xa000a0d800000000, 0xa100a18900000000, 0xa200a27a00000000, + 0xa300a32b00000000, 0xa700a72c00000000, 0xa600a67d00000000, + 0xa500a58e00000000, 0xa400a4df00000000, 0x800080e000000000, + 0x810081b100000000, 0x8200824200000000, 0x8300831300000000, + 0x8700871400000000, 0x8600864500000000, 0x850085b600000000, + 0x840084e700000000, 0x8d008db800000000, 0x8c008ce900000000, + 0x8f008f1a00000000, 0x8e008e4b00000000, 0x8a008a4c00000000, + 0x8b008b1d00000000, 0x880088ee00000000, 0x890089bf00000000, + 0x9a009a5000000000, 0x9b009b0100000000, 0x980098f200000000, + 0x990099a300000000, 0x9d009da400000000, 0x9c009cf500000000, + 0x9f009f0600000000, 0x9e009e5700000000, 0x9700970800000000, + 0x9600965900000000, 0x950095aa00000000, 0x940094fb00000000, + 0x900090fc00000000, 0x910091ad00000000, 0x9200925e00000000, + 0x9300930f00000000}, + {0x0000000000000000, 0x0100c09000000000, 0x0100839100000000, + 0x0000430100000000, 0x0100059300000000, 0x0000c50300000000, + 0x0000860200000000, 0x0100469200000000, 0x0100099600000000, + 0x0000c90600000000, 0x00008a0700000000, 0x01004a9700000000, + 0x00000c0500000000, 0x0100cc9500000000, 0x01008f9400000000, + 0x00004f0400000000, 0x0100119c00000000, 0x0000d10c00000000, + 0x0000920d00000000, 0x0100529d00000000, 0x0000140f00000000, + 0x0100d49f00000000, 0x0100979e00000000, 0x0000570e00000000, + 0x0000180a00000000, 0x0100d89a00000000, 0x01009b9b00000000, + 0x00005b0b00000000, 0x01001d9900000000, 0x0000dd0900000000, + 0x00009e0800000000, 0x01005e9800000000, 0x0100218800000000, + 0x0000e11800000000, 0x0000a21900000000, 0x0100628900000000, + 0x0000241b00000000, 0x0100e48b00000000, 0x0100a78a00000000, + 0x0000671a00000000, 0x0000281e00000000, 0x0100e88e00000000, + 0x0100ab8f00000000, 0x00006b1f00000000, 0x01002d8d00000000, + 0x0000ed1d00000000, 0x0000ae1c00000000, 0x01006e8c00000000, + 0x0000301400000000, 0x0100f08400000000, 0x0100b38500000000, + 0x0000731500000000, 0x0100358700000000, 0x0000f51700000000, + 0x0000b61600000000, 0x0100768600000000, 0x0100398200000000, + 0x0000f91200000000, 0x0000ba1300000000, 0x01007a8300000000, + 0x00003c1100000000, 0x0100fc8100000000, 0x0100bf8000000000, + 0x00007f1000000000, 0x010041a000000000, 0x0000813000000000, + 0x0000c23100000000, 0x010002a100000000, 0x0000443300000000, + 0x010084a300000000, 0x0100c7a200000000, 0x0000073200000000, + 0x0000483600000000, 0x010088a600000000, 0x0100cba700000000, + 0x00000b3700000000, 0x01004da500000000, 0x00008d3500000000, + 0x0000ce3400000000, 0x01000ea400000000, 0x0000503c00000000, + 0x010090ac00000000, 0x0100d3ad00000000, 0x0000133d00000000, + 0x010055af00000000, 0x0000953f00000000, 0x0000d63e00000000, + 0x010016ae00000000, 0x010059aa00000000, 0x0000993a00000000, + 0x0000da3b00000000, 0x01001aab00000000, 0x00005c3900000000, + 0x01009ca900000000, 0x0100dfa800000000, 0x00001f3800000000, + 0x0000602800000000, 0x0100a0b800000000, 0x0100e3b900000000, + 0x0000232900000000, 0x010065bb00000000, 0x0000a52b00000000, + 0x0000e62a00000000, 0x010026ba00000000, 0x010069be00000000, + 0x0000a92e00000000, 0x0000ea2f00000000, 0x01002abf00000000, + 0x00006c2d00000000, 0x0100acbd00000000, 0x0100efbc00000000, + 0x00002f2c00000000, 0x010071b400000000, 0x0000b12400000000, + 0x0000f22500000000, 0x010032b500000000, 0x0000742700000000, + 0x0100b4b700000000, 0x0100f7b600000000, 0x0000372600000000, + 0x0000782200000000, 0x0100b8b200000000, 0x0100fbb300000000, + 0x00003b2300000000, 0x01007db100000000, 0x0000bd2100000000, + 0x0000fe2000000000, 0x01003eb000000000, 0x010081f000000000, + 0x0000416000000000, 0x0000026100000000, 0x0100c2f100000000, + 0x0000846300000000, 0x010044f300000000, 0x010007f200000000, + 0x0000c76200000000, 0x0000886600000000, 0x010048f600000000, + 0x01000bf700000000, 0x0000cb6700000000, 0x01008df500000000, + 0x00004d6500000000, 0x00000e6400000000, 0x0100cef400000000, + 0x0000906c00000000, 0x010050fc00000000, 0x010013fd00000000, + 0x0000d36d00000000, 0x010095ff00000000, 0x0000556f00000000, + 0x0000166e00000000, 0x0100d6fe00000000, 0x010099fa00000000, + 0x0000596a00000000, 0x00001a6b00000000, 0x0100dafb00000000, + 0x00009c6900000000, 0x01005cf900000000, 0x01001ff800000000, + 0x0000df6800000000, 0x0000a07800000000, 0x010060e800000000, + 0x010023e900000000, 0x0000e37900000000, 0x0100a5eb00000000, + 0x0000657b00000000, 0x0000267a00000000, 0x0100e6ea00000000, + 0x0100a9ee00000000, 0x0000697e00000000, 0x00002a7f00000000, + 0x0100eaef00000000, 0x0000ac7d00000000, 0x01006ced00000000, + 0x01002fec00000000, 0x0000ef7c00000000, 0x0100b1e400000000, + 0x0000717400000000, 0x0000327500000000, 0x0100f2e500000000, + 0x0000b47700000000, 0x010074e700000000, 0x010037e600000000, + 0x0000f77600000000, 0x0000b87200000000, 0x010078e200000000, + 0x01003be300000000, 0x0000fb7300000000, 0x0100bde100000000, + 0x00007d7100000000, 0x00003e7000000000, 0x0100fee000000000, + 0x0000c05000000000, 0x010000c000000000, 0x010043c100000000, + 0x0000835100000000, 0x0100c5c300000000, 0x0000055300000000, + 0x0000465200000000, 0x010086c200000000, 0x0100c9c600000000, + 0x0000095600000000, 0x00004a5700000000, 0x01008ac700000000, + 0x0000cc5500000000, 0x01000cc500000000, 0x01004fc400000000, + 0x00008f5400000000, 0x0100d1cc00000000, 0x0000115c00000000, + 0x0000525d00000000, 0x010092cd00000000, 0x0000d45f00000000, + 0x010014cf00000000, 0x010057ce00000000, 0x0000975e00000000, + 0x0000d85a00000000, 0x010018ca00000000, 0x01005bcb00000000, + 0x00009b5b00000000, 0x0100ddc900000000, 0x00001d5900000000, + 0x00005e5800000000, 0x01009ec800000000, 0x0100e1d800000000, + 0x0000214800000000, 0x0000624900000000, 0x0100a2d900000000, + 0x0000e44b00000000, 0x010024db00000000, 0x010067da00000000, + 0x0000a74a00000000, 0x0000e84e00000000, 0x010028de00000000, + 0x01006bdf00000000, 0x0000ab4f00000000, 0x0100eddd00000000, + 0x00002d4d00000000, 0x00006e4c00000000, 0x0100aedc00000000, + 0x0000f04400000000, 0x010030d400000000, 0x010073d500000000, + 0x0000b34500000000, 0x0100f5d700000000, 0x0000354700000000, + 0x0000764600000000, 0x0100b6d600000000, 0x0100f9d200000000, + 0x0000394200000000, 0x00007a4300000000, 0x0100bad300000000, + 0x0000fc4100000000, 0x01003cd100000000, 0x01007fd000000000, + 0x0000bf4000000000}, + {0x0000000000000000, 0x01c1019000000000, 0x0182009000000000, + 0x0043010000000000, 0x0104029000000000, 0x00c5030000000000, + 0x0086020000000000, 0x0147039000000000, 0x0108079000000000, + 0x00c9060000000000, 0x008a070000000000, 0x014b069000000000, + 0x000c050000000000, 0x01cd049000000000, 0x018e059000000000, + 0x004f040000000000, 0x01100d9000000000, 0x00d10c0000000000, + 0x00920d0000000000, 0x01530c9000000000, 0x00140f0000000000, + 0x01d50e9000000000, 0x01960f9000000000, 0x00570e0000000000, + 0x00180a0000000000, 0x01d90b9000000000, 0x019a0a9000000000, + 0x005b0b0000000000, 0x011c089000000000, 0x00dd090000000000, + 0x009e080000000000, 0x015f099000000000, 0x0120199000000000, + 0x00e1180000000000, 0x00a2190000000000, 0x0163189000000000, + 0x00241b0000000000, 0x01e51a9000000000, 0x01a61b9000000000, + 0x00671a0000000000, 0x00281e0000000000, 0x01e91f9000000000, + 0x01aa1e9000000000, 0x006b1f0000000000, 0x012c1c9000000000, + 0x00ed1d0000000000, 0x00ae1c0000000000, 0x016f1d9000000000, + 0x0030140000000000, 0x01f1159000000000, 0x01b2149000000000, + 0x0073150000000000, 0x0134169000000000, 0x00f5170000000000, + 0x00b6160000000000, 0x0177179000000000, 0x0138139000000000, + 0x00f9120000000000, 0x00ba130000000000, 0x017b129000000000, + 0x003c110000000000, 0x01fd109000000000, 0x01be119000000000, + 0x007f100000000000, 0x0140319000000000, 0x0081300000000000, + 0x00c2310000000000, 0x0103309000000000, 0x0044330000000000, + 0x0185329000000000, 0x01c6339000000000, 0x0007320000000000, + 0x0048360000000000, 0x0189379000000000, 0x01ca369000000000, + 0x000b370000000000, 0x014c349000000000, 0x008d350000000000, + 0x00ce340000000000, 0x010f359000000000, 0x00503c0000000000, + 0x01913d9000000000, 0x01d23c9000000000, 0x00133d0000000000, + 0x01543e9000000000, 0x00953f0000000000, 0x00d63e0000000000, + 0x01173f9000000000, 0x01583b9000000000, 0x00993a0000000000, + 0x00da3b0000000000, 0x011b3a9000000000, 0x005c390000000000, + 0x019d389000000000, 0x01de399000000000, 0x001f380000000000, + 0x0060280000000000, 0x01a1299000000000, 0x01e2289000000000, + 0x0023290000000000, 0x01642a9000000000, 0x00a52b0000000000, + 0x00e62a0000000000, 0x01272b9000000000, 0x01682f9000000000, + 0x00a92e0000000000, 0x00ea2f0000000000, 0x012b2e9000000000, + 0x006c2d0000000000, 0x01ad2c9000000000, 0x01ee2d9000000000, + 0x002f2c0000000000, 0x0170259000000000, 0x00b1240000000000, + 0x00f2250000000000, 0x0133249000000000, 0x0074270000000000, + 0x01b5269000000000, 0x01f6279000000000, 0x0037260000000000, + 0x0078220000000000, 0x01b9239000000000, 0x01fa229000000000, + 0x003b230000000000, 0x017c209000000000, 0x00bd210000000000, + 0x00fe200000000000, 0x013f219000000000, 0x0180619000000000, + 0x0041600000000000, 0x0002610000000000, 0x01c3609000000000, + 0x0084630000000000, 0x0145629000000000, 0x0106639000000000, + 0x00c7620000000000, 0x0088660000000000, 0x0149679000000000, + 0x010a669000000000, 0x00cb670000000000, 0x018c649000000000, + 0x004d650000000000, 0x000e640000000000, 0x01cf659000000000, + 0x00906c0000000000, 0x01516d9000000000, 0x01126c9000000000, + 0x00d36d0000000000, 0x01946e9000000000, 0x00556f0000000000, + 0x00166e0000000000, 0x01d76f9000000000, 0x01986b9000000000, + 0x00596a0000000000, 0x001a6b0000000000, 0x01db6a9000000000, + 0x009c690000000000, 0x015d689000000000, 0x011e699000000000, + 0x00df680000000000, 0x00a0780000000000, 0x0161799000000000, + 0x0122789000000000, 0x00e3790000000000, 0x01a47a9000000000, + 0x00657b0000000000, 0x00267a0000000000, 0x01e77b9000000000, + 0x01a87f9000000000, 0x00697e0000000000, 0x002a7f0000000000, + 0x01eb7e9000000000, 0x00ac7d0000000000, 0x016d7c9000000000, + 0x012e7d9000000000, 0x00ef7c0000000000, 0x01b0759000000000, + 0x0071740000000000, 0x0032750000000000, 0x01f3749000000000, + 0x00b4770000000000, 0x0175769000000000, 0x0136779000000000, + 0x00f7760000000000, 0x00b8720000000000, 0x0179739000000000, + 0x013a729000000000, 0x00fb730000000000, 0x01bc709000000000, + 0x007d710000000000, 0x003e700000000000, 0x01ff719000000000, + 0x00c0500000000000, 0x0101519000000000, 0x0142509000000000, + 0x0083510000000000, 0x01c4529000000000, 0x0005530000000000, + 0x0046520000000000, 0x0187539000000000, 0x01c8579000000000, + 0x0009560000000000, 0x004a570000000000, 0x018b569000000000, + 0x00cc550000000000, 0x010d549000000000, 0x014e559000000000, + 0x008f540000000000, 0x01d05d9000000000, 0x00115c0000000000, + 0x00525d0000000000, 0x01935c9000000000, 0x00d45f0000000000, + 0x01155e9000000000, 0x01565f9000000000, 0x00975e0000000000, + 0x00d85a0000000000, 0x01195b9000000000, 0x015a5a9000000000, + 0x009b5b0000000000, 0x01dc589000000000, 0x001d590000000000, + 0x005e580000000000, 0x019f599000000000, 0x01e0499000000000, + 0x0021480000000000, 0x0062490000000000, 0x01a3489000000000, + 0x00e44b0000000000, 0x01254a9000000000, 0x01664b9000000000, + 0x00a74a0000000000, 0x00e84e0000000000, 0x01294f9000000000, + 0x016a4e9000000000, 0x00ab4f0000000000, 0x01ec4c9000000000, + 0x002d4d0000000000, 0x006e4c0000000000, 0x01af4d9000000000, + 0x00f0440000000000, 0x0131459000000000, 0x0172449000000000, + 0x00b3450000000000, 0x01f4469000000000, 0x0035470000000000, + 0x0076460000000000, 0x01b7479000000000, 0x01f8439000000000, + 0x0039420000000000, 0x007a430000000000, 0x01bb429000000000, + 0x00fc410000000000, 0x013d409000000000, 0x017e419000000000, + 0x00bf400000000000}, + {0x0000000000000000, 0xc000019000000000, 0x8301019000000000, + 0x4301000000000000, 0x0503019000000000, 0xc503000000000000, + 0x8602000000000000, 0x4602019000000000, 0x0906019000000000, + 0xc906000000000000, 0x8a07000000000000, 0x4a07019000000000, + 0x0c05000000000000, 0xcc05019000000000, 0x8f04019000000000, + 0x4f04000000000000, 0x110c019000000000, 0xd10c000000000000, + 0x920d000000000000, 0x520d019000000000, 0x140f000000000000, + 0xd40f019000000000, 0x970e019000000000, 0x570e000000000000, + 0x180a000000000000, 0xd80a019000000000, 0x9b0b019000000000, + 0x5b0b000000000000, 0x1d09019000000000, 0xdd09000000000000, + 0x9e08000000000000, 0x5e08019000000000, 0x2118019000000000, + 0xe118000000000000, 0xa219000000000000, 0x6219019000000000, + 0x241b000000000000, 0xe41b019000000000, 0xa71a019000000000, + 0x671a000000000000, 0x281e000000000000, 0xe81e019000000000, + 0xab1f019000000000, 0x6b1f000000000000, 0x2d1d019000000000, + 0xed1d000000000000, 0xae1c000000000000, 0x6e1c019000000000, + 0x3014000000000000, 0xf014019000000000, 0xb315019000000000, + 0x7315000000000000, 0x3517019000000000, 0xf517000000000000, + 0xb616000000000000, 0x7616019000000000, 0x3912019000000000, + 0xf912000000000000, 0xba13000000000000, 0x7a13019000000000, + 0x3c11000000000000, 0xfc11019000000000, 0xbf10019000000000, + 0x7f10000000000000, 0x4130019000000000, 0x8130000000000000, + 0xc231000000000000, 0x0231019000000000, 0x4433000000000000, + 0x8433019000000000, 0xc732019000000000, 0x0732000000000000, + 0x4836000000000000, 0x8836019000000000, 0xcb37019000000000, + 0x0b37000000000000, 0x4d35019000000000, 0x8d35000000000000, + 0xce34000000000000, 0x0e34019000000000, 0x503c000000000000, + 0x903c019000000000, 0xd33d019000000000, 0x133d000000000000, + 0x553f019000000000, 0x953f000000000000, 0xd63e000000000000, + 0x163e019000000000, 0x593a019000000000, 0x993a000000000000, + 0xda3b000000000000, 0x1a3b019000000000, 0x5c39000000000000, + 0x9c39019000000000, 0xdf38019000000000, 0x1f38000000000000, + 0x6028000000000000, 0xa028019000000000, 0xe329019000000000, + 0x2329000000000000, 0x652b019000000000, 0xa52b000000000000, + 0xe62a000000000000, 0x262a019000000000, 0x692e019000000000, + 0xa92e000000000000, 0xea2f000000000000, 0x2a2f019000000000, + 0x6c2d000000000000, 0xac2d019000000000, 0xef2c019000000000, + 0x2f2c000000000000, 0x7124019000000000, 0xb124000000000000, + 0xf225000000000000, 0x3225019000000000, 0x7427000000000000, + 0xb427019000000000, 0xf726019000000000, 0x3726000000000000, + 0x7822000000000000, 0xb822019000000000, 0xfb23019000000000, + 0x3b23000000000000, 0x7d21019000000000, 0xbd21000000000000, + 0xfe20000000000000, 0x3e20019000000000, 0x8160019000000000, + 0x4160000000000000, 0x0261000000000000, 0xc261019000000000, + 0x8463000000000000, 0x4463019000000000, 0x0762019000000000, + 0xc762000000000000, 0x8866000000000000, 0x4866019000000000, + 0x0b67019000000000, 0xcb67000000000000, 0x8d65019000000000, + 0x4d65000000000000, 0x0e64000000000000, 0xce64019000000000, + 0x906c000000000000, 0x506c019000000000, 0x136d019000000000, + 0xd36d000000000000, 0x956f019000000000, 0x556f000000000000, + 0x166e000000000000, 0xd66e019000000000, 0x996a019000000000, + 0x596a000000000000, 0x1a6b000000000000, 0xda6b019000000000, + 0x9c69000000000000, 0x5c69019000000000, 0x1f68019000000000, + 0xdf68000000000000, 0xa078000000000000, 0x6078019000000000, + 0x2379019000000000, 0xe379000000000000, 0xa57b019000000000, + 0x657b000000000000, 0x267a000000000000, 0xe67a019000000000, + 0xa97e019000000000, 0x697e000000000000, 0x2a7f000000000000, + 0xea7f019000000000, 0xac7d000000000000, 0x6c7d019000000000, + 0x2f7c019000000000, 0xef7c000000000000, 0xb174019000000000, + 0x7174000000000000, 0x3275000000000000, 0xf275019000000000, + 0xb477000000000000, 0x7477019000000000, 0x3776019000000000, + 0xf776000000000000, 0xb872000000000000, 0x7872019000000000, + 0x3b73019000000000, 0xfb73000000000000, 0xbd71019000000000, + 0x7d71000000000000, 0x3e70000000000000, 0xfe70019000000000, + 0xc050000000000000, 0x0050019000000000, 0x4351019000000000, + 0x8351000000000000, 0xc553019000000000, 0x0553000000000000, + 0x4652000000000000, 0x8652019000000000, 0xc956019000000000, + 0x0956000000000000, 0x4a57000000000000, 0x8a57019000000000, + 0xcc55000000000000, 0x0c55019000000000, 0x4f54019000000000, + 0x8f54000000000000, 0xd15c019000000000, 0x115c000000000000, + 0x525d000000000000, 0x925d019000000000, 0xd45f000000000000, + 0x145f019000000000, 0x575e019000000000, 0x975e000000000000, + 0xd85a000000000000, 0x185a019000000000, 0x5b5b019000000000, + 0x9b5b000000000000, 0xdd59019000000000, 0x1d59000000000000, + 0x5e58000000000000, 0x9e58019000000000, 0xe148019000000000, + 0x2148000000000000, 0x6249000000000000, 0xa249019000000000, + 0xe44b000000000000, 0x244b019000000000, 0x674a019000000000, + 0xa74a000000000000, 0xe84e000000000000, 0x284e019000000000, + 0x6b4f019000000000, 0xab4f000000000000, 0xed4d019000000000, + 0x2d4d000000000000, 0x6e4c000000000000, 0xae4c019000000000, + 0xf044000000000000, 0x3044019000000000, 0x7345019000000000, + 0xb345000000000000, 0xf547019000000000, 0x3547000000000000, + 0x7646000000000000, 0xb646019000000000, 0xf942019000000000, + 0x3942000000000000, 0x7a43000000000000, 0xba43019000000000, + 0xfc41000000000000, 0x3c41019000000000, 0x7f40019000000000, + 0xbf40000000000000}, + {0x0000000000000000, 0x00c1906c00000000, 0x008221d900000000, + 0x0043b1b500000000, 0x0304400200000000, 0x03c5d06e00000000, + 0x038661db00000000, 0x0347f1b700000000, 0x0608800400000000, + 0x06c9106800000000, 0x068aa1dd00000000, 0x064b31b100000000, + 0x050cc00600000000, 0x05cd506a00000000, 0x058ee1df00000000, + 0x054f71b300000000, 0x0c10000900000000, 0x0cd1906500000000, + 0x0c9221d000000000, 0x0c53b1bc00000000, 0x0f14400b00000000, + 0x0fd5d06700000000, 0x0f9661d200000000, 0x0f57f1be00000000, + 0x0a18800d00000000, 0x0ad9106100000000, 0x0a9aa1d400000000, + 0x0a5b31b800000000, 0x091cc00f00000000, 0x09dd506300000000, + 0x099ee1d600000000, 0x095f71ba00000000, 0x1820001200000000, + 0x18e1907e00000000, 0x18a221cb00000000, 0x1863b1a700000000, + 0x1b24401000000000, 0x1be5d07c00000000, 0x1ba661c900000000, + 0x1b67f1a500000000, 0x1e28801600000000, 0x1ee9107a00000000, + 0x1eaaa1cf00000000, 0x1e6b31a300000000, 0x1d2cc01400000000, + 0x1ded507800000000, 0x1daee1cd00000000, 0x1d6f71a100000000, + 0x1430001b00000000, 0x14f1907700000000, 0x14b221c200000000, + 0x1473b1ae00000000, 0x1734401900000000, 0x17f5d07500000000, + 0x17b661c000000000, 0x1777f1ac00000000, 0x1238801f00000000, + 0x12f9107300000000, 0x12baa1c600000000, 0x127b31aa00000000, + 0x113cc01d00000000, 0x11fd507100000000, 0x11bee1c400000000, + 0x117f71a800000000, 0x3040002400000000, 0x3081904800000000, + 0x30c221fd00000000, 0x3003b19100000000, 0x3344402600000000, + 0x3385d04a00000000, 0x33c661ff00000000, 0x3307f19300000000, + 0x3648802000000000, 0x3689104c00000000, 0x36caa1f900000000, + 0x360b319500000000, 0x354cc02200000000, 0x358d504e00000000, + 0x35cee1fb00000000, 0x350f719700000000, 0x3c50002d00000000, + 0x3c91904100000000, 0x3cd221f400000000, 0x3c13b19800000000, + 0x3f54402f00000000, 0x3f95d04300000000, 0x3fd661f600000000, + 0x3f17f19a00000000, 0x3a58802900000000, 0x3a99104500000000, + 0x3adaa1f000000000, 0x3a1b319c00000000, 0x395cc02b00000000, + 0x399d504700000000, 0x39dee1f200000000, 0x391f719e00000000, + 0x2860003600000000, 0x28a1905a00000000, 0x28e221ef00000000, + 0x2823b18300000000, 0x2b64403400000000, 0x2ba5d05800000000, + 0x2be661ed00000000, 0x2b27f18100000000, 0x2e68803200000000, + 0x2ea9105e00000000, 0x2eeaa1eb00000000, 0x2e2b318700000000, + 0x2d6cc03000000000, 0x2dad505c00000000, 0x2deee1e900000000, + 0x2d2f718500000000, 0x2470003f00000000, 0x24b1905300000000, + 0x24f221e600000000, 0x2433b18a00000000, 0x2774403d00000000, + 0x27b5d05100000000, 0x27f661e400000000, 0x2737f18800000000, + 0x2278803b00000000, 0x22b9105700000000, 0x22faa1e200000000, + 0x223b318e00000000, 0x217cc03900000000, 0x21bd505500000000, + 0x21fee1e000000000, 0x213f718c00000000, 0x6080004800000000, + 0x6041902400000000, 0x6002219100000000, 0x60c3b1fd00000000, + 0x6384404a00000000, 0x6345d02600000000, 0x6306619300000000, + 0x63c7f1ff00000000, 0x6688804c00000000, 0x6649102000000000, + 0x660aa19500000000, 0x66cb31f900000000, 0x658cc04e00000000, + 0x654d502200000000, 0x650ee19700000000, 0x65cf71fb00000000, + 0x6c90004100000000, 0x6c51902d00000000, 0x6c12219800000000, + 0x6cd3b1f400000000, 0x6f94404300000000, 0x6f55d02f00000000, + 0x6f16619a00000000, 0x6fd7f1f600000000, 0x6a98804500000000, + 0x6a59102900000000, 0x6a1aa19c00000000, 0x6adb31f000000000, + 0x699cc04700000000, 0x695d502b00000000, 0x691ee19e00000000, + 0x69df71f200000000, 0x78a0005a00000000, 0x7861903600000000, + 0x7822218300000000, 0x78e3b1ef00000000, 0x7ba4405800000000, + 0x7b65d03400000000, 0x7b26618100000000, 0x7be7f1ed00000000, + 0x7ea8805e00000000, 0x7e69103200000000, 0x7e2aa18700000000, + 0x7eeb31eb00000000, 0x7dacc05c00000000, 0x7d6d503000000000, + 0x7d2ee18500000000, 0x7def71e900000000, 0x74b0005300000000, + 0x7471903f00000000, 0x7432218a00000000, 0x74f3b1e600000000, + 0x77b4405100000000, 0x7775d03d00000000, 0x7736618800000000, + 0x77f7f1e400000000, 0x72b8805700000000, 0x7279103b00000000, + 0x723aa18e00000000, 0x72fb31e200000000, 0x71bcc05500000000, + 0x717d503900000000, 0x713ee18c00000000, 0x71ff71e000000000, + 0x50c0006c00000000, 0x5001900000000000, 0x504221b500000000, + 0x5083b1d900000000, 0x53c4406e00000000, 0x5305d00200000000, + 0x534661b700000000, 0x5387f1db00000000, 0x56c8806800000000, + 0x5609100400000000, 0x564aa1b100000000, 0x568b31dd00000000, + 0x55ccc06a00000000, 0x550d500600000000, 0x554ee1b300000000, + 0x558f71df00000000, 0x5cd0006500000000, 0x5c11900900000000, + 0x5c5221bc00000000, 0x5c93b1d000000000, 0x5fd4406700000000, + 0x5f15d00b00000000, 0x5f5661be00000000, 0x5f97f1d200000000, + 0x5ad8806100000000, 0x5a19100d00000000, 0x5a5aa1b800000000, + 0x5a9b31d400000000, 0x59dcc06300000000, 0x591d500f00000000, + 0x595ee1ba00000000, 0x599f71d600000000, 0x48e0007e00000000, + 0x4821901200000000, 0x486221a700000000, 0x48a3b1cb00000000, + 0x4be4407c00000000, 0x4b25d01000000000, 0x4b6661a500000000, + 0x4ba7f1c900000000, 0x4ee8807a00000000, 0x4e29101600000000, + 0x4e6aa1a300000000, 0x4eab31cf00000000, 0x4decc07800000000, + 0x4d2d501400000000, 0x4d6ee1a100000000, 0x4daf71cd00000000, + 0x44f0007700000000, 0x4431901b00000000, 0x447221ae00000000, + 0x44b3b1c200000000, 0x47f4407500000000, 0x4735d01900000000, + 0x477661ac00000000, 0x47b7f1c000000000, 0x42f8807300000000, + 0x4239101f00000000, 0x427aa1aa00000000, 0x42bb31c600000000, + 0x41fcc07100000000, 0x413d501d00000000, 0x417ee1a800000000, + 0x41bf71c400000000}}; + +#else /* W == 4 */ + +static const crc_t crc_braid_table[][256] = { + {0x00000000, 0x65904101, 0xcb208202, 0xaeb0c303, 0x26420407, + 0x43d24506, 0xed628605, 0x88f2c704, 0x4c84080e, 0x2914490f, + 0x87a48a0c, 0xe234cb0d, 0x6ac60c09, 0x0f564d08, 0xa1e68e0b, + 0xc476cf0a, 0x9908101c, 0xfc98511d, 0x5228921e, 0x37b8d31f, + 0xbf4a141b, 0xdada551a, 0x746a9619, 0x11fad718, 0xd58c1812, + 0xb01c5913, 0x1eac9a10, 0x7b3cdb11, 0xf3ce1c15, 0x965e5d14, + 0x38ee9e17, 0x5d7edf16, 0x8213203b, 0xe783613a, 0x4933a239, + 0x2ca3e338, 0xa451243c, 0xc1c1653d, 0x6f71a63e, 0x0ae1e73f, + 0xce972835, 0xab076934, 0x05b7aa37, 0x6027eb36, 0xe8d52c32, + 0x8d456d33, 0x23f5ae30, 0x4665ef31, 0x1b1b3027, 0x7e8b7126, + 0xd03bb225, 0xb5abf324, 0x3d593420, 0x58c97521, 0xf679b622, + 0x93e9f723, 0x579f3829, 0x320f7928, 0x9cbfba2b, 0xf92ffb2a, + 0x71dd3c2e, 0x144d7d2f, 0xbafdbe2c, 0xdf6dff2d, 0xb4254075, + 0xd1b50174, 0x7f05c277, 0x1a958376, 0x92674472, 0xf7f70573, + 0x5947c670, 0x3cd78771, 0xf8a1487b, 0x9d31097a, 0x3381ca79, + 0x56118b78, 0xdee34c7c, 0xbb730d7d, 0x15c3ce7e, 0x70538f7f, + 0x2d2d5069, 0x48bd1168, 0xe60dd26b, 0x839d936a, 0x0b6f546e, + 0x6eff156f, 0xc04fd66c, 0xa5df976d, 0x61a95867, 0x04391966, + 0xaa89da65, 0xcf199b64, 0x47eb5c60, 0x227b1d61, 0x8ccbde62, + 0xe95b9f63, 0x3636604e, 0x53a6214f, 0xfd16e24c, 0x9886a34d, + 0x10746449, 0x75e42548, 0xdb54e64b, 0xbec4a74a, 0x7ab26840, + 0x1f222941, 0xb192ea42, 0xd402ab43, 0x5cf06c47, 0x39602d46, + 0x97d0ee45, 0xf240af44, 0xaf3e7052, 0xcaae3153, 0x641ef250, + 0x018eb351, 0x897c7455, 0xecec3554, 0x425cf657, 0x27ccb756, + 0xe3ba785c, 0x862a395d, 0x289afa5e, 0x4d0abb5f, 0xc5f87c5b, + 0xa0683d5a, 0x0ed8fe59, 0x6b48bf58, 0xd84980e9, 0xbdd9c1e8, + 0x136902eb, 0x76f943ea, 0xfe0b84ee, 0x9b9bc5ef, 0x352b06ec, + 0x50bb47ed, 0x94cd88e7, 0xf15dc9e6, 0x5fed0ae5, 0x3a7d4be4, + 0xb28f8ce0, 0xd71fcde1, 0x79af0ee2, 0x1c3f4fe3, 0x414190f5, + 0x24d1d1f4, 0x8a6112f7, 0xeff153f6, 0x670394f2, 0x0293d5f3, + 0xac2316f0, 0xc9b357f1, 0x0dc598fb, 0x6855d9fa, 0xc6e51af9, + 0xa3755bf8, 0x2b879cfc, 0x4e17ddfd, 0xe0a71efe, 0x85375fff, + 0x5a5aa0d2, 0x3fcae1d3, 0x917a22d0, 0xf4ea63d1, 0x7c18a4d5, + 0x1988e5d4, 0xb73826d7, 0xd2a867d6, 0x16dea8dc, 0x734ee9dd, + 0xddfe2ade, 0xb86e6bdf, 0x309cacdb, 0x550cedda, 0xfbbc2ed9, + 0x9e2c6fd8, 0xc352b0ce, 0xa6c2f1cf, 0x087232cc, 0x6de273cd, + 0xe510b4c9, 0x8080f5c8, 0x2e3036cb, 0x4ba077ca, 0x8fd6b8c0, + 0xea46f9c1, 0x44f63ac2, 0x21667bc3, 0xa994bcc7, 0xcc04fdc6, + 0x62b43ec5, 0x07247fc4, 0x6c6cc09c, 0x09fc819d, 0xa74c429e, + 0xc2dc039f, 0x4a2ec49b, 0x2fbe859a, 0x810e4699, 0xe49e0798, + 0x20e8c892, 0x45788993, 0xebc84a90, 0x8e580b91, 0x06aacc95, + 0x633a8d94, 0xcd8a4e97, 0xa81a0f96, 0xf564d080, 0x90f49181, + 0x3e445282, 0x5bd41383, 0xd326d487, 0xb6b69586, 0x18065685, + 0x7d961784, 0xb9e0d88e, 0xdc70998f, 0x72c05a8c, 0x17501b8d, + 0x9fa2dc89, 0xfa329d88, 0x54825e8b, 0x31121f8a, 0xee7fe0a7, + 0x8befa1a6, 0x255f62a5, 0x40cf23a4, 0xc83de4a0, 0xadada5a1, + 0x031d66a2, 0x668d27a3, 0xa2fbe8a9, 0xc76ba9a8, 0x69db6aab, + 0x0c4b2baa, 0x84b9ecae, 0xe129adaf, 0x4f996eac, 0x2a092fad, + 0x7777f0bb, 0x12e7b1ba, 0xbc5772b9, 0xd9c733b8, 0x5135f4bc, + 0x34a5b5bd, 0x9a1576be, 0xff8537bf, 0x3bf3f8b5, 0x5e63b9b4, + 0xf0d37ab7, 0x95433bb6, 0x1db1fcb2, 0x7821bdb3, 0xd6917eb0, + 0xb3013fb1}, + {0x00000000, 0x009001d1, 0x012003a2, 0x01b00273, 0x02400744, + 0x02d00695, 0x036004e6, 0x03f00537, 0x04800e88, 0x04100f59, + 0x05a00d2a, 0x05300cfb, 0x06c009cc, 0x0650081d, 0x07e00a6e, + 0x07700bbf, 0x09001d10, 0x09901cc1, 0x08201eb2, 0x08b01f63, + 0x0b401a54, 0x0bd01b85, 0x0a6019f6, 0x0af01827, 0x0d801398, + 0x0d101249, 0x0ca0103a, 0x0c3011eb, 0x0fc014dc, 0x0f50150d, + 0x0ee0177e, 0x0e7016af, 0x12003a20, 0x12903bf1, 0x13203982, + 0x13b03853, 0x10403d64, 0x10d03cb5, 0x11603ec6, 0x11f03f17, + 0x168034a8, 0x16103579, 0x17a0370a, 0x173036db, 0x14c033ec, + 0x1450323d, 0x15e0304e, 0x1570319f, 0x1b002730, 0x1b9026e1, + 0x1a202492, 0x1ab02543, 0x19402074, 0x19d021a5, 0x186023d6, + 0x18f02207, 0x1f8029b8, 0x1f102869, 0x1ea02a1a, 0x1e302bcb, + 0x1dc02efc, 0x1d502f2d, 0x1ce02d5e, 0x1c702c8f, 0x24007440, + 0x24907591, 0x252077e2, 0x25b07633, 0x26407304, 0x26d072d5, + 0x276070a6, 0x27f07177, 0x20807ac8, 0x20107b19, 0x21a0796a, + 0x213078bb, 0x22c07d8c, 0x22507c5d, 0x23e07e2e, 0x23707fff, + 0x2d006950, 0x2d906881, 0x2c206af2, 0x2cb06b23, 0x2f406e14, + 0x2fd06fc5, 0x2e606db6, 0x2ef06c67, 0x298067d8, 0x29106609, + 0x28a0647a, 0x283065ab, 0x2bc0609c, 0x2b50614d, 0x2ae0633e, + 0x2a7062ef, 0x36004e60, 0x36904fb1, 0x37204dc2, 0x37b04c13, + 0x34404924, 0x34d048f5, 0x35604a86, 0x35f04b57, 0x328040e8, + 0x32104139, 0x33a0434a, 0x3330429b, 0x30c047ac, 0x3050467d, + 0x31e0440e, 0x317045df, 0x3f005370, 0x3f9052a1, 0x3e2050d2, + 0x3eb05103, 0x3d405434, 0x3dd055e5, 0x3c605796, 0x3cf05647, + 0x3b805df8, 0x3b105c29, 0x3aa05e5a, 0x3a305f8b, 0x39c05abc, + 0x39505b6d, 0x38e0591e, 0x387058cf, 0x4800e880, 0x4890e951, + 0x4920eb22, 0x49b0eaf3, 0x4a40efc4, 0x4ad0ee15, 0x4b60ec66, + 0x4bf0edb7, 0x4c80e608, 0x4c10e7d9, 0x4da0e5aa, 0x4d30e47b, + 0x4ec0e14c, 0x4e50e09d, 0x4fe0e2ee, 0x4f70e33f, 0x4100f590, + 0x4190f441, 0x4020f632, 0x40b0f7e3, 0x4340f2d4, 0x43d0f305, + 0x4260f176, 0x42f0f0a7, 0x4580fb18, 0x4510fac9, 0x44a0f8ba, + 0x4430f96b, 0x47c0fc5c, 0x4750fd8d, 0x46e0fffe, 0x4670fe2f, + 0x5a00d2a0, 0x5a90d371, 0x5b20d102, 0x5bb0d0d3, 0x5840d5e4, + 0x58d0d435, 0x5960d646, 0x59f0d797, 0x5e80dc28, 0x5e10ddf9, + 0x5fa0df8a, 0x5f30de5b, 0x5cc0db6c, 0x5c50dabd, 0x5de0d8ce, + 0x5d70d91f, 0x5300cfb0, 0x5390ce61, 0x5220cc12, 0x52b0cdc3, + 0x5140c8f4, 0x51d0c925, 0x5060cb56, 0x50f0ca87, 0x5780c138, + 0x5710c0e9, 0x56a0c29a, 0x5630c34b, 0x55c0c67c, 0x5550c7ad, + 0x54e0c5de, 0x5470c40f, 0x6c009cc0, 0x6c909d11, 0x6d209f62, + 0x6db09eb3, 0x6e409b84, 0x6ed09a55, 0x6f609826, 0x6ff099f7, + 0x68809248, 0x68109399, 0x69a091ea, 0x6930903b, 0x6ac0950c, + 0x6a5094dd, 0x6be096ae, 0x6b70977f, 0x650081d0, 0x65908001, + 0x64208272, 0x64b083a3, 0x67408694, 0x67d08745, 0x66608536, + 0x66f084e7, 0x61808f58, 0x61108e89, 0x60a08cfa, 0x60308d2b, + 0x63c0881c, 0x635089cd, 0x62e08bbe, 0x62708a6f, 0x7e00a6e0, + 0x7e90a731, 0x7f20a542, 0x7fb0a493, 0x7c40a1a4, 0x7cd0a075, + 0x7d60a206, 0x7df0a3d7, 0x7a80a868, 0x7a10a9b9, 0x7ba0abca, + 0x7b30aa1b, 0x78c0af2c, 0x7850aefd, 0x79e0ac8e, 0x7970ad5f, + 0x7700bbf0, 0x7790ba21, 0x7620b852, 0x76b0b983, 0x7540bcb4, + 0x75d0bd65, 0x7460bf16, 0x74f0bec7, 0x7380b578, 0x7310b4a9, + 0x72a0b6da, 0x7230b70b, 0x71c0b23c, 0x7150b3ed, 0x70e0b19e, + 0x7070b04f}, + {0x00000000, 0x9001d100, 0x9000a203, 0x00017303, 0x90024405, + 0x00039505, 0x0002e606, 0x90033706, 0x90078809, 0x00065909, + 0x00072a0a, 0x9006fb0a, 0x0005cc0c, 0x90041d0c, 0x90056e0f, + 0x0004bf0f, 0x900c1011, 0x000dc111, 0x000cb212, 0x900d6312, + 0x000e5414, 0x900f8514, 0x900ef617, 0x000f2717, 0x000b9818, + 0x900a4918, 0x900b3a1b, 0x000aeb1b, 0x9009dc1d, 0x00080d1d, + 0x00097e1e, 0x9008af1e, 0x901b2021, 0x001af121, 0x001b8222, + 0x901a5322, 0x00196424, 0x9018b524, 0x9019c627, 0x00181727, + 0x001ca828, 0x901d7928, 0x901c0a2b, 0x001ddb2b, 0x901eec2d, + 0x001f3d2d, 0x001e4e2e, 0x901f9f2e, 0x00173030, 0x9016e130, + 0x90179233, 0x00164333, 0x90157435, 0x0014a535, 0x0015d636, + 0x90140736, 0x9010b839, 0x00116939, 0x00101a3a, 0x9011cb3a, + 0x0012fc3c, 0x90132d3c, 0x90125e3f, 0x00138f3f, 0x90354041, + 0x00349141, 0x0035e242, 0x90343342, 0x00370444, 0x9036d544, + 0x9037a647, 0x00367747, 0x0032c848, 0x90331948, 0x90326a4b, + 0x0033bb4b, 0x90308c4d, 0x00315d4d, 0x00302e4e, 0x9031ff4e, + 0x00395050, 0x90388150, 0x9039f253, 0x00382353, 0x903b1455, + 0x003ac555, 0x003bb656, 0x903a6756, 0x903ed859, 0x003f0959, + 0x003e7a5a, 0x903fab5a, 0x003c9c5c, 0x903d4d5c, 0x903c3e5f, + 0x003def5f, 0x002e6060, 0x902fb160, 0x902ec263, 0x002f1363, + 0x902c2465, 0x002df565, 0x002c8666, 0x902d5766, 0x9029e869, + 0x00283969, 0x00294a6a, 0x90289b6a, 0x002bac6c, 0x902a7d6c, + 0x902b0e6f, 0x002adf6f, 0x90227071, 0x0023a171, 0x0022d272, + 0x90230372, 0x00203474, 0x9021e574, 0x90209677, 0x00214777, + 0x0025f878, 0x90242978, 0x90255a7b, 0x00248b7b, 0x9027bc7d, + 0x00266d7d, 0x00271e7e, 0x9026cf7e, 0x90698081, 0x00685181, + 0x00692282, 0x9068f382, 0x006bc484, 0x906a1584, 0x906b6687, + 0x006ab787, 0x006e0888, 0x906fd988, 0x906eaa8b, 0x006f7b8b, + 0x906c4c8d, 0x006d9d8d, 0x006cee8e, 0x906d3f8e, 0x00659090, + 0x90644190, 0x90653293, 0x0064e393, 0x9067d495, 0x00660595, + 0x00677696, 0x9066a796, 0x90621899, 0x0063c999, 0x0062ba9a, + 0x90636b9a, 0x00605c9c, 0x90618d9c, 0x9060fe9f, 0x00612f9f, + 0x0072a0a0, 0x907371a0, 0x907202a3, 0x0073d3a3, 0x9070e4a5, + 0x007135a5, 0x007046a6, 0x907197a6, 0x907528a9, 0x0074f9a9, + 0x00758aaa, 0x90745baa, 0x00776cac, 0x9076bdac, 0x9077ceaf, + 0x00761faf, 0x907eb0b1, 0x007f61b1, 0x007e12b2, 0x907fc3b2, + 0x007cf4b4, 0x907d25b4, 0x907c56b7, 0x007d87b7, 0x007938b8, + 0x9078e9b8, 0x90799abb, 0x00784bbb, 0x907b7cbd, 0x007aadbd, + 0x007bdebe, 0x907a0fbe, 0x005cc0c0, 0x905d11c0, 0x905c62c3, + 0x005db3c3, 0x905e84c5, 0x005f55c5, 0x005e26c6, 0x905ff7c6, + 0x905b48c9, 0x005a99c9, 0x005beaca, 0x905a3bca, 0x00590ccc, + 0x9058ddcc, 0x9059aecf, 0x00587fcf, 0x9050d0d1, 0x005101d1, + 0x005072d2, 0x9051a3d2, 0x005294d4, 0x905345d4, 0x905236d7, + 0x0053e7d7, 0x005758d8, 0x905689d8, 0x9057fadb, 0x00562bdb, + 0x90551cdd, 0x0054cddd, 0x0055bede, 0x90546fde, 0x9047e0e1, + 0x004631e1, 0x004742e2, 0x904693e2, 0x0045a4e4, 0x904475e4, + 0x904506e7, 0x0044d7e7, 0x004068e8, 0x9041b9e8, 0x9040caeb, + 0x00411beb, 0x90422ced, 0x0043fded, 0x00428eee, 0x90435fee, + 0x004bf0f0, 0x904a21f0, 0x904b52f3, 0x004a83f3, 0x9049b4f5, + 0x004865f5, 0x004916f6, 0x9048c7f6, 0x904c78f9, 0x004da9f9, + 0x004cdafa, 0x904d0bfa, 0x004e3cfc, 0x904fedfc, 0x904e9eff, + 0x004f4fff}, + {0x00000000, 0x90d00101, 0x91a30201, 0x01730300, 0x93450401, + 0x03950500, 0x02e60600, 0x92360701, 0x96890801, 0x06590900, + 0x072a0a00, 0x97fa0b01, 0x05cc0c00, 0x951c0d01, 0x946f0e01, + 0x04bf0f00, 0x9d111001, 0x0dc11100, 0x0cb21200, 0x9c621301, + 0x0e541400, 0x9e841501, 0x9ff71601, 0x0f271700, 0x0b981800, + 0x9b481901, 0x9a3b1a01, 0x0aeb1b00, 0x98dd1c01, 0x080d1d00, + 0x097e1e00, 0x99ae1f01, 0x8a212001, 0x1af12100, 0x1b822200, + 0x8b522301, 0x19642400, 0x89b42501, 0x88c72601, 0x18172700, + 0x1ca82800, 0x8c782901, 0x8d0b2a01, 0x1ddb2b00, 0x8fed2c01, + 0x1f3d2d00, 0x1e4e2e00, 0x8e9e2f01, 0x17303000, 0x87e03101, + 0x86933201, 0x16433300, 0x84753401, 0x14a53500, 0x15d63600, + 0x85063701, 0x81b93801, 0x11693900, 0x101a3a00, 0x80ca3b01, + 0x12fc3c00, 0x822c3d01, 0x835f3e01, 0x138f3f00, 0xa4414001, + 0x34914100, 0x35e24200, 0xa5324301, 0x37044400, 0xa7d44501, + 0xa6a74601, 0x36774700, 0x32c84800, 0xa2184901, 0xa36b4a01, + 0x33bb4b00, 0xa18d4c01, 0x315d4d00, 0x302e4e00, 0xa0fe4f01, + 0x39505000, 0xa9805101, 0xa8f35201, 0x38235300, 0xaa155401, + 0x3ac55500, 0x3bb65600, 0xab665701, 0xafd95801, 0x3f095900, + 0x3e7a5a00, 0xaeaa5b01, 0x3c9c5c00, 0xac4c5d01, 0xad3f5e01, + 0x3def5f00, 0x2e606000, 0xbeb06101, 0xbfc36201, 0x2f136300, + 0xbd256401, 0x2df56500, 0x2c866600, 0xbc566701, 0xb8e96801, + 0x28396900, 0x294a6a00, 0xb99a6b01, 0x2bac6c00, 0xbb7c6d01, + 0xba0f6e01, 0x2adf6f00, 0xb3717001, 0x23a17100, 0x22d27200, + 0xb2027301, 0x20347400, 0xb0e47501, 0xb1977601, 0x21477700, + 0x25f87800, 0xb5287901, 0xb45b7a01, 0x248b7b00, 0xb6bd7c01, + 0x266d7d00, 0x271e7e00, 0xb7ce7f01, 0xf8818001, 0x68518100, + 0x69228200, 0xf9f28301, 0x6bc48400, 0xfb148501, 0xfa678601, + 0x6ab78700, 0x6e088800, 0xfed88901, 0xffab8a01, 0x6f7b8b00, + 0xfd4d8c01, 0x6d9d8d00, 0x6cee8e00, 0xfc3e8f01, 0x65909000, + 0xf5409101, 0xf4339201, 0x64e39300, 0xf6d59401, 0x66059500, + 0x67769600, 0xf7a69701, 0xf3199801, 0x63c99900, 0x62ba9a00, + 0xf26a9b01, 0x605c9c00, 0xf08c9d01, 0xf1ff9e01, 0x612f9f00, + 0x72a0a000, 0xe270a101, 0xe303a201, 0x73d3a300, 0xe1e5a401, + 0x7135a500, 0x7046a600, 0xe096a701, 0xe429a801, 0x74f9a900, + 0x758aaa00, 0xe55aab01, 0x776cac00, 0xe7bcad01, 0xe6cfae01, + 0x761faf00, 0xefb1b001, 0x7f61b100, 0x7e12b200, 0xeec2b301, + 0x7cf4b400, 0xec24b501, 0xed57b601, 0x7d87b700, 0x7938b800, + 0xe9e8b901, 0xe89bba01, 0x784bbb00, 0xea7dbc01, 0x7aadbd00, + 0x7bdebe00, 0xeb0ebf01, 0x5cc0c000, 0xcc10c101, 0xcd63c201, + 0x5db3c300, 0xcf85c401, 0x5f55c500, 0x5e26c600, 0xcef6c701, + 0xca49c801, 0x5a99c900, 0x5beaca00, 0xcb3acb01, 0x590ccc00, + 0xc9dccd01, 0xc8afce01, 0x587fcf00, 0xc1d1d001, 0x5101d100, + 0x5072d200, 0xc0a2d301, 0x5294d400, 0xc244d501, 0xc337d601, + 0x53e7d700, 0x5758d800, 0xc788d901, 0xc6fbda01, 0x562bdb00, + 0xc41ddc01, 0x54cddd00, 0x55bede00, 0xc56edf01, 0xd6e1e001, + 0x4631e100, 0x4742e200, 0xd792e301, 0x45a4e400, 0xd574e501, + 0xd407e601, 0x44d7e700, 0x4068e800, 0xd0b8e901, 0xd1cbea01, + 0x411beb00, 0xd32dec01, 0x43fded00, 0x428eee00, 0xd25eef01, + 0x4bf0f000, 0xdb20f101, 0xda53f201, 0x4a83f300, 0xd8b5f401, + 0x4865f500, 0x4916f600, 0xd9c6f701, 0xdd79f801, 0x4da9f900, + 0x4cdafa00, 0xdc0afb01, 0x4e3cfc00, 0xdeecfd01, 0xdf9ffe01, + 0x4f4fff00}}; + +static const word_t crc_braid_big_table[][256] = { + {0x00000000, 0x0101d090, 0x0102a391, 0x00037301, 0x01044593, + 0x00059503, 0x0006e602, 0x01073692, 0x01088996, 0x00095906, + 0x000a2a07, 0x010bfa97, 0x000ccc05, 0x010d1c95, 0x010e6f94, + 0x000fbf04, 0x0110119d, 0x0011c10d, 0x0012b20c, 0x0113629c, + 0x0014540e, 0x0115849e, 0x0116f79f, 0x0017270f, 0x0018980b, + 0x0119489b, 0x011a3b9a, 0x001beb0a, 0x011cdd98, 0x001d0d08, + 0x001e7e09, 0x011fae99, 0x0120218a, 0x0021f11a, 0x0022821b, + 0x0123528b, 0x00246419, 0x0125b489, 0x0126c788, 0x00271718, + 0x0028a81c, 0x0129788c, 0x012a0b8d, 0x002bdb1d, 0x012ced8f, + 0x002d3d1f, 0x002e4e1e, 0x012f9e8e, 0x00303017, 0x0131e087, + 0x01329386, 0x00334316, 0x01347584, 0x0035a514, 0x0036d615, + 0x01370685, 0x0138b981, 0x00396911, 0x003a1a10, 0x013bca80, + 0x003cfc12, 0x013d2c82, 0x013e5f83, 0x003f8f13, 0x014041a4, + 0x00419134, 0x0042e235, 0x014332a5, 0x00440437, 0x0145d4a7, + 0x0146a7a6, 0x00477736, 0x0048c832, 0x014918a2, 0x014a6ba3, + 0x004bbb33, 0x014c8da1, 0x004d5d31, 0x004e2e30, 0x014ffea0, + 0x00505039, 0x015180a9, 0x0152f3a8, 0x00532338, 0x015415aa, + 0x0055c53a, 0x0056b63b, 0x015766ab, 0x0158d9af, 0x0059093f, + 0x005a7a3e, 0x015baaae, 0x005c9c3c, 0x015d4cac, 0x015e3fad, + 0x005fef3d, 0x0060602e, 0x0161b0be, 0x0162c3bf, 0x0063132f, + 0x016425bd, 0x0065f52d, 0x0066862c, 0x016756bc, 0x0168e9b8, + 0x00693928, 0x006a4a29, 0x016b9ab9, 0x006cac2b, 0x016d7cbb, + 0x016e0fba, 0x006fdf2a, 0x017071b3, 0x0071a123, 0x0072d222, + 0x017302b2, 0x00743420, 0x0175e4b0, 0x017697b1, 0x00774721, + 0x0078f825, 0x017928b5, 0x017a5bb4, 0x007b8b24, 0x017cbdb6, + 0x007d6d26, 0x007e1e27, 0x017fceb7, 0x018081f8, 0x00815168, + 0x00822269, 0x0183f2f9, 0x0084c46b, 0x018514fb, 0x018667fa, + 0x0087b76a, 0x0088086e, 0x0189d8fe, 0x018aabff, 0x008b7b6f, + 0x018c4dfd, 0x008d9d6d, 0x008eee6c, 0x018f3efc, 0x00909065, + 0x019140f5, 0x019233f4, 0x0093e364, 0x0194d5f6, 0x00950566, + 0x00967667, 0x0197a6f7, 0x019819f3, 0x0099c963, 0x009aba62, + 0x019b6af2, 0x009c5c60, 0x019d8cf0, 0x019efff1, 0x009f2f61, + 0x00a0a072, 0x01a170e2, 0x01a203e3, 0x00a3d373, 0x01a4e5e1, + 0x00a53571, 0x00a64670, 0x01a796e0, 0x01a829e4, 0x00a9f974, + 0x00aa8a75, 0x01ab5ae5, 0x00ac6c77, 0x01adbce7, 0x01aecfe6, + 0x00af1f76, 0x01b0b1ef, 0x00b1617f, 0x00b2127e, 0x01b3c2ee, + 0x00b4f47c, 0x01b524ec, 0x01b657ed, 0x00b7877d, 0x00b83879, + 0x01b9e8e9, 0x01ba9be8, 0x00bb4b78, 0x01bc7dea, 0x00bdad7a, + 0x00bede7b, 0x01bf0eeb, 0x00c0c05c, 0x01c110cc, 0x01c263cd, + 0x00c3b35d, 0x01c485cf, 0x00c5555f, 0x00c6265e, 0x01c7f6ce, + 0x01c849ca, 0x00c9995a, 0x00caea5b, 0x01cb3acb, 0x00cc0c59, + 0x01cddcc9, 0x01ceafc8, 0x00cf7f58, 0x01d0d1c1, 0x00d10151, + 0x00d27250, 0x01d3a2c0, 0x00d49452, 0x01d544c2, 0x01d637c3, + 0x00d7e753, 0x00d85857, 0x01d988c7, 0x01dafbc6, 0x00db2b56, + 0x01dc1dc4, 0x00ddcd54, 0x00debe55, 0x01df6ec5, 0x01e0e1d6, + 0x00e13146, 0x00e24247, 0x01e392d7, 0x00e4a445, 0x01e574d5, + 0x01e607d4, 0x00e7d744, 0x00e86840, 0x01e9b8d0, 0x01eacbd1, + 0x00eb1b41, 0x01ec2dd3, 0x00edfd43, 0x00ee8e42, 0x01ef5ed2, + 0x00f0f04b, 0x01f120db, 0x01f253da, 0x00f3834a, 0x01f4b5d8, + 0x00f56548, 0x00f61649, 0x01f7c6d9, 0x01f879dd, 0x00f9a94d, + 0x00fada4c, 0x01fb0adc, 0x00fc3c4e, 0x01fdecde, 0x01fe9fdf, + 0x00ff4f4f}, + {0x00000000, 0x00d10190, 0x03a20090, 0x03730100, 0x05440290, + 0x05950300, 0x06e60200, 0x06370390, 0x09880790, 0x09590600, + 0x0a2a0700, 0x0afb0690, 0x0ccc0500, 0x0c1d0490, 0x0f6e0590, + 0x0fbf0400, 0x11100c90, 0x11c10d00, 0x12b20c00, 0x12630d90, + 0x14540e00, 0x14850f90, 0x17f60e90, 0x17270f00, 0x18980b00, + 0x18490a90, 0x1b3a0b90, 0x1beb0a00, 0x1ddc0990, 0x1d0d0800, + 0x1e7e0900, 0x1eaf0890, 0x21201b90, 0x21f11a00, 0x22821b00, + 0x22531a90, 0x24641900, 0x24b51890, 0x27c61990, 0x27171800, + 0x28a81c00, 0x28791d90, 0x2b0a1c90, 0x2bdb1d00, 0x2dec1e90, + 0x2d3d1f00, 0x2e4e1e00, 0x2e9f1f90, 0x30301700, 0x30e11690, + 0x33921790, 0x33431600, 0x35741590, 0x35a51400, 0x36d61500, + 0x36071490, 0x39b81090, 0x39691100, 0x3a1a1000, 0x3acb1190, + 0x3cfc1200, 0x3c2d1390, 0x3f5e1290, 0x3f8f1300, 0x41403590, + 0x41913400, 0x42e23500, 0x42333490, 0x44043700, 0x44d53690, + 0x47a63790, 0x47773600, 0x48c83200, 0x48193390, 0x4b6a3290, + 0x4bbb3300, 0x4d8c3090, 0x4d5d3100, 0x4e2e3000, 0x4eff3190, + 0x50503900, 0x50813890, 0x53f23990, 0x53233800, 0x55143b90, + 0x55c53a00, 0x56b63b00, 0x56673a90, 0x59d83e90, 0x59093f00, + 0x5a7a3e00, 0x5aab3f90, 0x5c9c3c00, 0x5c4d3d90, 0x5f3e3c90, + 0x5fef3d00, 0x60602e00, 0x60b12f90, 0x63c22e90, 0x63132f00, + 0x65242c90, 0x65f52d00, 0x66862c00, 0x66572d90, 0x69e82990, + 0x69392800, 0x6a4a2900, 0x6a9b2890, 0x6cac2b00, 0x6c7d2a90, + 0x6f0e2b90, 0x6fdf2a00, 0x71702290, 0x71a12300, 0x72d22200, + 0x72032390, 0x74342000, 0x74e52190, 0x77962090, 0x77472100, + 0x78f82500, 0x78292490, 0x7b5a2590, 0x7b8b2400, 0x7dbc2790, + 0x7d6d2600, 0x7e1e2700, 0x7ecf2690, 0x81806990, 0x81516800, + 0x82226900, 0x82f36890, 0x84c46b00, 0x84156a90, 0x87666b90, + 0x87b76a00, 0x88086e00, 0x88d96f90, 0x8baa6e90, 0x8b7b6f00, + 0x8d4c6c90, 0x8d9d6d00, 0x8eee6c00, 0x8e3f6d90, 0x90906500, + 0x90416490, 0x93326590, 0x93e36400, 0x95d46790, 0x95056600, + 0x96766700, 0x96a76690, 0x99186290, 0x99c96300, 0x9aba6200, + 0x9a6b6390, 0x9c5c6000, 0x9c8d6190, 0x9ffe6090, 0x9f2f6100, + 0xa0a07200, 0xa0717390, 0xa3027290, 0xa3d37300, 0xa5e47090, + 0xa5357100, 0xa6467000, 0xa6977190, 0xa9287590, 0xa9f97400, + 0xaa8a7500, 0xaa5b7490, 0xac6c7700, 0xacbd7690, 0xafce7790, + 0xaf1f7600, 0xb1b07e90, 0xb1617f00, 0xb2127e00, 0xb2c37f90, + 0xb4f47c00, 0xb4257d90, 0xb7567c90, 0xb7877d00, 0xb8387900, + 0xb8e97890, 0xbb9a7990, 0xbb4b7800, 0xbd7c7b90, 0xbdad7a00, + 0xbede7b00, 0xbe0f7a90, 0xc0c05c00, 0xc0115d90, 0xc3625c90, + 0xc3b35d00, 0xc5845e90, 0xc5555f00, 0xc6265e00, 0xc6f75f90, + 0xc9485b90, 0xc9995a00, 0xcaea5b00, 0xca3b5a90, 0xcc0c5900, + 0xccdd5890, 0xcfae5990, 0xcf7f5800, 0xd1d05090, 0xd1015100, + 0xd2725000, 0xd2a35190, 0xd4945200, 0xd4455390, 0xd7365290, + 0xd7e75300, 0xd8585700, 0xd8895690, 0xdbfa5790, 0xdb2b5600, + 0xdd1c5590, 0xddcd5400, 0xdebe5500, 0xde6f5490, 0xe1e04790, + 0xe1314600, 0xe2424700, 0xe2934690, 0xe4a44500, 0xe4754490, + 0xe7064590, 0xe7d74400, 0xe8684000, 0xe8b94190, 0xebca4090, + 0xeb1b4100, 0xed2c4290, 0xedfd4300, 0xee8e4200, 0xee5f4390, + 0xf0f04b00, 0xf0214a90, 0xf3524b90, 0xf3834a00, 0xf5b44990, + 0xf5654800, 0xf6164900, 0xf6c74890, 0xf9784c90, 0xf9a94d00, + 0xfada4c00, 0xfa0b4d90, 0xfc3c4e00, 0xfced4f90, 0xff9e4e90, + 0xff4f4f00}, + {0x00000000, 0xd1019000, 0xa2032001, 0x7302b001, 0x44074002, + 0x9506d002, 0xe6046003, 0x3705f003, 0x880e8004, 0x590f1004, + 0x2a0da005, 0xfb0c3005, 0xcc09c006, 0x1d085006, 0x6e0ae007, + 0xbf0b7007, 0x101d0009, 0xc11c9009, 0xb21e2008, 0x631fb008, + 0x541a400b, 0x851bd00b, 0xf619600a, 0x2718f00a, 0x9813800d, + 0x4912100d, 0x3a10a00c, 0xeb11300c, 0xdc14c00f, 0x0d15500f, + 0x7e17e00e, 0xaf16700e, 0x203a0012, 0xf13b9012, 0x82392013, + 0x5338b013, 0x643d4010, 0xb53cd010, 0xc63e6011, 0x173ff011, + 0xa8348016, 0x79351016, 0x0a37a017, 0xdb363017, 0xec33c014, + 0x3d325014, 0x4e30e015, 0x9f317015, 0x3027001b, 0xe126901b, + 0x9224201a, 0x4325b01a, 0x74204019, 0xa521d019, 0xd6236018, + 0x0722f018, 0xb829801f, 0x6928101f, 0x1a2aa01e, 0xcb2b301e, + 0xfc2ec01d, 0x2d2f501d, 0x5e2de01c, 0x8f2c701c, 0x40740024, + 0x91759024, 0xe2772025, 0x3376b025, 0x04734026, 0xd572d026, + 0xa6706027, 0x7771f027, 0xc87a8020, 0x197b1020, 0x6a79a021, + 0xbb783021, 0x8c7dc022, 0x5d7c5022, 0x2e7ee023, 0xff7f7023, + 0x5069002d, 0x8168902d, 0xf26a202c, 0x236bb02c, 0x146e402f, + 0xc56fd02f, 0xb66d602e, 0x676cf02e, 0xd8678029, 0x09661029, + 0x7a64a028, 0xab653028, 0x9c60c02b, 0x4d61502b, 0x3e63e02a, + 0xef62702a, 0x604e0036, 0xb14f9036, 0xc24d2037, 0x134cb037, + 0x24494034, 0xf548d034, 0x864a6035, 0x574bf035, 0xe8408032, + 0x39411032, 0x4a43a033, 0x9b423033, 0xac47c030, 0x7d465030, + 0x0e44e031, 0xdf457031, 0x7053003f, 0xa152903f, 0xd250203e, + 0x0351b03e, 0x3454403d, 0xe555d03d, 0x9657603c, 0x4756f03c, + 0xf85d803b, 0x295c103b, 0x5a5ea03a, 0x8b5f303a, 0xbc5ac039, + 0x6d5b5039, 0x1e59e038, 0xcf587038, 0x80e80048, 0x51e99048, + 0x22eb2049, 0xf3eab049, 0xc4ef404a, 0x15eed04a, 0x66ec604b, + 0xb7edf04b, 0x08e6804c, 0xd9e7104c, 0xaae5a04d, 0x7be4304d, + 0x4ce1c04e, 0x9de0504e, 0xeee2e04f, 0x3fe3704f, 0x90f50041, + 0x41f49041, 0x32f62040, 0xe3f7b040, 0xd4f24043, 0x05f3d043, + 0x76f16042, 0xa7f0f042, 0x18fb8045, 0xc9fa1045, 0xbaf8a044, + 0x6bf93044, 0x5cfcc047, 0x8dfd5047, 0xfeffe046, 0x2ffe7046, + 0xa0d2005a, 0x71d3905a, 0x02d1205b, 0xd3d0b05b, 0xe4d54058, + 0x35d4d058, 0x46d66059, 0x97d7f059, 0x28dc805e, 0xf9dd105e, + 0x8adfa05f, 0x5bde305f, 0x6cdbc05c, 0xbdda505c, 0xced8e05d, + 0x1fd9705d, 0xb0cf0053, 0x61ce9053, 0x12cc2052, 0xc3cdb052, + 0xf4c84051, 0x25c9d051, 0x56cb6050, 0x87caf050, 0x38c18057, + 0xe9c01057, 0x9ac2a056, 0x4bc33056, 0x7cc6c055, 0xadc75055, + 0xdec5e054, 0x0fc47054, 0xc09c006c, 0x119d906c, 0x629f206d, + 0xb39eb06d, 0x849b406e, 0x559ad06e, 0x2698606f, 0xf799f06f, + 0x48928068, 0x99931068, 0xea91a069, 0x3b903069, 0x0c95c06a, + 0xdd94506a, 0xae96e06b, 0x7f97706b, 0xd0810065, 0x01809065, + 0x72822064, 0xa383b064, 0x94864067, 0x4587d067, 0x36856066, + 0xe784f066, 0x588f8061, 0x898e1061, 0xfa8ca060, 0x2b8d3060, + 0x1c88c063, 0xcd895063, 0xbe8be062, 0x6f8a7062, 0xe0a6007e, + 0x31a7907e, 0x42a5207f, 0x93a4b07f, 0xa4a1407c, 0x75a0d07c, + 0x06a2607d, 0xd7a3f07d, 0x68a8807a, 0xb9a9107a, 0xcaaba07b, + 0x1baa307b, 0x2cafc078, 0xfdae5078, 0x8eace079, 0x5fad7079, + 0xf0bb0077, 0x21ba9077, 0x52b82076, 0x83b9b076, 0xb4bc4075, + 0x65bdd075, 0x16bf6074, 0xc7bef074, 0x78b58073, 0xa9b41073, + 0xdab6a072, 0x0bb73072, 0x3cb2c071, 0xedb35071, 0x9eb1e070, + 0x4fb07070}, + {0x00000000, 0x01419065, 0x028220cb, 0x03c3b0ae, 0x07044226, + 0x0645d243, 0x058662ed, 0x04c7f288, 0x0e08844c, 0x0f491429, + 0x0c8aa487, 0x0dcb34e2, 0x090cc66a, 0x084d560f, 0x0b8ee6a1, + 0x0acf76c4, 0x1c100899, 0x1d5198fc, 0x1e922852, 0x1fd3b837, + 0x1b144abf, 0x1a55dada, 0x19966a74, 0x18d7fa11, 0x12188cd5, + 0x13591cb0, 0x109aac1e, 0x11db3c7b, 0x151ccef3, 0x145d5e96, + 0x179eee38, 0x16df7e5d, 0x3b201382, 0x3a6183e7, 0x39a23349, + 0x38e3a32c, 0x3c2451a4, 0x3d65c1c1, 0x3ea6716f, 0x3fe7e10a, + 0x352897ce, 0x346907ab, 0x37aab705, 0x36eb2760, 0x322cd5e8, + 0x336d458d, 0x30aef523, 0x31ef6546, 0x27301b1b, 0x26718b7e, + 0x25b23bd0, 0x24f3abb5, 0x2034593d, 0x2175c958, 0x22b679f6, + 0x23f7e993, 0x29389f57, 0x28790f32, 0x2bbabf9c, 0x2afb2ff9, + 0x2e3cdd71, 0x2f7d4d14, 0x2cbefdba, 0x2dff6ddf, 0x754025b4, + 0x7401b5d1, 0x77c2057f, 0x7683951a, 0x72446792, 0x7305f7f7, + 0x70c64759, 0x7187d73c, 0x7b48a1f8, 0x7a09319d, 0x79ca8133, + 0x788b1156, 0x7c4ce3de, 0x7d0d73bb, 0x7ecec315, 0x7f8f5370, + 0x69502d2d, 0x6811bd48, 0x6bd20de6, 0x6a939d83, 0x6e546f0b, + 0x6f15ff6e, 0x6cd64fc0, 0x6d97dfa5, 0x6758a961, 0x66193904, + 0x65da89aa, 0x649b19cf, 0x605ceb47, 0x611d7b22, 0x62decb8c, + 0x639f5be9, 0x4e603636, 0x4f21a653, 0x4ce216fd, 0x4da38698, + 0x49647410, 0x4825e475, 0x4be654db, 0x4aa7c4be, 0x4068b27a, + 0x4129221f, 0x42ea92b1, 0x43ab02d4, 0x476cf05c, 0x462d6039, + 0x45eed097, 0x44af40f2, 0x52703eaf, 0x5331aeca, 0x50f21e64, + 0x51b38e01, 0x55747c89, 0x5435ecec, 0x57f65c42, 0x56b7cc27, + 0x5c78bae3, 0x5d392a86, 0x5efa9a28, 0x5fbb0a4d, 0x5b7cf8c5, + 0x5a3d68a0, 0x59fed80e, 0x58bf486b, 0xe98049d8, 0xe8c1d9bd, + 0xeb026913, 0xea43f976, 0xee840bfe, 0xefc59b9b, 0xec062b35, + 0xed47bb50, 0xe788cd94, 0xe6c95df1, 0xe50aed5f, 0xe44b7d3a, + 0xe08c8fb2, 0xe1cd1fd7, 0xe20eaf79, 0xe34f3f1c, 0xf5904141, + 0xf4d1d124, 0xf712618a, 0xf653f1ef, 0xf2940367, 0xf3d59302, + 0xf01623ac, 0xf157b3c9, 0xfb98c50d, 0xfad95568, 0xf91ae5c6, + 0xf85b75a3, 0xfc9c872b, 0xfddd174e, 0xfe1ea7e0, 0xff5f3785, + 0xd2a05a5a, 0xd3e1ca3f, 0xd0227a91, 0xd163eaf4, 0xd5a4187c, + 0xd4e58819, 0xd72638b7, 0xd667a8d2, 0xdca8de16, 0xdde94e73, + 0xde2afedd, 0xdf6b6eb8, 0xdbac9c30, 0xdaed0c55, 0xd92ebcfb, + 0xd86f2c9e, 0xceb052c3, 0xcff1c2a6, 0xcc327208, 0xcd73e26d, + 0xc9b410e5, 0xc8f58080, 0xcb36302e, 0xca77a04b, 0xc0b8d68f, + 0xc1f946ea, 0xc23af644, 0xc37b6621, 0xc7bc94a9, 0xc6fd04cc, + 0xc53eb462, 0xc47f2407, 0x9cc06c6c, 0x9d81fc09, 0x9e424ca7, + 0x9f03dcc2, 0x9bc42e4a, 0x9a85be2f, 0x99460e81, 0x98079ee4, + 0x92c8e820, 0x93897845, 0x904ac8eb, 0x910b588e, 0x95ccaa06, + 0x948d3a63, 0x974e8acd, 0x960f1aa8, 0x80d064f5, 0x8191f490, + 0x8252443e, 0x8313d45b, 0x87d426d3, 0x8695b6b6, 0x85560618, + 0x8417967d, 0x8ed8e0b9, 0x8f9970dc, 0x8c5ac072, 0x8d1b5017, + 0x89dca29f, 0x889d32fa, 0x8b5e8254, 0x8a1f1231, 0xa7e07fee, + 0xa6a1ef8b, 0xa5625f25, 0xa423cf40, 0xa0e43dc8, 0xa1a5adad, + 0xa2661d03, 0xa3278d66, 0xa9e8fba2, 0xa8a96bc7, 0xab6adb69, + 0xaa2b4b0c, 0xaeecb984, 0xafad29e1, 0xac6e994f, 0xad2f092a, + 0xbbf07777, 0xbab1e712, 0xb97257bc, 0xb833c7d9, 0xbcf43551, + 0xbdb5a534, 0xbe76159a, 0xbf3785ff, 0xb5f8f33b, 0xb4b9635e, + 0xb77ad3f0, 0xb63b4395, 0xb2fcb11d, 0xb3bd2178, 0xb07e91d6, + 0xb13f01b3}}; + +#endif + +#endif + +#if N == 3 + +#if W == 8 + +static const crc_t crc_braid_table[][256] = { + {0x00000000, 0x47596181, 0x8eb2c302, 0xc9eba283, 0xad668607, + 0xea3fe786, 0x23d44505, 0x648d2484, 0xeace0c0d, 0xad976d8c, + 0x647ccf0f, 0x2325ae8e, 0x47a88a0a, 0x00f1eb8b, 0xc91a4908, + 0x8e432889, 0x659f1819, 0x22c67998, 0xeb2ddb1b, 0xac74ba9a, + 0xc8f99e1e, 0x8fa0ff9f, 0x464b5d1c, 0x01123c9d, 0x8f511414, + 0xc8087595, 0x01e3d716, 0x46bab697, 0x22379213, 0x656ef392, + 0xac855111, 0xebdc3090, 0xcb3e3032, 0x8c6751b3, 0x458cf330, + 0x02d592b1, 0x6658b635, 0x2101d7b4, 0xe8ea7537, 0xafb314b6, + 0x21f03c3f, 0x66a95dbe, 0xaf42ff3d, 0xe81b9ebc, 0x8c96ba38, + 0xcbcfdbb9, 0x0224793a, 0x457d18bb, 0xaea1282b, 0xe9f849aa, + 0x2013eb29, 0x674a8aa8, 0x03c7ae2c, 0x449ecfad, 0x8d756d2e, + 0xca2c0caf, 0x446f2426, 0x033645a7, 0xcadde724, 0x8d8486a5, + 0xe909a221, 0xae50c3a0, 0x67bb6123, 0x20e200a2, 0x267f6067, + 0x612601e6, 0xa8cda365, 0xef94c2e4, 0x8b19e660, 0xcc4087e1, + 0x05ab2562, 0x42f244e3, 0xccb16c6a, 0x8be80deb, 0x4203af68, + 0x055acee9, 0x61d7ea6d, 0x268e8bec, 0xef65296f, 0xa83c48ee, + 0x43e0787e, 0x04b919ff, 0xcd52bb7c, 0x8a0bdafd, 0xee86fe79, + 0xa9df9ff8, 0x60343d7b, 0x276d5cfa, 0xa92e7473, 0xee7715f2, + 0x279cb771, 0x60c5d6f0, 0x0448f274, 0x431193f5, 0x8afa3176, + 0xcda350f7, 0xed415055, 0xaa1831d4, 0x63f39357, 0x24aaf2d6, + 0x4027d652, 0x077eb7d3, 0xce951550, 0x89cc74d1, 0x078f5c58, + 0x40d63dd9, 0x893d9f5a, 0xce64fedb, 0xaae9da5f, 0xedb0bbde, + 0x245b195d, 0x630278dc, 0x88de484c, 0xcf8729cd, 0x066c8b4e, + 0x4135eacf, 0x25b8ce4b, 0x62e1afca, 0xab0a0d49, 0xec536cc8, + 0x62104441, 0x254925c0, 0xeca28743, 0xabfbe6c2, 0xcf76c246, + 0x882fa3c7, 0x41c40144, 0x069d60c5, 0x4cfec0ce, 0x0ba7a14f, + 0xc24c03cc, 0x8515624d, 0xe19846c9, 0xa6c12748, 0x6f2a85cb, + 0x2873e44a, 0xa630ccc3, 0xe169ad42, 0x28820fc1, 0x6fdb6e40, + 0x0b564ac4, 0x4c0f2b45, 0x85e489c6, 0xc2bde847, 0x2961d8d7, + 0x6e38b956, 0xa7d31bd5, 0xe08a7a54, 0x84075ed0, 0xc35e3f51, + 0x0ab59dd2, 0x4decfc53, 0xc3afd4da, 0x84f6b55b, 0x4d1d17d8, + 0x0a447659, 0x6ec952dd, 0x2990335c, 0xe07b91df, 0xa722f05e, + 0x87c0f0fc, 0xc099917d, 0x097233fe, 0x4e2b527f, 0x2aa676fb, + 0x6dff177a, 0xa414b5f9, 0xe34dd478, 0x6d0efcf1, 0x2a579d70, + 0xe3bc3ff3, 0xa4e55e72, 0xc0687af6, 0x87311b77, 0x4edab9f4, + 0x0983d875, 0xe25fe8e5, 0xa5068964, 0x6ced2be7, 0x2bb44a66, + 0x4f396ee2, 0x08600f63, 0xc18bade0, 0x86d2cc61, 0x0891e4e8, + 0x4fc88569, 0x862327ea, 0xc17a466b, 0xa5f762ef, 0xe2ae036e, + 0x2b45a1ed, 0x6c1cc06c, 0x6a81a0a9, 0x2dd8c128, 0xe43363ab, + 0xa36a022a, 0xc7e726ae, 0x80be472f, 0x4955e5ac, 0x0e0c842d, + 0x804faca4, 0xc716cd25, 0x0efd6fa6, 0x49a40e27, 0x2d292aa3, + 0x6a704b22, 0xa39be9a1, 0xe4c28820, 0x0f1eb8b0, 0x4847d931, + 0x81ac7bb2, 0xc6f51a33, 0xa2783eb7, 0xe5215f36, 0x2ccafdb5, + 0x6b939c34, 0xe5d0b4bd, 0xa289d53c, 0x6b6277bf, 0x2c3b163e, + 0x48b632ba, 0x0fef533b, 0xc604f1b8, 0x815d9039, 0xa1bf909b, + 0xe6e6f11a, 0x2f0d5399, 0x68543218, 0x0cd9169c, 0x4b80771d, + 0x826bd59e, 0xc532b41f, 0x4b719c96, 0x0c28fd17, 0xc5c35f94, + 0x829a3e15, 0xe6171a91, 0xa14e7b10, 0x68a5d993, 0x2ffcb812, + 0xc4208882, 0x8379e903, 0x4a924b80, 0x0dcb2a01, 0x69460e85, + 0x2e1f6f04, 0xe7f4cd87, 0xa0adac06, 0x2eee848f, 0x69b7e50e, + 0xa05c478d, 0xe705260c, 0x83880288, 0xc4d16309, 0x0d3ac18a, + 0x4a63a00b}, + {0x00000000, 0x99fd819c, 0x83f8033b, 0x1a0582a7, 0xb7f30675, + 0x2e0e87e9, 0x340b054e, 0xadf684d2, 0xdfe50ce9, 0x46188d75, + 0x5c1d0fd2, 0xc5e08e4e, 0x68160a9c, 0xf1eb8b00, 0xebee09a7, + 0x7213883b, 0x0fc919d1, 0x9634984d, 0x8c311aea, 0x15cc9b76, + 0xb83a1fa4, 0x21c79e38, 0x3bc21c9f, 0xa23f9d03, 0xd02c1538, + 0x49d194a4, 0x53d41603, 0xca29979f, 0x67df134d, 0xfe2292d1, + 0xe4271076, 0x7dda91ea, 0x1f9233a2, 0x866fb23e, 0x9c6a3099, + 0x0597b105, 0xa86135d7, 0x319cb44b, 0x2b9936ec, 0xb264b770, + 0xc0773f4b, 0x598abed7, 0x438f3c70, 0xda72bdec, 0x7784393e, + 0xee79b8a2, 0xf47c3a05, 0x6d81bb99, 0x105b2a73, 0x89a6abef, + 0x93a32948, 0x0a5ea8d4, 0xa7a82c06, 0x3e55ad9a, 0x24502f3d, + 0xbdadaea1, 0xcfbe269a, 0x5643a706, 0x4c4625a1, 0xd5bba43d, + 0x784d20ef, 0xe1b0a173, 0xfbb523d4, 0x6248a248, 0x3f246744, + 0xa6d9e6d8, 0xbcdc647f, 0x2521e5e3, 0x88d76131, 0x112ae0ad, + 0x0b2f620a, 0x92d2e396, 0xe0c16bad, 0x793cea31, 0x63396896, + 0xfac4e90a, 0x57326dd8, 0xcecfec44, 0xd4ca6ee3, 0x4d37ef7f, + 0x30ed7e95, 0xa910ff09, 0xb3157dae, 0x2ae8fc32, 0x871e78e0, + 0x1ee3f97c, 0x04e67bdb, 0x9d1bfa47, 0xef08727c, 0x76f5f3e0, + 0x6cf07147, 0xf50df0db, 0x58fb7409, 0xc106f595, 0xdb037732, + 0x42fef6ae, 0x20b654e6, 0xb94bd57a, 0xa34e57dd, 0x3ab3d641, + 0x97455293, 0x0eb8d30f, 0x14bd51a8, 0x8d40d034, 0xff53580f, + 0x66aed993, 0x7cab5b34, 0xe556daa8, 0x48a05e7a, 0xd15ddfe6, + 0xcb585d41, 0x52a5dcdd, 0x2f7f4d37, 0xb682ccab, 0xac874e0c, + 0x357acf90, 0x988c4b42, 0x0171cade, 0x1b744879, 0x8289c9e5, + 0xf09a41de, 0x6967c042, 0x736242e5, 0xea9fc379, 0x476947ab, + 0xde94c637, 0xc4914490, 0x5d6cc50c, 0x7e48ce88, 0xe7b54f14, + 0xfdb0cdb3, 0x644d4c2f, 0xc9bbc8fd, 0x50464961, 0x4a43cbc6, + 0xd3be4a5a, 0xa1adc261, 0x385043fd, 0x2255c15a, 0xbba840c6, + 0x165ec414, 0x8fa34588, 0x95a6c72f, 0x0c5b46b3, 0x7181d759, + 0xe87c56c5, 0xf279d462, 0x6b8455fe, 0xc672d12c, 0x5f8f50b0, + 0x458ad217, 0xdc77538b, 0xae64dbb0, 0x37995a2c, 0x2d9cd88b, + 0xb4615917, 0x1997ddc5, 0x806a5c59, 0x9a6fdefe, 0x03925f62, + 0x61dafd2a, 0xf8277cb6, 0xe222fe11, 0x7bdf7f8d, 0xd629fb5f, + 0x4fd47ac3, 0x55d1f864, 0xcc2c79f8, 0xbe3ff1c3, 0x27c2705f, + 0x3dc7f2f8, 0xa43a7364, 0x09ccf7b6, 0x9031762a, 0x8a34f48d, + 0x13c97511, 0x6e13e4fb, 0xf7ee6567, 0xedebe7c0, 0x7416665c, + 0xd9e0e28e, 0x401d6312, 0x5a18e1b5, 0xc3e56029, 0xb1f6e812, + 0x280b698e, 0x320eeb29, 0xabf36ab5, 0x0605ee67, 0x9ff86ffb, + 0x85fded5c, 0x1c006cc0, 0x416ca9cc, 0xd8912850, 0xc294aaf7, + 0x5b692b6b, 0xf69fafb9, 0x6f622e25, 0x7567ac82, 0xec9a2d1e, + 0x9e89a525, 0x077424b9, 0x1d71a61e, 0x848c2782, 0x297aa350, + 0xb08722cc, 0xaa82a06b, 0x337f21f7, 0x4ea5b01d, 0xd7583181, + 0xcd5db326, 0x54a032ba, 0xf956b668, 0x60ab37f4, 0x7aaeb553, + 0xe35334cf, 0x9140bcf4, 0x08bd3d68, 0x12b8bfcf, 0x8b453e53, + 0x26b3ba81, 0xbf4e3b1d, 0xa54bb9ba, 0x3cb63826, 0x5efe9a6e, + 0xc7031bf2, 0xdd069955, 0x44fb18c9, 0xe90d9c1b, 0x70f01d87, + 0x6af59f20, 0xf3081ebc, 0x811b9687, 0x18e6171b, 0x02e395bc, + 0x9b1e1420, 0x36e890f2, 0xaf15116e, 0xb51093c9, 0x2ced1255, + 0x513783bf, 0xc8ca0223, 0xd2cf8084, 0x4b320118, 0xe6c485ca, + 0x7f390456, 0x653c86f1, 0xfcc1076d, 0x8ed28f56, 0x172f0eca, + 0x0d2a8c6d, 0x94d70df1, 0x39218923, 0xa0dc08bf, 0xbad98a18, + 0x23240b84}, + {0x00000000, 0xfc919d10, 0x49203a23, 0xb5b1a733, 0x92407446, + 0x6ed1e956, 0xdb604e65, 0x27f1d375, 0x9483e88f, 0x6812759f, + 0xdda3d2ac, 0x21324fbc, 0x06c39cc9, 0xfa5201d9, 0x4fe3a6ea, + 0xb3723bfa, 0x9904d11d, 0x65954c0d, 0xd024eb3e, 0x2cb5762e, + 0x0b44a55b, 0xf7d5384b, 0x42649f78, 0xbef50268, 0x0d873992, + 0xf116a482, 0x44a703b1, 0xb8369ea1, 0x9fc74dd4, 0x6356d0c4, + 0xd6e777f7, 0x2a76eae7, 0x820aa239, 0x7e9b3f29, 0xcb2a981a, + 0x37bb050a, 0x104ad67f, 0xecdb4b6f, 0x596aec5c, 0xa5fb714c, + 0x16894ab6, 0xea18d7a6, 0x5fa97095, 0xa338ed85, 0x84c93ef0, + 0x7858a3e0, 0xcde904d3, 0x317899c3, 0x1b0e7324, 0xe79fee34, + 0x522e4907, 0xaebfd417, 0x894e0762, 0x75df9a72, 0xc06e3d41, + 0x3cffa051, 0x8f8d9bab, 0x731c06bb, 0xc6ada188, 0x3a3c3c98, + 0x1dcdefed, 0xe15c72fd, 0x54edd5ce, 0xa87c48de, 0xb4164471, + 0x4887d961, 0xfd367e52, 0x01a7e342, 0x26563037, 0xdac7ad27, + 0x6f760a14, 0x93e79704, 0x2095acfe, 0xdc0431ee, 0x69b596dd, + 0x95240bcd, 0xb2d5d8b8, 0x4e4445a8, 0xfbf5e29b, 0x07647f8b, + 0x2d12956c, 0xd183087c, 0x6432af4f, 0x98a3325f, 0xbf52e12a, + 0x43c37c3a, 0xf672db09, 0x0ae34619, 0xb9917de3, 0x4500e0f3, + 0xf0b147c0, 0x0c20dad0, 0x2bd109a5, 0xd74094b5, 0x62f13386, + 0x9e60ae96, 0x361ce648, 0xca8d7b58, 0x7f3cdc6b, 0x83ad417b, + 0xa45c920e, 0x58cd0f1e, 0xed7ca82d, 0x11ed353d, 0xa29f0ec7, + 0x5e0e93d7, 0xebbf34e4, 0x172ea9f4, 0x30df7a81, 0xcc4ee791, + 0x79ff40a2, 0x856eddb2, 0xaf183755, 0x5389aa45, 0xe6380d76, + 0x1aa99066, 0x3d584313, 0xc1c9de03, 0x74787930, 0x88e9e420, + 0x3b9bdfda, 0xc70a42ca, 0x72bbe5f9, 0x8e2a78e9, 0xa9dbab9c, + 0x554a368c, 0xe0fb91bf, 0x1c6a0caf, 0xd82f88e1, 0x24be15f1, + 0x910fb2c2, 0x6d9e2fd2, 0x4a6ffca7, 0xb6fe61b7, 0x034fc684, + 0xffde5b94, 0x4cac606e, 0xb03dfd7e, 0x058c5a4d, 0xf91dc75d, + 0xdeec1428, 0x227d8938, 0x97cc2e0b, 0x6b5db31b, 0x412b59fc, + 0xbdbac4ec, 0x080b63df, 0xf49afecf, 0xd36b2dba, 0x2ffab0aa, + 0x9a4b1799, 0x66da8a89, 0xd5a8b173, 0x29392c63, 0x9c888b50, + 0x60191640, 0x47e8c535, 0xbb795825, 0x0ec8ff16, 0xf2596206, + 0x5a252ad8, 0xa6b4b7c8, 0x130510fb, 0xef948deb, 0xc8655e9e, + 0x34f4c38e, 0x814564bd, 0x7dd4f9ad, 0xcea6c257, 0x32375f47, + 0x8786f874, 0x7b176564, 0x5ce6b611, 0xa0772b01, 0x15c68c32, + 0xe9571122, 0xc321fbc5, 0x3fb066d5, 0x8a01c1e6, 0x76905cf6, + 0x51618f83, 0xadf01293, 0x1841b5a0, 0xe4d028b0, 0x57a2134a, + 0xab338e5a, 0x1e822969, 0xe213b479, 0xc5e2670c, 0x3973fa1c, + 0x8cc25d2f, 0x7053c03f, 0x6c39cc90, 0x90a85180, 0x2519f6b3, + 0xd9886ba3, 0xfe79b8d6, 0x02e825c6, 0xb75982f5, 0x4bc81fe5, + 0xf8ba241f, 0x042bb90f, 0xb19a1e3c, 0x4d0b832c, 0x6afa5059, + 0x966bcd49, 0x23da6a7a, 0xdf4bf76a, 0xf53d1d8d, 0x09ac809d, + 0xbc1d27ae, 0x408cbabe, 0x677d69cb, 0x9becf4db, 0x2e5d53e8, + 0xd2cccef8, 0x61bef502, 0x9d2f6812, 0x289ecf21, 0xd40f5231, + 0xf3fe8144, 0x0f6f1c54, 0xbadebb67, 0x464f2677, 0xee336ea9, + 0x12a2f3b9, 0xa713548a, 0x5b82c99a, 0x7c731aef, 0x80e287ff, + 0x355320cc, 0xc9c2bddc, 0x7ab08626, 0x86211b36, 0x3390bc05, + 0xcf012115, 0xe8f0f260, 0x14616f70, 0xa1d0c843, 0x5d415553, + 0x7737bfb4, 0x8ba622a4, 0x3e178597, 0xc2861887, 0xe577cbf2, + 0x19e656e2, 0xac57f1d1, 0x50c66cc1, 0xe3b4573b, 0x1f25ca2b, + 0xaa946d18, 0x5605f008, 0x71f4237d, 0x8d65be6d, 0x38d4195e, + 0xc445844e}, + {0x00000000, 0x005c11c1, 0x00b82382, 0x00e43243, 0x01704704, + 0x012c56c5, 0x01c86486, 0x01947547, 0x02e08e08, 0x02bc9fc9, + 0x0258ad8a, 0x0204bc4b, 0x0390c90c, 0x03ccd8cd, 0x0328ea8e, + 0x0374fb4f, 0x05c11c10, 0x059d0dd1, 0x05793f92, 0x05252e53, + 0x04b15b14, 0x04ed4ad5, 0x04097896, 0x04556957, 0x07219218, + 0x077d83d9, 0x0799b19a, 0x07c5a05b, 0x0651d51c, 0x060dc4dd, + 0x06e9f69e, 0x06b5e75f, 0x0b823820, 0x0bde29e1, 0x0b3a1ba2, + 0x0b660a63, 0x0af27f24, 0x0aae6ee5, 0x0a4a5ca6, 0x0a164d67, + 0x0962b628, 0x093ea7e9, 0x09da95aa, 0x0986846b, 0x0812f12c, + 0x084ee0ed, 0x08aad2ae, 0x08f6c36f, 0x0e432430, 0x0e1f35f1, + 0x0efb07b2, 0x0ea71673, 0x0f336334, 0x0f6f72f5, 0x0f8b40b6, + 0x0fd75177, 0x0ca3aa38, 0x0cffbbf9, 0x0c1b89ba, 0x0c47987b, + 0x0dd3ed3c, 0x0d8ffcfd, 0x0d6bcebe, 0x0d37df7f, 0x17047040, + 0x17586181, 0x17bc53c2, 0x17e04203, 0x16743744, 0x16282685, + 0x16cc14c6, 0x16900507, 0x15e4fe48, 0x15b8ef89, 0x155cddca, + 0x1500cc0b, 0x1494b94c, 0x14c8a88d, 0x142c9ace, 0x14708b0f, + 0x12c56c50, 0x12997d91, 0x127d4fd2, 0x12215e13, 0x13b52b54, + 0x13e93a95, 0x130d08d6, 0x13511917, 0x1025e258, 0x1079f399, + 0x109dc1da, 0x10c1d01b, 0x1155a55c, 0x1109b49d, 0x11ed86de, + 0x11b1971f, 0x1c864860, 0x1cda59a1, 0x1c3e6be2, 0x1c627a23, + 0x1df60f64, 0x1daa1ea5, 0x1d4e2ce6, 0x1d123d27, 0x1e66c668, + 0x1e3ad7a9, 0x1edee5ea, 0x1e82f42b, 0x1f16816c, 0x1f4a90ad, + 0x1faea2ee, 0x1ff2b32f, 0x19475470, 0x191b45b1, 0x19ff77f2, + 0x19a36633, 0x18371374, 0x186b02b5, 0x188f30f6, 0x18d32137, + 0x1ba7da78, 0x1bfbcbb9, 0x1b1ff9fa, 0x1b43e83b, 0x1ad79d7c, + 0x1a8b8cbd, 0x1a6fbefe, 0x1a33af3f, 0x2e08e080, 0x2e54f141, + 0x2eb0c302, 0x2eecd2c3, 0x2f78a784, 0x2f24b645, 0x2fc08406, + 0x2f9c95c7, 0x2ce86e88, 0x2cb47f49, 0x2c504d0a, 0x2c0c5ccb, + 0x2d98298c, 0x2dc4384d, 0x2d200a0e, 0x2d7c1bcf, 0x2bc9fc90, + 0x2b95ed51, 0x2b71df12, 0x2b2dced3, 0x2ab9bb94, 0x2ae5aa55, + 0x2a019816, 0x2a5d89d7, 0x29297298, 0x29756359, 0x2991511a, + 0x29cd40db, 0x2859359c, 0x2805245d, 0x28e1161e, 0x28bd07df, + 0x258ad8a0, 0x25d6c961, 0x2532fb22, 0x256eeae3, 0x24fa9fa4, + 0x24a68e65, 0x2442bc26, 0x241eade7, 0x276a56a8, 0x27364769, + 0x27d2752a, 0x278e64eb, 0x261a11ac, 0x2646006d, 0x26a2322e, + 0x26fe23ef, 0x204bc4b0, 0x2017d571, 0x20f3e732, 0x20aff6f3, + 0x213b83b4, 0x21679275, 0x2183a036, 0x21dfb1f7, 0x22ab4ab8, + 0x22f75b79, 0x2213693a, 0x224f78fb, 0x23db0dbc, 0x23871c7d, + 0x23632e3e, 0x233f3fff, 0x390c90c0, 0x39508101, 0x39b4b342, + 0x39e8a283, 0x387cd7c4, 0x3820c605, 0x38c4f446, 0x3898e587, + 0x3bec1ec8, 0x3bb00f09, 0x3b543d4a, 0x3b082c8b, 0x3a9c59cc, + 0x3ac0480d, 0x3a247a4e, 0x3a786b8f, 0x3ccd8cd0, 0x3c919d11, + 0x3c75af52, 0x3c29be93, 0x3dbdcbd4, 0x3de1da15, 0x3d05e856, + 0x3d59f997, 0x3e2d02d8, 0x3e711319, 0x3e95215a, 0x3ec9309b, + 0x3f5d45dc, 0x3f01541d, 0x3fe5665e, 0x3fb9779f, 0x328ea8e0, + 0x32d2b921, 0x32368b62, 0x326a9aa3, 0x33feefe4, 0x33a2fe25, + 0x3346cc66, 0x331adda7, 0x306e26e8, 0x30323729, 0x30d6056a, + 0x308a14ab, 0x311e61ec, 0x3142702d, 0x31a6426e, 0x31fa53af, + 0x374fb4f0, 0x3713a531, 0x37f79772, 0x37ab86b3, 0x363ff3f4, + 0x3663e235, 0x3687d076, 0x36dbc1b7, 0x35af3af8, 0x35f32b39, + 0x3517197a, 0x354b08bb, 0x34df7dfc, 0x34836c3d, 0x34675e7e, + 0x343b4fbf}, + {0x00000000, 0x5c11c100, 0xb8238200, 0xe4324300, 0xc0440403, + 0x9c55c503, 0x78678603, 0x24764703, 0x308b0805, 0x6c9ac905, + 0x88a88a05, 0xd4b94b05, 0xf0cf0c06, 0xacdecd06, 0x48ec8e06, + 0x14fd4f06, 0x6116100a, 0x3d07d10a, 0xd935920a, 0x8524530a, + 0xa1521409, 0xfd43d509, 0x19719609, 0x45605709, 0x519d180f, + 0x0d8cd90f, 0xe9be9a0f, 0xb5af5b0f, 0x91d91c0c, 0xcdc8dd0c, + 0x29fa9e0c, 0x75eb5f0c, 0xc22c2014, 0x9e3de114, 0x7a0fa214, + 0x261e6314, 0x02682417, 0x5e79e517, 0xba4ba617, 0xe65a6717, + 0xf2a72811, 0xaeb6e911, 0x4a84aa11, 0x16956b11, 0x32e32c12, + 0x6ef2ed12, 0x8ac0ae12, 0xd6d16f12, 0xa33a301e, 0xff2bf11e, + 0x1b19b21e, 0x4708731e, 0x637e341d, 0x3f6ff51d, 0xdb5db61d, + 0x874c771d, 0x93b1381b, 0xcfa0f91b, 0x2b92ba1b, 0x77837b1b, + 0x53f53c18, 0x0fe4fd18, 0xebd6be18, 0xb7c77f18, 0x345b402b, + 0x684a812b, 0x8c78c22b, 0xd069032b, 0xf41f4428, 0xa80e8528, + 0x4c3cc628, 0x102d0728, 0x04d0482e, 0x58c1892e, 0xbcf3ca2e, + 0xe0e20b2e, 0xc4944c2d, 0x98858d2d, 0x7cb7ce2d, 0x20a60f2d, + 0x554d5021, 0x095c9121, 0xed6ed221, 0xb17f1321, 0x95095422, + 0xc9189522, 0x2d2ad622, 0x713b1722, 0x65c65824, 0x39d79924, + 0xdde5da24, 0x81f41b24, 0xa5825c27, 0xf9939d27, 0x1da1de27, + 0x41b01f27, 0xf677603f, 0xaa66a13f, 0x4e54e23f, 0x1245233f, + 0x3633643c, 0x6a22a53c, 0x8e10e63c, 0xd201273c, 0xc6fc683a, + 0x9aeda93a, 0x7edfea3a, 0x22ce2b3a, 0x06b86c39, 0x5aa9ad39, + 0xbe9bee39, 0xe28a2f39, 0x97617035, 0xcb70b135, 0x2f42f235, + 0x73533335, 0x57257436, 0x0b34b536, 0xef06f636, 0xb3173736, + 0xa7ea7830, 0xfbfbb930, 0x1fc9fa30, 0x43d83b30, 0x67ae7c33, + 0x3bbfbd33, 0xdf8dfe33, 0x839c3f33, 0x68b68056, 0x34a74156, + 0xd0950256, 0x8c84c356, 0xa8f28455, 0xf4e34555, 0x10d10655, + 0x4cc0c755, 0x583d8853, 0x042c4953, 0xe01e0a53, 0xbc0fcb53, + 0x98798c50, 0xc4684d50, 0x205a0e50, 0x7c4bcf50, 0x09a0905c, + 0x55b1515c, 0xb183125c, 0xed92d35c, 0xc9e4945f, 0x95f5555f, + 0x71c7165f, 0x2dd6d75f, 0x392b9859, 0x653a5959, 0x81081a59, + 0xdd19db59, 0xf96f9c5a, 0xa57e5d5a, 0x414c1e5a, 0x1d5ddf5a, + 0xaa9aa042, 0xf68b6142, 0x12b92242, 0x4ea8e342, 0x6adea441, + 0x36cf6541, 0xd2fd2641, 0x8eece741, 0x9a11a847, 0xc6006947, + 0x22322a47, 0x7e23eb47, 0x5a55ac44, 0x06446d44, 0xe2762e44, + 0xbe67ef44, 0xcb8cb048, 0x979d7148, 0x73af3248, 0x2fbef348, + 0x0bc8b44b, 0x57d9754b, 0xb3eb364b, 0xeffaf74b, 0xfb07b84d, + 0xa716794d, 0x43243a4d, 0x1f35fb4d, 0x3b43bc4e, 0x67527d4e, + 0x83603e4e, 0xdf71ff4e, 0x5cedc07d, 0x00fc017d, 0xe4ce427d, + 0xb8df837d, 0x9ca9c47e, 0xc0b8057e, 0x248a467e, 0x789b877e, + 0x6c66c878, 0x30770978, 0xd4454a78, 0x88548b78, 0xac22cc7b, + 0xf0330d7b, 0x14014e7b, 0x48108f7b, 0x3dfbd077, 0x61ea1177, + 0x85d85277, 0xd9c99377, 0xfdbfd474, 0xa1ae1574, 0x459c5674, + 0x198d9774, 0x0d70d872, 0x51611972, 0xb5535a72, 0xe9429b72, + 0xcd34dc71, 0x91251d71, 0x75175e71, 0x29069f71, 0x9ec1e069, + 0xc2d02169, 0x26e26269, 0x7af3a369, 0x5e85e46a, 0x0294256a, + 0xe6a6666a, 0xbab7a76a, 0xae4ae86c, 0xf25b296c, 0x16696a6c, + 0x4a78ab6c, 0x6e0eec6f, 0x321f2d6f, 0xd62d6e6f, 0x8a3caf6f, + 0xffd7f063, 0xa3c63163, 0x47f47263, 0x1be5b363, 0x3f93f460, + 0x63823560, 0x87b07660, 0xdba1b760, 0xcf5cf866, 0x934d3966, + 0x777f7a66, 0x2b6ebb66, 0x0f18fc65, 0x53093d65, 0xb73b7e65, + 0xeb2abf65}, + {0x00000000, 0xd16d00ac, 0x12d9015b, 0xc3b401f7, 0x25b202b6, + 0xf4df021a, 0x376b03ed, 0xe6060341, 0x4b64056c, 0x9a0905c0, + 0x59bd0437, 0x88d0049b, 0x6ed607da, 0xbfbb0776, 0x7c0f0681, + 0xad62062d, 0x96c80ad8, 0x47a50a74, 0x84110b83, 0x557c0b2f, + 0xb37a086e, 0x621708c2, 0xa1a30935, 0x70ce0999, 0xddac0fb4, + 0x0cc10f18, 0xcf750eef, 0x1e180e43, 0xf81e0d02, 0x29730dae, + 0xeac70c59, 0x3baa0cf5, 0x9d9315b3, 0x4cfe151f, 0x8f4a14e8, + 0x5e271444, 0xb8211705, 0x694c17a9, 0xaaf8165e, 0x7b9516f2, + 0xd6f710df, 0x079a1073, 0xc42e1184, 0x15431128, 0xf3451269, + 0x222812c5, 0xe19c1332, 0x30f1139e, 0x0b5b1f6b, 0xda361fc7, + 0x19821e30, 0xc8ef1e9c, 0x2ee91ddd, 0xff841d71, 0x3c301c86, + 0xed5d1c2a, 0x403f1a07, 0x91521aab, 0x52e61b5c, 0x838b1bf0, + 0x658d18b1, 0xb4e0181d, 0x775419ea, 0xa6391946, 0x8b252b65, + 0x5a482bc9, 0x99fc2a3e, 0x48912a92, 0xae9729d3, 0x7ffa297f, + 0xbc4e2888, 0x6d232824, 0xc0412e09, 0x112c2ea5, 0xd2982f52, + 0x03f52ffe, 0xe5f32cbf, 0x349e2c13, 0xf72a2de4, 0x26472d48, + 0x1ded21bd, 0xcc802111, 0x0f3420e6, 0xde59204a, 0x385f230b, + 0xe93223a7, 0x2a862250, 0xfbeb22fc, 0x568924d1, 0x87e4247d, + 0x4450258a, 0x953d2526, 0x733b2667, 0xa25626cb, 0x61e2273c, + 0xb08f2790, 0x16b63ed6, 0xc7db3e7a, 0x046f3f8d, 0xd5023f21, + 0x33043c60, 0xe2693ccc, 0x21dd3d3b, 0xf0b03d97, 0x5dd23bba, + 0x8cbf3b16, 0x4f0b3ae1, 0x9e663a4d, 0x7860390c, 0xa90d39a0, + 0x6ab93857, 0xbbd438fb, 0x807e340e, 0x511334a2, 0x92a73555, + 0x43ca35f9, 0xa5cc36b8, 0x74a13614, 0xb71537e3, 0x6678374f, + 0xcb1a3162, 0x1a7731ce, 0xd9c33039, 0x08ae3095, 0xeea833d4, + 0x3fc53378, 0xfc71328f, 0x2d1c3223, 0xa64956c9, 0x77245665, + 0xb4905792, 0x65fd573e, 0x83fb547f, 0x529654d3, 0x91225524, + 0x404f5588, 0xed2d53a5, 0x3c405309, 0xfff452fe, 0x2e995252, + 0xc89f5113, 0x19f251bf, 0xda465048, 0x0b2b50e4, 0x30815c11, + 0xe1ec5cbd, 0x22585d4a, 0xf3355de6, 0x15335ea7, 0xc45e5e0b, + 0x07ea5ffc, 0xd6875f50, 0x7be5597d, 0xaa8859d1, 0x693c5826, + 0xb851588a, 0x5e575bcb, 0x8f3a5b67, 0x4c8e5a90, 0x9de35a3c, + 0x3bda437a, 0xeab743d6, 0x29034221, 0xf86e428d, 0x1e6841cc, + 0xcf054160, 0x0cb14097, 0xdddc403b, 0x70be4616, 0xa1d346ba, + 0x6267474d, 0xb30a47e1, 0x550c44a0, 0x8461440c, 0x47d545fb, + 0x96b84557, 0xad1249a2, 0x7c7f490e, 0xbfcb48f9, 0x6ea64855, + 0x88a04b14, 0x59cd4bb8, 0x9a794a4f, 0x4b144ae3, 0xe6764cce, + 0x371b4c62, 0xf4af4d95, 0x25c24d39, 0xc3c44e78, 0x12a94ed4, + 0xd11d4f23, 0x00704f8f, 0x2d6c7dac, 0xfc017d00, 0x3fb57cf7, + 0xeed87c5b, 0x08de7f1a, 0xd9b37fb6, 0x1a077e41, 0xcb6a7eed, + 0x660878c0, 0xb765786c, 0x74d1799b, 0xa5bc7937, 0x43ba7a76, + 0x92d77ada, 0x51637b2d, 0x800e7b81, 0xbba47774, 0x6ac977d8, + 0xa97d762f, 0x78107683, 0x9e1675c2, 0x4f7b756e, 0x8ccf7499, + 0x5da27435, 0xf0c07218, 0x21ad72b4, 0xe2197343, 0x337473ef, + 0xd57270ae, 0x041f7002, 0xc7ab71f5, 0x16c67159, 0xb0ff681f, + 0x619268b3, 0xa2266944, 0x734b69e8, 0x954d6aa9, 0x44206a05, + 0x87946bf2, 0x56f96b5e, 0xfb9b6d73, 0x2af66ddf, 0xe9426c28, + 0x382f6c84, 0xde296fc5, 0x0f446f69, 0xccf06e9e, 0x1d9d6e32, + 0x263762c7, 0xf75a626b, 0x34ee639c, 0xe5836330, 0x03856071, + 0xd2e860dd, 0x115c612a, 0xc0316186, 0x6d5367ab, 0xbc3e6707, + 0x7f8a66f0, 0xaee7665c, 0x48e1651d, 0x998c65b1, 0x5a386446, + 0x8b5564ea}, + {0x00000000, 0xfc91ad91, 0x49205b21, 0xb5b1f6b0, 0x9240b642, + 0x6ed11bd3, 0xdb60ed63, 0x27f140f2, 0x94826c87, 0x6813c116, + 0xdda237a6, 0x21339a37, 0x06c2dac5, 0xfa537754, 0x4fe281e4, + 0xb3732c75, 0x9907d90d, 0x6596749c, 0xd027822c, 0x2cb62fbd, + 0x0b476f4f, 0xf7d6c2de, 0x4267346e, 0xbef699ff, 0x0d85b58a, + 0xf114181b, 0x44a5eeab, 0xb834433a, 0x9fc503c8, 0x6354ae59, + 0xd6e558e9, 0x2a74f578, 0x820cb219, 0x7e9d1f88, 0xcb2ce938, + 0x37bd44a9, 0x104c045b, 0xecdda9ca, 0x596c5f7a, 0xa5fdf2eb, + 0x168ede9e, 0xea1f730f, 0x5fae85bf, 0xa33f282e, 0x84ce68dc, + 0x785fc54d, 0xcdee33fd, 0x317f9e6c, 0x1b0b6b14, 0xe79ac685, + 0x522b3035, 0xaeba9da4, 0x894bdd56, 0x75da70c7, 0xc06b8677, + 0x3cfa2be6, 0x8f890793, 0x7318aa02, 0xc6a95cb2, 0x3a38f123, + 0x1dc9b1d1, 0xe1581c40, 0x54e9eaf0, 0xa8784761, 0xb41a6431, + 0x488bc9a0, 0xfd3a3f10, 0x01ab9281, 0x265ad273, 0xdacb7fe2, + 0x6f7a8952, 0x93eb24c3, 0x209808b6, 0xdc09a527, 0x69b85397, + 0x9529fe06, 0xb2d8bef4, 0x4e491365, 0xfbf8e5d5, 0x07694844, + 0x2d1dbd3c, 0xd18c10ad, 0x643de61d, 0x98ac4b8c, 0xbf5d0b7e, + 0x43cca6ef, 0xf67d505f, 0x0aecfdce, 0xb99fd1bb, 0x450e7c2a, + 0xf0bf8a9a, 0x0c2e270b, 0x2bdf67f9, 0xd74eca68, 0x62ff3cd8, + 0x9e6e9149, 0x3616d628, 0xca877bb9, 0x7f368d09, 0x83a72098, + 0xa456606a, 0x58c7cdfb, 0xed763b4b, 0x11e796da, 0xa294baaf, + 0x5e05173e, 0xebb4e18e, 0x17254c1f, 0x30d40ced, 0xcc45a17c, + 0x79f457cc, 0x8565fa5d, 0xaf110f25, 0x5380a2b4, 0xe6315404, + 0x1aa0f995, 0x3d51b967, 0xc1c014f6, 0x7471e246, 0x88e04fd7, + 0x3b9363a2, 0xc702ce33, 0x72b33883, 0x8e229512, 0xa9d3d5e0, + 0x55427871, 0xe0f38ec1, 0x1c622350, 0xd837c861, 0x24a665f0, + 0x91179340, 0x6d863ed1, 0x4a777e23, 0xb6e6d3b2, 0x03572502, + 0xffc68893, 0x4cb5a4e6, 0xb0240977, 0x0595ffc7, 0xf9045256, + 0xdef512a4, 0x2264bf35, 0x97d54985, 0x6b44e414, 0x4130116c, + 0xbda1bcfd, 0x08104a4d, 0xf481e7dc, 0xd370a72e, 0x2fe10abf, + 0x9a50fc0f, 0x66c1519e, 0xd5b27deb, 0x2923d07a, 0x9c9226ca, + 0x60038b5b, 0x47f2cba9, 0xbb636638, 0x0ed29088, 0xf2433d19, + 0x5a3b7a78, 0xa6aad7e9, 0x131b2159, 0xef8a8cc8, 0xc87bcc3a, + 0x34ea61ab, 0x815b971b, 0x7dca3a8a, 0xceb916ff, 0x3228bb6e, + 0x87994dde, 0x7b08e04f, 0x5cf9a0bd, 0xa0680d2c, 0x15d9fb9c, + 0xe948560d, 0xc33ca375, 0x3fad0ee4, 0x8a1cf854, 0x768d55c5, + 0x517c1537, 0xadedb8a6, 0x185c4e16, 0xe4cde387, 0x57becff2, + 0xab2f6263, 0x1e9e94d3, 0xe20f3942, 0xc5fe79b0, 0x396fd421, + 0x8cde2291, 0x704f8f00, 0x6c2dac50, 0x90bc01c1, 0x250df771, + 0xd99c5ae0, 0xfe6d1a12, 0x02fcb783, 0xb74d4133, 0x4bdceca2, + 0xf8afc0d7, 0x043e6d46, 0xb18f9bf6, 0x4d1e3667, 0x6aef7695, + 0x967edb04, 0x23cf2db4, 0xdf5e8025, 0xf52a755d, 0x09bbd8cc, + 0xbc0a2e7c, 0x409b83ed, 0x676ac31f, 0x9bfb6e8e, 0x2e4a983e, + 0xd2db35af, 0x61a819da, 0x9d39b44b, 0x288842fb, 0xd419ef6a, + 0xf3e8af98, 0x0f790209, 0xbac8f4b9, 0x46595928, 0xee211e49, + 0x12b0b3d8, 0xa7014568, 0x5b90e8f9, 0x7c61a80b, 0x80f0059a, + 0x3541f32a, 0xc9d05ebb, 0x7aa372ce, 0x8632df5f, 0x338329ef, + 0xcf12847e, 0xe8e3c48c, 0x1472691d, 0xa1c39fad, 0x5d52323c, + 0x7726c744, 0x8bb76ad5, 0x3e069c65, 0xc29731f4, 0xe5667106, + 0x19f7dc97, 0xac462a27, 0x50d787b6, 0xe3a4abc3, 0x1f350652, + 0xaa84f0e2, 0x56155d73, 0x71e41d81, 0x8d75b010, 0x38c446a0, + 0xc455eb31}, + {0x00000000, 0x006c90c1, 0x00d92182, 0x00b5b143, 0x01b24304, + 0x01ded3c5, 0x016b6286, 0x0107f247, 0x03648608, 0x030816c9, + 0x03bda78a, 0x03d1374b, 0x02d6c50c, 0x02ba55cd, 0x020fe48e, + 0x0263744f, 0x06c90c10, 0x06a59cd1, 0x06102d92, 0x067cbd53, + 0x077b4f14, 0x0717dfd5, 0x07a26e96, 0x07cefe57, 0x05ad8a18, + 0x05c11ad9, 0x0574ab9a, 0x05183b5b, 0x041fc91c, 0x047359dd, + 0x04c6e89e, 0x04aa785f, 0x0d921820, 0x0dfe88e1, 0x0d4b39a2, + 0x0d27a963, 0x0c205b24, 0x0c4ccbe5, 0x0cf97aa6, 0x0c95ea67, + 0x0ef69e28, 0x0e9a0ee9, 0x0e2fbfaa, 0x0e432f6b, 0x0f44dd2c, + 0x0f284ded, 0x0f9dfcae, 0x0ff16c6f, 0x0b5b1430, 0x0b3784f1, + 0x0b8235b2, 0x0beea573, 0x0ae95734, 0x0a85c7f5, 0x0a3076b6, + 0x0a5ce677, 0x083f9238, 0x085302f9, 0x08e6b3ba, 0x088a237b, + 0x098dd13c, 0x09e141fd, 0x0954f0be, 0x0938607f, 0x1b243040, + 0x1b48a081, 0x1bfd11c2, 0x1b918103, 0x1a967344, 0x1afae385, + 0x1a4f52c6, 0x1a23c207, 0x1840b648, 0x182c2689, 0x189997ca, + 0x18f5070b, 0x19f2f54c, 0x199e658d, 0x192bd4ce, 0x1947440f, + 0x1ded3c50, 0x1d81ac91, 0x1d341dd2, 0x1d588d13, 0x1c5f7f54, + 0x1c33ef95, 0x1c865ed6, 0x1ceace17, 0x1e89ba58, 0x1ee52a99, + 0x1e509bda, 0x1e3c0b1b, 0x1f3bf95c, 0x1f57699d, 0x1fe2d8de, + 0x1f8e481f, 0x16b62860, 0x16dab8a1, 0x166f09e2, 0x16039923, + 0x17046b64, 0x1768fba5, 0x17dd4ae6, 0x17b1da27, 0x15d2ae68, + 0x15be3ea9, 0x150b8fea, 0x15671f2b, 0x1460ed6c, 0x140c7dad, + 0x14b9ccee, 0x14d55c2f, 0x107f2470, 0x1013b4b1, 0x10a605f2, + 0x10ca9533, 0x11cd6774, 0x11a1f7b5, 0x111446f6, 0x1178d637, + 0x131ba278, 0x137732b9, 0x13c283fa, 0x13ae133b, 0x12a9e17c, + 0x12c571bd, 0x1270c0fe, 0x121c503f, 0x36486080, 0x3624f041, + 0x36914102, 0x36fdd1c3, 0x37fa2384, 0x3796b345, 0x37230206, + 0x374f92c7, 0x352ce688, 0x35407649, 0x35f5c70a, 0x359957cb, + 0x349ea58c, 0x34f2354d, 0x3447840e, 0x342b14cf, 0x30816c90, + 0x30edfc51, 0x30584d12, 0x3034ddd3, 0x31332f94, 0x315fbf55, + 0x31ea0e16, 0x31869ed7, 0x33e5ea98, 0x33897a59, 0x333ccb1a, + 0x33505bdb, 0x3257a99c, 0x323b395d, 0x328e881e, 0x32e218df, + 0x3bda78a0, 0x3bb6e861, 0x3b035922, 0x3b6fc9e3, 0x3a683ba4, + 0x3a04ab65, 0x3ab11a26, 0x3add8ae7, 0x38befea8, 0x38d26e69, + 0x3867df2a, 0x380b4feb, 0x390cbdac, 0x39602d6d, 0x39d59c2e, + 0x39b90cef, 0x3d1374b0, 0x3d7fe471, 0x3dca5532, 0x3da6c5f3, + 0x3ca137b4, 0x3ccda775, 0x3c781636, 0x3c1486f7, 0x3e77f2b8, + 0x3e1b6279, 0x3eaed33a, 0x3ec243fb, 0x3fc5b1bc, 0x3fa9217d, + 0x3f1c903e, 0x3f7000ff, 0x2d6c50c0, 0x2d00c001, 0x2db57142, + 0x2dd9e183, 0x2cde13c4, 0x2cb28305, 0x2c073246, 0x2c6ba287, + 0x2e08d6c8, 0x2e644609, 0x2ed1f74a, 0x2ebd678b, 0x2fba95cc, + 0x2fd6050d, 0x2f63b44e, 0x2f0f248f, 0x2ba55cd0, 0x2bc9cc11, + 0x2b7c7d52, 0x2b10ed93, 0x2a171fd4, 0x2a7b8f15, 0x2ace3e56, + 0x2aa2ae97, 0x28c1dad8, 0x28ad4a19, 0x2818fb5a, 0x28746b9b, + 0x297399dc, 0x291f091d, 0x29aab85e, 0x29c6289f, 0x20fe48e0, + 0x2092d821, 0x20276962, 0x204bf9a3, 0x214c0be4, 0x21209b25, + 0x21952a66, 0x21f9baa7, 0x239acee8, 0x23f65e29, 0x2343ef6a, + 0x232f7fab, 0x22288dec, 0x22441d2d, 0x22f1ac6e, 0x229d3caf, + 0x263744f0, 0x265bd431, 0x26ee6572, 0x2682f5b3, 0x278507f4, + 0x27e99735, 0x275c2676, 0x2730b6b7, 0x2553c2f8, 0x253f5239, + 0x258ae37a, 0x25e673bb, 0x24e181fc, 0x248d113d, 0x2438a07e, + 0x245430bf}}; + +static const word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0xc1906c0000000000, 0x8221d90000000000, + 0x43b1b50000000000, 0x0443b20100000000, 0xc5d3de0100000000, + 0x86626b0100000000, 0x47f2070100000000, 0x0886640300000000, + 0xc916080300000000, 0x8aa7bd0300000000, 0x4b37d10300000000, + 0x0cc5d60200000000, 0xcd55ba0200000000, 0x8ee40f0200000000, + 0x4f74630200000000, 0x100cc90600000000, 0xd19ca50600000000, + 0x922d100600000000, 0x53bd7c0600000000, 0x144f7b0700000000, + 0xd5df170700000000, 0x966ea20700000000, 0x57fece0700000000, + 0x188aad0500000000, 0xd91ac10500000000, 0x9aab740500000000, + 0x5b3b180500000000, 0x1cc91f0400000000, 0xdd59730400000000, + 0x9ee8c60400000000, 0x5f78aa0400000000, 0x2018920d00000000, + 0xe188fe0d00000000, 0xa2394b0d00000000, 0x63a9270d00000000, + 0x245b200c00000000, 0xe5cb4c0c00000000, 0xa67af90c00000000, + 0x67ea950c00000000, 0x289ef60e00000000, 0xe90e9a0e00000000, + 0xaabf2f0e00000000, 0x6b2f430e00000000, 0x2cdd440f00000000, + 0xed4d280f00000000, 0xaefc9d0f00000000, 0x6f6cf10f00000000, + 0x30145b0b00000000, 0xf184370b00000000, 0xb235820b00000000, + 0x73a5ee0b00000000, 0x3457e90a00000000, 0xf5c7850a00000000, + 0xb676300a00000000, 0x77e65c0a00000000, 0x38923f0800000000, + 0xf902530800000000, 0xbab3e60800000000, 0x7b238a0800000000, + 0x3cd18d0900000000, 0xfd41e10900000000, 0xbef0540900000000, + 0x7f60380900000000, 0x4030241b00000000, 0x81a0481b00000000, + 0xc211fd1b00000000, 0x0381911b00000000, 0x4473961a00000000, + 0x85e3fa1a00000000, 0xc6524f1a00000000, 0x07c2231a00000000, + 0x48b6401800000000, 0x89262c1800000000, 0xca97991800000000, + 0x0b07f51800000000, 0x4cf5f21900000000, 0x8d659e1900000000, + 0xced42b1900000000, 0x0f44471900000000, 0x503ced1d00000000, + 0x91ac811d00000000, 0xd21d341d00000000, 0x138d581d00000000, + 0x547f5f1c00000000, 0x95ef331c00000000, 0xd65e861c00000000, + 0x17ceea1c00000000, 0x58ba891e00000000, 0x992ae51e00000000, + 0xda9b501e00000000, 0x1b0b3c1e00000000, 0x5cf93b1f00000000, + 0x9d69571f00000000, 0xded8e21f00000000, 0x1f488e1f00000000, + 0x6028b61600000000, 0xa1b8da1600000000, 0xe2096f1600000000, + 0x2399031600000000, 0x646b041700000000, 0xa5fb681700000000, + 0xe64add1700000000, 0x27dab11700000000, 0x68aed21500000000, + 0xa93ebe1500000000, 0xea8f0b1500000000, 0x2b1f671500000000, + 0x6ced601400000000, 0xad7d0c1400000000, 0xeeccb91400000000, + 0x2f5cd51400000000, 0x70247f1000000000, 0xb1b4131000000000, + 0xf205a61000000000, 0x3395ca1000000000, 0x7467cd1100000000, + 0xb5f7a11100000000, 0xf646141100000000, 0x37d6781100000000, + 0x78a21b1300000000, 0xb932771300000000, 0xfa83c21300000000, + 0x3b13ae1300000000, 0x7ce1a91200000000, 0xbd71c51200000000, + 0xfec0701200000000, 0x3f501c1200000000, 0x8060483600000000, + 0x41f0243600000000, 0x0241913600000000, 0xc3d1fd3600000000, + 0x8423fa3700000000, 0x45b3963700000000, 0x0602233700000000, + 0xc7924f3700000000, 0x88e62c3500000000, 0x4976403500000000, + 0x0ac7f53500000000, 0xcb57993500000000, 0x8ca59e3400000000, + 0x4d35f23400000000, 0x0e84473400000000, 0xcf142b3400000000, + 0x906c813000000000, 0x51fced3000000000, 0x124d583000000000, + 0xd3dd343000000000, 0x942f333100000000, 0x55bf5f3100000000, + 0x160eea3100000000, 0xd79e863100000000, 0x98eae53300000000, + 0x597a893300000000, 0x1acb3c3300000000, 0xdb5b503300000000, + 0x9ca9573200000000, 0x5d393b3200000000, 0x1e888e3200000000, + 0xdf18e23200000000, 0xa078da3b00000000, 0x61e8b63b00000000, + 0x2259033b00000000, 0xe3c96f3b00000000, 0xa43b683a00000000, + 0x65ab043a00000000, 0x261ab13a00000000, 0xe78add3a00000000, + 0xa8febe3800000000, 0x696ed23800000000, 0x2adf673800000000, + 0xeb4f0b3800000000, 0xacbd0c3900000000, 0x6d2d603900000000, + 0x2e9cd53900000000, 0xef0cb93900000000, 0xb074133d00000000, + 0x71e47f3d00000000, 0x3255ca3d00000000, 0xf3c5a63d00000000, + 0xb437a13c00000000, 0x75a7cd3c00000000, 0x3616783c00000000, + 0xf786143c00000000, 0xb8f2773e00000000, 0x79621b3e00000000, + 0x3ad3ae3e00000000, 0xfb43c23e00000000, 0xbcb1c53f00000000, + 0x7d21a93f00000000, 0x3e901c3f00000000, 0xff00703f00000000, + 0xc0506c2d00000000, 0x01c0002d00000000, 0x4271b52d00000000, + 0x83e1d92d00000000, 0xc413de2c00000000, 0x0583b22c00000000, + 0x4632072c00000000, 0x87a26b2c00000000, 0xc8d6082e00000000, + 0x0946642e00000000, 0x4af7d12e00000000, 0x8b67bd2e00000000, + 0xcc95ba2f00000000, 0x0d05d62f00000000, 0x4eb4632f00000000, + 0x8f240f2f00000000, 0xd05ca52b00000000, 0x11ccc92b00000000, + 0x527d7c2b00000000, 0x93ed102b00000000, 0xd41f172a00000000, + 0x158f7b2a00000000, 0x563ece2a00000000, 0x97aea22a00000000, + 0xd8dac12800000000, 0x194aad2800000000, 0x5afb182800000000, + 0x9b6b742800000000, 0xdc99732900000000, 0x1d091f2900000000, + 0x5eb8aa2900000000, 0x9f28c62900000000, 0xe048fe2000000000, + 0x21d8922000000000, 0x6269272000000000, 0xa3f94b2000000000, + 0xe40b4c2100000000, 0x259b202100000000, 0x662a952100000000, + 0xa7baf92100000000, 0xe8ce9a2300000000, 0x295ef62300000000, + 0x6aef432300000000, 0xab7f2f2300000000, 0xec8d282200000000, + 0x2d1d442200000000, 0x6eacf12200000000, 0xaf3c9d2200000000, + 0xf044372600000000, 0x31d45b2600000000, 0x7265ee2600000000, + 0xb3f5822600000000, 0xf407852700000000, 0x3597e92700000000, + 0x76265c2700000000, 0xb7b6302700000000, 0xf8c2532500000000, + 0x39523f2500000000, 0x7ae38a2500000000, 0xbb73e62500000000, + 0xfc81e12400000000, 0x3d118d2400000000, 0x7ea0382400000000, + 0xbf30542400000000}, + {0x0000000000000000, 0x91ad91fc00000000, 0x215b204900000000, + 0xb0f6b1b500000000, 0x42b6409200000000, 0xd31bd16e00000000, + 0x63ed60db00000000, 0xf240f12700000000, 0x876c829400000000, + 0x16c1136800000000, 0xa637a2dd00000000, 0x379a332100000000, + 0xc5dac20600000000, 0x547753fa00000000, 0xe481e24f00000000, + 0x752c73b300000000, 0x0dd9079900000000, 0x9c74966500000000, + 0x2c8227d000000000, 0xbd2fb62c00000000, 0x4f6f470b00000000, + 0xdec2d6f700000000, 0x6e34674200000000, 0xff99f6be00000000, + 0x8ab5850d00000000, 0x1b1814f100000000, 0xabeea54400000000, + 0x3a4334b800000000, 0xc803c59f00000000, 0x59ae546300000000, + 0xe958e5d600000000, 0x78f5742a00000000, 0x19b20c8200000000, + 0x881f9d7e00000000, 0x38e92ccb00000000, 0xa944bd3700000000, + 0x5b044c1000000000, 0xcaa9ddec00000000, 0x7a5f6c5900000000, + 0xebf2fda500000000, 0x9ede8e1600000000, 0x0f731fea00000000, + 0xbf85ae5f00000000, 0x2e283fa300000000, 0xdc68ce8400000000, + 0x4dc55f7800000000, 0xfd33eecd00000000, 0x6c9e7f3100000000, + 0x146b0b1b00000000, 0x85c69ae700000000, 0x35302b5200000000, + 0xa49dbaae00000000, 0x56dd4b8900000000, 0xc770da7500000000, + 0x77866bc000000000, 0xe62bfa3c00000000, 0x9307898f00000000, + 0x02aa187300000000, 0xb25ca9c600000000, 0x23f1383a00000000, + 0xd1b1c91d00000000, 0x401c58e100000000, 0xf0eae95400000000, + 0x614778a800000000, 0x31641ab400000000, 0xa0c98b4800000000, + 0x103f3afd00000000, 0x8192ab0100000000, 0x73d25a2600000000, + 0xe27fcbda00000000, 0x52897a6f00000000, 0xc324eb9300000000, + 0xb608982000000000, 0x27a509dc00000000, 0x9753b86900000000, + 0x06fe299500000000, 0xf4bed8b200000000, 0x6513494e00000000, + 0xd5e5f8fb00000000, 0x4448690700000000, 0x3cbd1d2d00000000, + 0xad108cd100000000, 0x1de63d6400000000, 0x8c4bac9800000000, + 0x7e0b5dbf00000000, 0xefa6cc4300000000, 0x5f507df600000000, + 0xcefdec0a00000000, 0xbbd19fb900000000, 0x2a7c0e4500000000, + 0x9a8abff000000000, 0x0b272e0c00000000, 0xf967df2b00000000, + 0x68ca4ed700000000, 0xd83cff6200000000, 0x49916e9e00000000, + 0x28d6163600000000, 0xb97b87ca00000000, 0x098d367f00000000, + 0x9820a78300000000, 0x6a6056a400000000, 0xfbcdc75800000000, + 0x4b3b76ed00000000, 0xda96e71100000000, 0xafba94a200000000, + 0x3e17055e00000000, 0x8ee1b4eb00000000, 0x1f4c251700000000, + 0xed0cd43000000000, 0x7ca145cc00000000, 0xcc57f47900000000, + 0x5dfa658500000000, 0x250f11af00000000, 0xb4a2805300000000, + 0x045431e600000000, 0x95f9a01a00000000, 0x67b9513d00000000, + 0xf614c0c100000000, 0x46e2717400000000, 0xd74fe08800000000, + 0xa263933b00000000, 0x33ce02c700000000, 0x8338b37200000000, + 0x1295228e00000000, 0xe0d5d3a900000000, 0x7178425500000000, + 0xc18ef3e000000000, 0x5023621c00000000, 0x61c837d800000000, + 0xf065a62400000000, 0x4093179100000000, 0xd13e866d00000000, + 0x237e774a00000000, 0xb2d3e6b600000000, 0x0225570300000000, + 0x9388c6ff00000000, 0xe6a4b54c00000000, 0x770924b000000000, + 0xc7ff950500000000, 0x565204f900000000, 0xa412f5de00000000, + 0x35bf642200000000, 0x8549d59700000000, 0x14e4446b00000000, + 0x6c11304100000000, 0xfdbca1bd00000000, 0x4d4a100800000000, + 0xdce781f400000000, 0x2ea770d300000000, 0xbf0ae12f00000000, + 0x0ffc509a00000000, 0x9e51c16600000000, 0xeb7db2d500000000, + 0x7ad0232900000000, 0xca26929c00000000, 0x5b8b036000000000, + 0xa9cbf24700000000, 0x386663bb00000000, 0x8890d20e00000000, + 0x193d43f200000000, 0x787a3b5a00000000, 0xe9d7aaa600000000, + 0x59211b1300000000, 0xc88c8aef00000000, 0x3acc7bc800000000, + 0xab61ea3400000000, 0x1b975b8100000000, 0x8a3aca7d00000000, + 0xff16b9ce00000000, 0x6ebb283200000000, 0xde4d998700000000, + 0x4fe0087b00000000, 0xbda0f95c00000000, 0x2c0d68a000000000, + 0x9cfbd91500000000, 0x0d5648e900000000, 0x75a33cc300000000, + 0xe40ead3f00000000, 0x54f81c8a00000000, 0xc5558d7600000000, + 0x37157c5100000000, 0xa6b8edad00000000, 0x164e5c1800000000, + 0x87e3cde400000000, 0xf2cfbe5700000000, 0x63622fab00000000, + 0xd3949e1e00000000, 0x42390fe200000000, 0xb079fec500000000, + 0x21d46f3900000000, 0x9122de8c00000000, 0x008f4f7000000000, + 0x50ac2d6c00000000, 0xc101bc9000000000, 0x71f70d2500000000, + 0xe05a9cd900000000, 0x121a6dfe00000000, 0x83b7fc0200000000, + 0x33414db700000000, 0xa2ecdc4b00000000, 0xd7c0aff800000000, + 0x466d3e0400000000, 0xf69b8fb100000000, 0x67361e4d00000000, + 0x9576ef6a00000000, 0x04db7e9600000000, 0xb42dcf2300000000, + 0x25805edf00000000, 0x5d752af500000000, 0xccd8bb0900000000, + 0x7c2e0abc00000000, 0xed839b4000000000, 0x1fc36a6700000000, + 0x8e6efb9b00000000, 0x3e984a2e00000000, 0xaf35dbd200000000, + 0xda19a86100000000, 0x4bb4399d00000000, 0xfb42882800000000, + 0x6aef19d400000000, 0x98afe8f300000000, 0x0902790f00000000, + 0xb9f4c8ba00000000, 0x2859594600000000, 0x491e21ee00000000, + 0xd8b3b01200000000, 0x684501a700000000, 0xf9e8905b00000000, + 0x0ba8617c00000000, 0x9a05f08000000000, 0x2af3413500000000, + 0xbb5ed0c900000000, 0xce72a37a00000000, 0x5fdf328600000000, + 0xef29833300000000, 0x7e8412cf00000000, 0x8cc4e3e800000000, + 0x1d69721400000000, 0xad9fc3a100000000, 0x3c32525d00000000, + 0x44c7267700000000, 0xd56ab78b00000000, 0x659c063e00000000, + 0xf43197c200000000, 0x067166e500000000, 0x97dcf71900000000, + 0x272a46ac00000000, 0xb687d75000000000, 0xc3aba4e300000000, + 0x5206351f00000000, 0xe2f084aa00000000, 0x735d155600000000, + 0x811de47100000000, 0x10b0758d00000000, 0xa046c43800000000, + 0x31eb55c400000000}, + {0x0000000000000000, 0xac006dd100000000, 0x5b01d91200000000, + 0xf701b4c300000000, 0xb602b22500000000, 0x1a02dff400000000, + 0xed036b3700000000, 0x410306e600000000, 0x6c05644b00000000, + 0xc005099a00000000, 0x3704bd5900000000, 0x9b04d08800000000, + 0xda07d66e00000000, 0x7607bbbf00000000, 0x81060f7c00000000, + 0x2d0662ad00000000, 0xd80ac89600000000, 0x740aa54700000000, + 0x830b118400000000, 0x2f0b7c5500000000, 0x6e087ab300000000, + 0xc208176200000000, 0x3509a3a100000000, 0x9909ce7000000000, + 0xb40facdd00000000, 0x180fc10c00000000, 0xef0e75cf00000000, + 0x430e181e00000000, 0x020d1ef800000000, 0xae0d732900000000, + 0x590cc7ea00000000, 0xf50caa3b00000000, 0xb315939d00000000, + 0x1f15fe4c00000000, 0xe8144a8f00000000, 0x4414275e00000000, + 0x051721b800000000, 0xa9174c6900000000, 0x5e16f8aa00000000, + 0xf216957b00000000, 0xdf10f7d600000000, 0x73109a0700000000, + 0x84112ec400000000, 0x2811431500000000, 0x691245f300000000, + 0xc512282200000000, 0x32139ce100000000, 0x9e13f13000000000, + 0x6b1f5b0b00000000, 0xc71f36da00000000, 0x301e821900000000, + 0x9c1eefc800000000, 0xdd1de92e00000000, 0x711d84ff00000000, + 0x861c303c00000000, 0x2a1c5ded00000000, 0x071a3f4000000000, + 0xab1a529100000000, 0x5c1be65200000000, 0xf01b8b8300000000, + 0xb1188d6500000000, 0x1d18e0b400000000, 0xea19547700000000, + 0x461939a600000000, 0x652b258b00000000, 0xc92b485a00000000, + 0x3e2afc9900000000, 0x922a914800000000, 0xd32997ae00000000, + 0x7f29fa7f00000000, 0x88284ebc00000000, 0x2428236d00000000, + 0x092e41c000000000, 0xa52e2c1100000000, 0x522f98d200000000, + 0xfe2ff50300000000, 0xbf2cf3e500000000, 0x132c9e3400000000, + 0xe42d2af700000000, 0x482d472600000000, 0xbd21ed1d00000000, + 0x112180cc00000000, 0xe620340f00000000, 0x4a2059de00000000, + 0x0b235f3800000000, 0xa72332e900000000, 0x5022862a00000000, + 0xfc22ebfb00000000, 0xd124895600000000, 0x7d24e48700000000, + 0x8a25504400000000, 0x26253d9500000000, 0x67263b7300000000, + 0xcb2656a200000000, 0x3c27e26100000000, 0x90278fb000000000, + 0xd63eb61600000000, 0x7a3edbc700000000, 0x8d3f6f0400000000, + 0x213f02d500000000, 0x603c043300000000, 0xcc3c69e200000000, + 0x3b3ddd2100000000, 0x973db0f000000000, 0xba3bd25d00000000, + 0x163bbf8c00000000, 0xe13a0b4f00000000, 0x4d3a669e00000000, + 0x0c39607800000000, 0xa0390da900000000, 0x5738b96a00000000, + 0xfb38d4bb00000000, 0x0e347e8000000000, 0xa234135100000000, + 0x5535a79200000000, 0xf935ca4300000000, 0xb836cca500000000, + 0x1436a17400000000, 0xe33715b700000000, 0x4f37786600000000, + 0x62311acb00000000, 0xce31771a00000000, 0x3930c3d900000000, + 0x9530ae0800000000, 0xd433a8ee00000000, 0x7833c53f00000000, + 0x8f3271fc00000000, 0x23321c2d00000000, 0xc95649a600000000, + 0x6556247700000000, 0x925790b400000000, 0x3e57fd6500000000, + 0x7f54fb8300000000, 0xd354965200000000, 0x2455229100000000, + 0x88554f4000000000, 0xa5532ded00000000, 0x0953403c00000000, + 0xfe52f4ff00000000, 0x5252992e00000000, 0x13519fc800000000, + 0xbf51f21900000000, 0x485046da00000000, 0xe4502b0b00000000, + 0x115c813000000000, 0xbd5cece100000000, 0x4a5d582200000000, + 0xe65d35f300000000, 0xa75e331500000000, 0x0b5e5ec400000000, + 0xfc5fea0700000000, 0x505f87d600000000, 0x7d59e57b00000000, + 0xd15988aa00000000, 0x26583c6900000000, 0x8a5851b800000000, + 0xcb5b575e00000000, 0x675b3a8f00000000, 0x905a8e4c00000000, + 0x3c5ae39d00000000, 0x7a43da3b00000000, 0xd643b7ea00000000, + 0x2142032900000000, 0x8d426ef800000000, 0xcc41681e00000000, + 0x604105cf00000000, 0x9740b10c00000000, 0x3b40dcdd00000000, + 0x1646be7000000000, 0xba46d3a100000000, 0x4d47676200000000, + 0xe1470ab300000000, 0xa0440c5500000000, 0x0c44618400000000, + 0xfb45d54700000000, 0x5745b89600000000, 0xa24912ad00000000, + 0x0e497f7c00000000, 0xf948cbbf00000000, 0x5548a66e00000000, + 0x144ba08800000000, 0xb84bcd5900000000, 0x4f4a799a00000000, + 0xe34a144b00000000, 0xce4c76e600000000, 0x624c1b3700000000, + 0x954daff400000000, 0x394dc22500000000, 0x784ec4c300000000, + 0xd44ea91200000000, 0x234f1dd100000000, 0x8f4f700000000000, + 0xac7d6c2d00000000, 0x007d01fc00000000, 0xf77cb53f00000000, + 0x5b7cd8ee00000000, 0x1a7fde0800000000, 0xb67fb3d900000000, + 0x417e071a00000000, 0xed7e6acb00000000, 0xc078086600000000, + 0x6c7865b700000000, 0x9b79d17400000000, 0x3779bca500000000, + 0x767aba4300000000, 0xda7ad79200000000, 0x2d7b635100000000, + 0x817b0e8000000000, 0x7477a4bb00000000, 0xd877c96a00000000, + 0x2f767da900000000, 0x8376107800000000, 0xc275169e00000000, + 0x6e757b4f00000000, 0x9974cf8c00000000, 0x3574a25d00000000, + 0x1872c0f000000000, 0xb472ad2100000000, 0x437319e200000000, + 0xef73743300000000, 0xae7072d500000000, 0x02701f0400000000, + 0xf571abc700000000, 0x5971c61600000000, 0x1f68ffb000000000, + 0xb368926100000000, 0x446926a200000000, 0xe8694b7300000000, + 0xa96a4d9500000000, 0x056a204400000000, 0xf26b948700000000, + 0x5e6bf95600000000, 0x736d9bfb00000000, 0xdf6df62a00000000, + 0x286c42e900000000, 0x846c2f3800000000, 0xc56f29de00000000, + 0x696f440f00000000, 0x9e6ef0cc00000000, 0x326e9d1d00000000, + 0xc762372600000000, 0x6b625af700000000, 0x9c63ee3400000000, + 0x306383e500000000, 0x7160850300000000, 0xdd60e8d200000000, + 0x2a615c1100000000, 0x866131c000000000, 0xab67536d00000000, + 0x07673ebc00000000, 0xf0668a7f00000000, 0x5c66e7ae00000000, + 0x1d65e14800000000, 0xb1658c9900000000, 0x4664385a00000000, + 0xea64558b00000000}, + {0x0000000000000000, 0x00c1115c00000000, 0x008223b800000000, + 0x004332e400000000, 0x030444c000000000, 0x03c5559c00000000, + 0x0386677800000000, 0x0347762400000000, 0x05088b3000000000, + 0x05c99a6c00000000, 0x058aa88800000000, 0x054bb9d400000000, + 0x060ccff000000000, 0x06cddeac00000000, 0x068eec4800000000, + 0x064ffd1400000000, 0x0a10166100000000, 0x0ad1073d00000000, + 0x0a9235d900000000, 0x0a53248500000000, 0x091452a100000000, + 0x09d543fd00000000, 0x0996711900000000, 0x0957604500000000, + 0x0f189d5100000000, 0x0fd98c0d00000000, 0x0f9abee900000000, + 0x0f5bafb500000000, 0x0c1cd99100000000, 0x0cddc8cd00000000, + 0x0c9efa2900000000, 0x0c5feb7500000000, 0x14202cc200000000, + 0x14e13d9e00000000, 0x14a20f7a00000000, 0x14631e2600000000, + 0x1724680200000000, 0x17e5795e00000000, 0x17a64bba00000000, + 0x17675ae600000000, 0x1128a7f200000000, 0x11e9b6ae00000000, + 0x11aa844a00000000, 0x116b951600000000, 0x122ce33200000000, + 0x12edf26e00000000, 0x12aec08a00000000, 0x126fd1d600000000, + 0x1e303aa300000000, 0x1ef12bff00000000, 0x1eb2191b00000000, + 0x1e73084700000000, 0x1d347e6300000000, 0x1df56f3f00000000, + 0x1db65ddb00000000, 0x1d774c8700000000, 0x1b38b19300000000, + 0x1bf9a0cf00000000, 0x1bba922b00000000, 0x1b7b837700000000, + 0x183cf55300000000, 0x18fde40f00000000, 0x18bed6eb00000000, + 0x187fc7b700000000, 0x2b405b3400000000, 0x2b814a6800000000, + 0x2bc2788c00000000, 0x2b0369d000000000, 0x28441ff400000000, + 0x28850ea800000000, 0x28c63c4c00000000, 0x28072d1000000000, + 0x2e48d00400000000, 0x2e89c15800000000, 0x2ecaf3bc00000000, + 0x2e0be2e000000000, 0x2d4c94c400000000, 0x2d8d859800000000, + 0x2dceb77c00000000, 0x2d0fa62000000000, 0x21504d5500000000, + 0x21915c0900000000, 0x21d26eed00000000, 0x21137fb100000000, + 0x2254099500000000, 0x229518c900000000, 0x22d62a2d00000000, + 0x22173b7100000000, 0x2458c66500000000, 0x2499d73900000000, + 0x24dae5dd00000000, 0x241bf48100000000, 0x275c82a500000000, + 0x279d93f900000000, 0x27dea11d00000000, 0x271fb04100000000, + 0x3f6077f600000000, 0x3fa166aa00000000, 0x3fe2544e00000000, + 0x3f23451200000000, 0x3c64333600000000, 0x3ca5226a00000000, + 0x3ce6108e00000000, 0x3c2701d200000000, 0x3a68fcc600000000, + 0x3aa9ed9a00000000, 0x3aeadf7e00000000, 0x3a2bce2200000000, + 0x396cb80600000000, 0x39ada95a00000000, 0x39ee9bbe00000000, + 0x392f8ae200000000, 0x3570619700000000, 0x35b170cb00000000, + 0x35f2422f00000000, 0x3533537300000000, 0x3674255700000000, + 0x36b5340b00000000, 0x36f606ef00000000, 0x363717b300000000, + 0x3078eaa700000000, 0x30b9fbfb00000000, 0x30fac91f00000000, + 0x303bd84300000000, 0x337cae6700000000, 0x33bdbf3b00000000, + 0x33fe8ddf00000000, 0x333f9c8300000000, 0x5680b66800000000, + 0x5641a73400000000, 0x560295d000000000, 0x56c3848c00000000, + 0x5584f2a800000000, 0x5545e3f400000000, 0x5506d11000000000, + 0x55c7c04c00000000, 0x53883d5800000000, 0x53492c0400000000, + 0x530a1ee000000000, 0x53cb0fbc00000000, 0x508c799800000000, + 0x504d68c400000000, 0x500e5a2000000000, 0x50cf4b7c00000000, + 0x5c90a00900000000, 0x5c51b15500000000, 0x5c1283b100000000, + 0x5cd392ed00000000, 0x5f94e4c900000000, 0x5f55f59500000000, + 0x5f16c77100000000, 0x5fd7d62d00000000, 0x59982b3900000000, + 0x59593a6500000000, 0x591a088100000000, 0x59db19dd00000000, + 0x5a9c6ff900000000, 0x5a5d7ea500000000, 0x5a1e4c4100000000, + 0x5adf5d1d00000000, 0x42a09aaa00000000, 0x42618bf600000000, + 0x4222b91200000000, 0x42e3a84e00000000, 0x41a4de6a00000000, + 0x4165cf3600000000, 0x4126fdd200000000, 0x41e7ec8e00000000, + 0x47a8119a00000000, 0x476900c600000000, 0x472a322200000000, + 0x47eb237e00000000, 0x44ac555a00000000, 0x446d440600000000, + 0x442e76e200000000, 0x44ef67be00000000, 0x48b08ccb00000000, + 0x48719d9700000000, 0x4832af7300000000, 0x48f3be2f00000000, + 0x4bb4c80b00000000, 0x4b75d95700000000, 0x4b36ebb300000000, + 0x4bf7faef00000000, 0x4db807fb00000000, 0x4d7916a700000000, + 0x4d3a244300000000, 0x4dfb351f00000000, 0x4ebc433b00000000, + 0x4e7d526700000000, 0x4e3e608300000000, 0x4eff71df00000000, + 0x7dc0ed5c00000000, 0x7d01fc0000000000, 0x7d42cee400000000, + 0x7d83dfb800000000, 0x7ec4a99c00000000, 0x7e05b8c000000000, + 0x7e468a2400000000, 0x7e879b7800000000, 0x78c8666c00000000, + 0x7809773000000000, 0x784a45d400000000, 0x788b548800000000, + 0x7bcc22ac00000000, 0x7b0d33f000000000, 0x7b4e011400000000, + 0x7b8f104800000000, 0x77d0fb3d00000000, 0x7711ea6100000000, + 0x7752d88500000000, 0x7793c9d900000000, 0x74d4bffd00000000, + 0x7415aea100000000, 0x74569c4500000000, 0x74978d1900000000, + 0x72d8700d00000000, 0x7219615100000000, 0x725a53b500000000, + 0x729b42e900000000, 0x71dc34cd00000000, 0x711d259100000000, + 0x715e177500000000, 0x719f062900000000, 0x69e0c19e00000000, + 0x6921d0c200000000, 0x6962e22600000000, 0x69a3f37a00000000, + 0x6ae4855e00000000, 0x6a25940200000000, 0x6a66a6e600000000, + 0x6aa7b7ba00000000, 0x6ce84aae00000000, 0x6c295bf200000000, + 0x6c6a691600000000, 0x6cab784a00000000, 0x6fec0e6e00000000, + 0x6f2d1f3200000000, 0x6f6e2dd600000000, 0x6faf3c8a00000000, + 0x63f0d7ff00000000, 0x6331c6a300000000, 0x6372f44700000000, + 0x63b3e51b00000000, 0x60f4933f00000000, 0x6035826300000000, + 0x6076b08700000000, 0x60b7a1db00000000, 0x66f85ccf00000000, + 0x66394d9300000000, 0x667a7f7700000000, 0x66bb6e2b00000000, + 0x65fc180f00000000, 0x653d095300000000, 0x657e3bb700000000, + 0x65bf2aeb00000000}, + {0x0000000000000000, 0xc1115c0000000000, 0x8223b80000000000, + 0x4332e40000000000, 0x0447700100000000, 0xc5562c0100000000, + 0x8664c80100000000, 0x4775940100000000, 0x088ee00200000000, + 0xc99fbc0200000000, 0x8aad580200000000, 0x4bbc040200000000, + 0x0cc9900300000000, 0xcdd8cc0300000000, 0x8eea280300000000, + 0x4ffb740300000000, 0x101cc10500000000, 0xd10d9d0500000000, + 0x923f790500000000, 0x532e250500000000, 0x145bb10400000000, + 0xd54aed0400000000, 0x9678090400000000, 0x5769550400000000, + 0x1892210700000000, 0xd9837d0700000000, 0x9ab1990700000000, + 0x5ba0c50700000000, 0x1cd5510600000000, 0xddc40d0600000000, + 0x9ef6e90600000000, 0x5fe7b50600000000, 0x2038820b00000000, + 0xe129de0b00000000, 0xa21b3a0b00000000, 0x630a660b00000000, + 0x247ff20a00000000, 0xe56eae0a00000000, 0xa65c4a0a00000000, + 0x674d160a00000000, 0x28b6620900000000, 0xe9a73e0900000000, + 0xaa95da0900000000, 0x6b84860900000000, 0x2cf1120800000000, + 0xede04e0800000000, 0xaed2aa0800000000, 0x6fc3f60800000000, + 0x3024430e00000000, 0xf1351f0e00000000, 0xb207fb0e00000000, + 0x7316a70e00000000, 0x3463330f00000000, 0xf5726f0f00000000, + 0xb6408b0f00000000, 0x7751d70f00000000, 0x38aaa30c00000000, + 0xf9bbff0c00000000, 0xba891b0c00000000, 0x7b98470c00000000, + 0x3cedd30d00000000, 0xfdfc8f0d00000000, 0xbece6b0d00000000, + 0x7fdf370d00000000, 0x4070041700000000, 0x8161581700000000, + 0xc253bc1700000000, 0x0342e01700000000, 0x4437741600000000, + 0x8526281600000000, 0xc614cc1600000000, 0x0705901600000000, + 0x48fee41500000000, 0x89efb81500000000, 0xcadd5c1500000000, + 0x0bcc001500000000, 0x4cb9941400000000, 0x8da8c81400000000, + 0xce9a2c1400000000, 0x0f8b701400000000, 0x506cc51200000000, + 0x917d991200000000, 0xd24f7d1200000000, 0x135e211200000000, + 0x542bb51300000000, 0x953ae91300000000, 0xd6080d1300000000, + 0x1719511300000000, 0x58e2251000000000, 0x99f3791000000000, + 0xdac19d1000000000, 0x1bd0c11000000000, 0x5ca5551100000000, + 0x9db4091100000000, 0xde86ed1100000000, 0x1f97b11100000000, + 0x6048861c00000000, 0xa159da1c00000000, 0xe26b3e1c00000000, + 0x237a621c00000000, 0x640ff61d00000000, 0xa51eaa1d00000000, + 0xe62c4e1d00000000, 0x273d121d00000000, 0x68c6661e00000000, + 0xa9d73a1e00000000, 0xeae5de1e00000000, 0x2bf4821e00000000, + 0x6c81161f00000000, 0xad904a1f00000000, 0xeea2ae1f00000000, + 0x2fb3f21f00000000, 0x7054471900000000, 0xb1451b1900000000, + 0xf277ff1900000000, 0x3366a31900000000, 0x7413371800000000, + 0xb5026b1800000000, 0xf6308f1800000000, 0x3721d31800000000, + 0x78daa71b00000000, 0xb9cbfb1b00000000, 0xfaf91f1b00000000, + 0x3be8431b00000000, 0x7c9dd71a00000000, 0xbd8c8b1a00000000, + 0xfebe6f1a00000000, 0x3faf331a00000000, 0x80e0082e00000000, + 0x41f1542e00000000, 0x02c3b02e00000000, 0xc3d2ec2e00000000, + 0x84a7782f00000000, 0x45b6242f00000000, 0x0684c02f00000000, + 0xc7959c2f00000000, 0x886ee82c00000000, 0x497fb42c00000000, + 0x0a4d502c00000000, 0xcb5c0c2c00000000, 0x8c29982d00000000, + 0x4d38c42d00000000, 0x0e0a202d00000000, 0xcf1b7c2d00000000, + 0x90fcc92b00000000, 0x51ed952b00000000, 0x12df712b00000000, + 0xd3ce2d2b00000000, 0x94bbb92a00000000, 0x55aae52a00000000, + 0x1698012a00000000, 0xd7895d2a00000000, 0x9872292900000000, + 0x5963752900000000, 0x1a51912900000000, 0xdb40cd2900000000, + 0x9c35592800000000, 0x5d24052800000000, 0x1e16e12800000000, + 0xdf07bd2800000000, 0xa0d88a2500000000, 0x61c9d62500000000, + 0x22fb322500000000, 0xe3ea6e2500000000, 0xa49ffa2400000000, + 0x658ea62400000000, 0x26bc422400000000, 0xe7ad1e2400000000, + 0xa8566a2700000000, 0x6947362700000000, 0x2a75d22700000000, + 0xeb648e2700000000, 0xac111a2600000000, 0x6d00462600000000, + 0x2e32a22600000000, 0xef23fe2600000000, 0xb0c44b2000000000, + 0x71d5172000000000, 0x32e7f32000000000, 0xf3f6af2000000000, + 0xb4833b2100000000, 0x7592672100000000, 0x36a0832100000000, + 0xf7b1df2100000000, 0xb84aab2200000000, 0x795bf72200000000, + 0x3a69132200000000, 0xfb784f2200000000, 0xbc0ddb2300000000, + 0x7d1c872300000000, 0x3e2e632300000000, 0xff3f3f2300000000, + 0xc0900c3900000000, 0x0181503900000000, 0x42b3b43900000000, + 0x83a2e83900000000, 0xc4d77c3800000000, 0x05c6203800000000, + 0x46f4c43800000000, 0x87e5983800000000, 0xc81eec3b00000000, + 0x090fb03b00000000, 0x4a3d543b00000000, 0x8b2c083b00000000, + 0xcc599c3a00000000, 0x0d48c03a00000000, 0x4e7a243a00000000, + 0x8f6b783a00000000, 0xd08ccd3c00000000, 0x119d913c00000000, + 0x52af753c00000000, 0x93be293c00000000, 0xd4cbbd3d00000000, + 0x15dae13d00000000, 0x56e8053d00000000, 0x97f9593d00000000, + 0xd8022d3e00000000, 0x1913713e00000000, 0x5a21953e00000000, + 0x9b30c93e00000000, 0xdc455d3f00000000, 0x1d54013f00000000, + 0x5e66e53f00000000, 0x9f77b93f00000000, 0xe0a88e3200000000, + 0x21b9d23200000000, 0x628b363200000000, 0xa39a6a3200000000, + 0xe4effe3300000000, 0x25fea23300000000, 0x66cc463300000000, + 0xa7dd1a3300000000, 0xe8266e3000000000, 0x2937323000000000, + 0x6a05d63000000000, 0xab148a3000000000, 0xec611e3100000000, + 0x2d70423100000000, 0x6e42a63100000000, 0xaf53fa3100000000, + 0xf0b44f3700000000, 0x31a5133700000000, 0x7297f73700000000, + 0xb386ab3700000000, 0xf4f33f3600000000, 0x35e2633600000000, + 0x76d0873600000000, 0xb7c1db3600000000, 0xf83aaf3500000000, + 0x392bf33500000000, 0x7a19173500000000, 0xbb084b3500000000, + 0xfc7ddf3400000000, 0x3d6c833400000000, 0x7e5e673400000000, + 0xbf4f3b3400000000}, + {0x0000000000000000, 0x109d91fc00000000, 0x233a204900000000, + 0x33a7b1b500000000, 0x4674409200000000, 0x56e9d16e00000000, + 0x654e60db00000000, 0x75d3f12700000000, 0x8fe8839400000000, + 0x9f75126800000000, 0xacd2a3dd00000000, 0xbc4f322100000000, + 0xc99cc30600000000, 0xd90152fa00000000, 0xeaa6e34f00000000, + 0xfa3b72b300000000, 0x1dd1049900000000, 0x0d4c956500000000, + 0x3eeb24d000000000, 0x2e76b52c00000000, 0x5ba5440b00000000, + 0x4b38d5f700000000, 0x789f644200000000, 0x6802f5be00000000, + 0x9239870d00000000, 0x82a416f100000000, 0xb103a74400000000, + 0xa19e36b800000000, 0xd44dc79f00000000, 0xc4d0566300000000, + 0xf777e7d600000000, 0xe7ea762a00000000, 0x39a20a8200000000, + 0x293f9b7e00000000, 0x1a982acb00000000, 0x0a05bb3700000000, + 0x7fd64a1000000000, 0x6f4bdbec00000000, 0x5cec6a5900000000, + 0x4c71fba500000000, 0xb64a891600000000, 0xa6d718ea00000000, + 0x9570a95f00000000, 0x85ed38a300000000, 0xf03ec98400000000, + 0xe0a3587800000000, 0xd304e9cd00000000, 0xc399783100000000, + 0x24730e1b00000000, 0x34ee9fe700000000, 0x07492e5200000000, + 0x17d4bfae00000000, 0x62074e8900000000, 0x729adf7500000000, + 0x413d6ec000000000, 0x51a0ff3c00000000, 0xab9b8d8f00000000, + 0xbb061c7300000000, 0x88a1adc600000000, 0x983c3c3a00000000, + 0xedefcd1d00000000, 0xfd725ce100000000, 0xced5ed5400000000, + 0xde487ca800000000, 0x714416b400000000, 0x61d9874800000000, + 0x527e36fd00000000, 0x42e3a70100000000, 0x3730562600000000, + 0x27adc7da00000000, 0x140a766f00000000, 0x0497e79300000000, + 0xfeac952000000000, 0xee3104dc00000000, 0xdd96b56900000000, + 0xcd0b249500000000, 0xb8d8d5b200000000, 0xa845444e00000000, + 0x9be2f5fb00000000, 0x8b7f640700000000, 0x6c95122d00000000, + 0x7c0883d100000000, 0x4faf326400000000, 0x5f32a39800000000, + 0x2ae152bf00000000, 0x3a7cc34300000000, 0x09db72f600000000, + 0x1946e30a00000000, 0xe37d91b900000000, 0xf3e0004500000000, + 0xc047b1f000000000, 0xd0da200c00000000, 0xa509d12b00000000, + 0xb59440d700000000, 0x8633f16200000000, 0x96ae609e00000000, + 0x48e61c3600000000, 0x587b8dca00000000, 0x6bdc3c7f00000000, + 0x7b41ad8300000000, 0x0e925ca400000000, 0x1e0fcd5800000000, + 0x2da87ced00000000, 0x3d35ed1100000000, 0xc70e9fa200000000, + 0xd7930e5e00000000, 0xe434bfeb00000000, 0xf4a92e1700000000, + 0x817adf3000000000, 0x91e74ecc00000000, 0xa240ff7900000000, + 0xb2dd6e8500000000, 0x553718af00000000, 0x45aa895300000000, + 0x760d38e600000000, 0x6690a91a00000000, 0x1343583d00000000, + 0x03dec9c100000000, 0x3079787400000000, 0x20e4e98800000000, + 0xdadf9b3b00000000, 0xca420ac700000000, 0xf9e5bb7200000000, + 0xe9782a8e00000000, 0x9cabdba900000000, 0x8c364a5500000000, + 0xbf91fbe000000000, 0xaf0c6a1c00000000, 0xe1882fd800000000, + 0xf115be2400000000, 0xc2b20f9100000000, 0xd22f9e6d00000000, + 0xa7fc6f4a00000000, 0xb761feb600000000, 0x84c64f0300000000, + 0x945bdeff00000000, 0x6e60ac4c00000000, 0x7efd3db000000000, + 0x4d5a8c0500000000, 0x5dc71df900000000, 0x2814ecde00000000, + 0x38897d2200000000, 0x0b2ecc9700000000, 0x1bb35d6b00000000, + 0xfc592b4100000000, 0xecc4babd00000000, 0xdf630b0800000000, + 0xcffe9af400000000, 0xba2d6bd300000000, 0xaab0fa2f00000000, + 0x99174b9a00000000, 0x898ada6600000000, 0x73b1a8d500000000, + 0x632c392900000000, 0x508b889c00000000, 0x4016196000000000, + 0x35c5e84700000000, 0x255879bb00000000, 0x16ffc80e00000000, + 0x066259f200000000, 0xd82a255a00000000, 0xc8b7b4a600000000, + 0xfb10051300000000, 0xeb8d94ef00000000, 0x9e5e65c800000000, + 0x8ec3f43400000000, 0xbd64458100000000, 0xadf9d47d00000000, + 0x57c2a6ce00000000, 0x475f373200000000, 0x74f8868700000000, + 0x6465177b00000000, 0x11b6e65c00000000, 0x012b77a000000000, + 0x328cc61500000000, 0x221157e900000000, 0xc5fb21c300000000, + 0xd566b03f00000000, 0xe6c1018a00000000, 0xf65c907600000000, + 0x838f615100000000, 0x9312f0ad00000000, 0xa0b5411800000000, + 0xb028d0e400000000, 0x4a13a25700000000, 0x5a8e33ab00000000, + 0x6929821e00000000, 0x79b413e200000000, 0x0c67e2c500000000, + 0x1cfa733900000000, 0x2f5dc28c00000000, 0x3fc0537000000000, + 0x90cc396c00000000, 0x8051a89000000000, 0xb3f6192500000000, + 0xa36b88d900000000, 0xd6b879fe00000000, 0xc625e80200000000, + 0xf58259b700000000, 0xe51fc84b00000000, 0x1f24baf800000000, + 0x0fb92b0400000000, 0x3c1e9ab100000000, 0x2c830b4d00000000, + 0x5950fa6a00000000, 0x49cd6b9600000000, 0x7a6ada2300000000, + 0x6af74bdf00000000, 0x8d1d3df500000000, 0x9d80ac0900000000, + 0xae271dbc00000000, 0xbeba8c4000000000, 0xcb697d6700000000, + 0xdbf4ec9b00000000, 0xe8535d2e00000000, 0xf8ceccd200000000, + 0x02f5be6100000000, 0x12682f9d00000000, 0x21cf9e2800000000, + 0x31520fd400000000, 0x4481fef300000000, 0x541c6f0f00000000, + 0x67bbdeba00000000, 0x77264f4600000000, 0xa96e33ee00000000, + 0xb9f3a21200000000, 0x8a5413a700000000, 0x9ac9825b00000000, + 0xef1a737c00000000, 0xff87e28000000000, 0xcc20533500000000, + 0xdcbdc2c900000000, 0x2686b07a00000000, 0x361b218600000000, + 0x05bc903300000000, 0x152101cf00000000, 0x60f2f0e800000000, + 0x706f611400000000, 0x43c8d0a100000000, 0x5355415d00000000, + 0xb4bf377700000000, 0xa422a68b00000000, 0x9785173e00000000, + 0x871886c200000000, 0xf2cb77e500000000, 0xe256e61900000000, + 0xd1f157ac00000000, 0xc16cc65000000000, 0x3b57b4e300000000, + 0x2bca251f00000000, 0x186d94aa00000000, 0x08f0055600000000, + 0x7d23f47100000000, 0x6dbe658d00000000, 0x5e19d43800000000, + 0x4e8445c400000000}, + {0x0000000000000000, 0x9c81fd9900000000, 0x3b03f88300000000, + 0xa782051a00000000, 0x7506f3b700000000, 0xe9870e2e00000000, + 0x4e050b3400000000, 0xd284f6ad00000000, 0xe90ce5df00000000, + 0x758d184600000000, 0xd20f1d5c00000000, 0x4e8ee0c500000000, + 0x9c0a166800000000, 0x008bebf100000000, 0xa709eeeb00000000, + 0x3b88137200000000, 0xd119c90f00000000, 0x4d98349600000000, + 0xea1a318c00000000, 0x769bcc1500000000, 0xa41f3ab800000000, + 0x389ec72100000000, 0x9f1cc23b00000000, 0x039d3fa200000000, + 0x38152cd000000000, 0xa494d14900000000, 0x0316d45300000000, + 0x9f9729ca00000000, 0x4d13df6700000000, 0xd19222fe00000000, + 0x761027e400000000, 0xea91da7d00000000, 0xa233921f00000000, + 0x3eb26f8600000000, 0x99306a9c00000000, 0x05b1970500000000, + 0xd73561a800000000, 0x4bb49c3100000000, 0xec36992b00000000, + 0x70b764b200000000, 0x4b3f77c000000000, 0xd7be8a5900000000, + 0x703c8f4300000000, 0xecbd72da00000000, 0x3e39847700000000, + 0xa2b879ee00000000, 0x053a7cf400000000, 0x99bb816d00000000, + 0x732a5b1000000000, 0xefaba68900000000, 0x4829a39300000000, + 0xd4a85e0a00000000, 0x062ca8a700000000, 0x9aad553e00000000, + 0x3d2f502400000000, 0xa1aeadbd00000000, 0x9a26becf00000000, + 0x06a7435600000000, 0xa125464c00000000, 0x3da4bbd500000000, + 0xef204d7800000000, 0x73a1b0e100000000, 0xd423b5fb00000000, + 0x48a2486200000000, 0x4467243f00000000, 0xd8e6d9a600000000, + 0x7f64dcbc00000000, 0xe3e5212500000000, 0x3161d78800000000, + 0xade02a1100000000, 0x0a622f0b00000000, 0x96e3d29200000000, + 0xad6bc1e000000000, 0x31ea3c7900000000, 0x9668396300000000, + 0x0ae9c4fa00000000, 0xd86d325700000000, 0x44eccfce00000000, + 0xe36ecad400000000, 0x7fef374d00000000, 0x957eed3000000000, + 0x09ff10a900000000, 0xae7d15b300000000, 0x32fce82a00000000, + 0xe0781e8700000000, 0x7cf9e31e00000000, 0xdb7be60400000000, + 0x47fa1b9d00000000, 0x7c7208ef00000000, 0xe0f3f57600000000, + 0x4771f06c00000000, 0xdbf00df500000000, 0x0974fb5800000000, + 0x95f506c100000000, 0x327703db00000000, 0xaef6fe4200000000, + 0xe654b62000000000, 0x7ad54bb900000000, 0xdd574ea300000000, + 0x41d6b33a00000000, 0x9352459700000000, 0x0fd3b80e00000000, + 0xa851bd1400000000, 0x34d0408d00000000, 0x0f5853ff00000000, + 0x93d9ae6600000000, 0x345bab7c00000000, 0xa8da56e500000000, + 0x7a5ea04800000000, 0xe6df5dd100000000, 0x415d58cb00000000, + 0xdddca55200000000, 0x374d7f2f00000000, 0xabcc82b600000000, + 0x0c4e87ac00000000, 0x90cf7a3500000000, 0x424b8c9800000000, + 0xdeca710100000000, 0x7948741b00000000, 0xe5c9898200000000, + 0xde419af000000000, 0x42c0676900000000, 0xe542627300000000, + 0x79c39fea00000000, 0xab47694700000000, 0x37c694de00000000, + 0x904491c400000000, 0x0cc56c5d00000000, 0x88ce487e00000000, + 0x144fb5e700000000, 0xb3cdb0fd00000000, 0x2f4c4d6400000000, + 0xfdc8bbc900000000, 0x6149465000000000, 0xc6cb434a00000000, + 0x5a4abed300000000, 0x61c2ada100000000, 0xfd43503800000000, + 0x5ac1552200000000, 0xc640a8bb00000000, 0x14c45e1600000000, + 0x8845a38f00000000, 0x2fc7a69500000000, 0xb3465b0c00000000, + 0x59d7817100000000, 0xc5567ce800000000, 0x62d479f200000000, + 0xfe55846b00000000, 0x2cd172c600000000, 0xb0508f5f00000000, + 0x17d28a4500000000, 0x8b5377dc00000000, 0xb0db64ae00000000, + 0x2c5a993700000000, 0x8bd89c2d00000000, 0x175961b400000000, + 0xc5dd971900000000, 0x595c6a8000000000, 0xfede6f9a00000000, + 0x625f920300000000, 0x2afdda6100000000, 0xb67c27f800000000, + 0x11fe22e200000000, 0x8d7fdf7b00000000, 0x5ffb29d600000000, + 0xc37ad44f00000000, 0x64f8d15500000000, 0xf8792ccc00000000, + 0xc3f13fbe00000000, 0x5f70c22700000000, 0xf8f2c73d00000000, + 0x64733aa400000000, 0xb6f7cc0900000000, 0x2a76319000000000, + 0x8df4348a00000000, 0x1175c91300000000, 0xfbe4136e00000000, + 0x6765eef700000000, 0xc0e7ebed00000000, 0x5c66167400000000, + 0x8ee2e0d900000000, 0x12631d4000000000, 0xb5e1185a00000000, + 0x2960e5c300000000, 0x12e8f6b100000000, 0x8e690b2800000000, + 0x29eb0e3200000000, 0xb56af3ab00000000, 0x67ee050600000000, + 0xfb6ff89f00000000, 0x5cedfd8500000000, 0xc06c001c00000000, + 0xcca96c4100000000, 0x502891d800000000, 0xf7aa94c200000000, + 0x6b2b695b00000000, 0xb9af9ff600000000, 0x252e626f00000000, + 0x82ac677500000000, 0x1e2d9aec00000000, 0x25a5899e00000000, + 0xb924740700000000, 0x1ea6711d00000000, 0x82278c8400000000, + 0x50a37a2900000000, 0xcc2287b000000000, 0x6ba082aa00000000, + 0xf7217f3300000000, 0x1db0a54e00000000, 0x813158d700000000, + 0x26b35dcd00000000, 0xba32a05400000000, 0x68b656f900000000, + 0xf437ab6000000000, 0x53b5ae7a00000000, 0xcf3453e300000000, + 0xf4bc409100000000, 0x683dbd0800000000, 0xcfbfb81200000000, + 0x533e458b00000000, 0x81bab32600000000, 0x1d3b4ebf00000000, + 0xbab94ba500000000, 0x2638b63c00000000, 0x6e9afe5e00000000, + 0xf21b03c700000000, 0x559906dd00000000, 0xc918fb4400000000, + 0x1b9c0de900000000, 0x871df07000000000, 0x209ff56a00000000, + 0xbc1e08f300000000, 0x87961b8100000000, 0x1b17e61800000000, + 0xbc95e30200000000, 0x20141e9b00000000, 0xf290e83600000000, + 0x6e1115af00000000, 0xc99310b500000000, 0x5512ed2c00000000, + 0xbf83375100000000, 0x2302cac800000000, 0x8480cfd200000000, + 0x1801324b00000000, 0xca85c4e600000000, 0x5604397f00000000, + 0xf1863c6500000000, 0x6d07c1fc00000000, 0x568fd28e00000000, + 0xca0e2f1700000000, 0x6d8c2a0d00000000, 0xf10dd79400000000, + 0x2389213900000000, 0xbf08dca000000000, 0x188ad9ba00000000, + 0x840b242300000000}, + {0x0000000000000000, 0x8161594700000000, 0x02c3b28e00000000, + 0x83a2ebc900000000, 0x078666ad00000000, 0x86e73fea00000000, + 0x0545d42300000000, 0x84248d6400000000, 0x0d0cceea00000000, + 0x8c6d97ad00000000, 0x0fcf7c6400000000, 0x8eae252300000000, + 0x0a8aa84700000000, 0x8bebf10000000000, 0x08491ac900000000, + 0x8928438e00000000, 0x19189f6500000000, 0x9879c62200000000, + 0x1bdb2deb00000000, 0x9aba74ac00000000, 0x1e9ef9c800000000, + 0x9fffa08f00000000, 0x1c5d4b4600000000, 0x9d3c120100000000, + 0x1414518f00000000, 0x957508c800000000, 0x16d7e30100000000, + 0x97b6ba4600000000, 0x1392372200000000, 0x92f36e6500000000, + 0x115185ac00000000, 0x9030dceb00000000, 0x32303ecb00000000, + 0xb351678c00000000, 0x30f38c4500000000, 0xb192d50200000000, + 0x35b6586600000000, 0xb4d7012100000000, 0x3775eae800000000, + 0xb614b3af00000000, 0x3f3cf02100000000, 0xbe5da96600000000, + 0x3dff42af00000000, 0xbc9e1be800000000, 0x38ba968c00000000, + 0xb9dbcfcb00000000, 0x3a79240200000000, 0xbb187d4500000000, + 0x2b28a1ae00000000, 0xaa49f8e900000000, 0x29eb132000000000, + 0xa88a4a6700000000, 0x2caec70300000000, 0xadcf9e4400000000, + 0x2e6d758d00000000, 0xaf0c2cca00000000, 0x26246f4400000000, + 0xa745360300000000, 0x24e7ddca00000000, 0xa586848d00000000, + 0x21a209e900000000, 0xa0c350ae00000000, 0x2361bb6700000000, + 0xa200e22000000000, 0x67607f2600000000, 0xe601266100000000, + 0x65a3cda800000000, 0xe4c294ef00000000, 0x60e6198b00000000, + 0xe18740cc00000000, 0x6225ab0500000000, 0xe344f24200000000, + 0x6a6cb1cc00000000, 0xeb0de88b00000000, 0x68af034200000000, + 0xe9ce5a0500000000, 0x6dead76100000000, 0xec8b8e2600000000, + 0x6f2965ef00000000, 0xee483ca800000000, 0x7e78e04300000000, + 0xff19b90400000000, 0x7cbb52cd00000000, 0xfdda0b8a00000000, + 0x79fe86ee00000000, 0xf89fdfa900000000, 0x7b3d346000000000, + 0xfa5c6d2700000000, 0x73742ea900000000, 0xf21577ee00000000, + 0x71b79c2700000000, 0xf0d6c56000000000, 0x74f2480400000000, + 0xf593114300000000, 0x7631fa8a00000000, 0xf750a3cd00000000, + 0x555041ed00000000, 0xd43118aa00000000, 0x5793f36300000000, + 0xd6f2aa2400000000, 0x52d6274000000000, 0xd3b77e0700000000, + 0x501595ce00000000, 0xd174cc8900000000, 0x585c8f0700000000, + 0xd93dd64000000000, 0x5a9f3d8900000000, 0xdbfe64ce00000000, + 0x5fdae9aa00000000, 0xdebbb0ed00000000, 0x5d195b2400000000, + 0xdc78026300000000, 0x4c48de8800000000, 0xcd2987cf00000000, + 0x4e8b6c0600000000, 0xcfea354100000000, 0x4bceb82500000000, + 0xcaafe16200000000, 0x490d0aab00000000, 0xc86c53ec00000000, + 0x4144106200000000, 0xc025492500000000, 0x4387a2ec00000000, + 0xc2e6fbab00000000, 0x46c276cf00000000, 0xc7a32f8800000000, + 0x4401c44100000000, 0xc5609d0600000000, 0xcec0fe4c00000000, + 0x4fa1a70b00000000, 0xcc034cc200000000, 0x4d62158500000000, + 0xc94698e100000000, 0x4827c1a600000000, 0xcb852a6f00000000, + 0x4ae4732800000000, 0xc3cc30a600000000, 0x42ad69e100000000, + 0xc10f822800000000, 0x406edb6f00000000, 0xc44a560b00000000, + 0x452b0f4c00000000, 0xc689e48500000000, 0x47e8bdc200000000, + 0xd7d8612900000000, 0x56b9386e00000000, 0xd51bd3a700000000, + 0x547a8ae000000000, 0xd05e078400000000, 0x513f5ec300000000, + 0xd29db50a00000000, 0x53fcec4d00000000, 0xdad4afc300000000, + 0x5bb5f68400000000, 0xd8171d4d00000000, 0x5976440a00000000, + 0xdd52c96e00000000, 0x5c33902900000000, 0xdf917be000000000, + 0x5ef022a700000000, 0xfcf0c08700000000, 0x7d9199c000000000, + 0xfe33720900000000, 0x7f522b4e00000000, 0xfb76a62a00000000, + 0x7a17ff6d00000000, 0xf9b514a400000000, 0x78d44de300000000, + 0xf1fc0e6d00000000, 0x709d572a00000000, 0xf33fbce300000000, + 0x725ee5a400000000, 0xf67a68c000000000, 0x771b318700000000, + 0xf4b9da4e00000000, 0x75d8830900000000, 0xe5e85fe200000000, + 0x648906a500000000, 0xe72bed6c00000000, 0x664ab42b00000000, + 0xe26e394f00000000, 0x630f600800000000, 0xe0ad8bc100000000, + 0x61ccd28600000000, 0xe8e4910800000000, 0x6985c84f00000000, + 0xea27238600000000, 0x6b467ac100000000, 0xef62f7a500000000, + 0x6e03aee200000000, 0xeda1452b00000000, 0x6cc01c6c00000000, + 0xa9a0816a00000000, 0x28c1d82d00000000, 0xab6333e400000000, + 0x2a026aa300000000, 0xae26e7c700000000, 0x2f47be8000000000, + 0xace5554900000000, 0x2d840c0e00000000, 0xa4ac4f8000000000, + 0x25cd16c700000000, 0xa66ffd0e00000000, 0x270ea44900000000, + 0xa32a292d00000000, 0x224b706a00000000, 0xa1e99ba300000000, + 0x2088c2e400000000, 0xb0b81e0f00000000, 0x31d9474800000000, + 0xb27bac8100000000, 0x331af5c600000000, 0xb73e78a200000000, + 0x365f21e500000000, 0xb5fdca2c00000000, 0x349c936b00000000, + 0xbdb4d0e500000000, 0x3cd589a200000000, 0xbf77626b00000000, + 0x3e163b2c00000000, 0xba32b64800000000, 0x3b53ef0f00000000, + 0xb8f104c600000000, 0x39905d8100000000, 0x9b90bfa100000000, + 0x1af1e6e600000000, 0x99530d2f00000000, 0x1832546800000000, + 0x9c16d90c00000000, 0x1d77804b00000000, 0x9ed56b8200000000, + 0x1fb432c500000000, 0x969c714b00000000, 0x17fd280c00000000, + 0x945fc3c500000000, 0x153e9a8200000000, 0x911a17e600000000, + 0x107b4ea100000000, 0x93d9a56800000000, 0x12b8fc2f00000000, + 0x828820c400000000, 0x03e9798300000000, 0x804b924a00000000, + 0x012acb0d00000000, 0x850e466900000000, 0x046f1f2e00000000, + 0x87cdf4e700000000, 0x06acada000000000, 0x8f84ee2e00000000, + 0x0ee5b76900000000, 0x8d475ca000000000, 0x0c2605e700000000, + 0x8802888300000000, 0x0963d1c400000000, 0x8ac13a0d00000000, + 0x0ba0634a00000000}}; + +#else /* W == 4 */ + +static const crc_t crc_braid_table[][256] = { + {0x00000000, 0x51010001, 0xa2020002, 0xf3030003, 0xf4070007, + 0xa5060006, 0x56050005, 0x07040004, 0x580d000d, 0x090c000c, + 0xfa0f000f, 0xab0e000e, 0xac0a000a, 0xfd0b000b, 0x0e080008, + 0x5f090009, 0xb01a001a, 0xe11b001b, 0x12180018, 0x43190019, + 0x441d001d, 0x151c001c, 0xe61f001f, 0xb71e001e, 0xe8170017, + 0xb9160016, 0x4a150015, 0x1b140014, 0x1c100010, 0x4d110011, + 0xbe120012, 0xef130013, 0xd0370037, 0x81360036, 0x72350035, + 0x23340034, 0x24300030, 0x75310031, 0x86320032, 0xd7330033, + 0x883a003a, 0xd93b003b, 0x2a380038, 0x7b390039, 0x7c3d003d, + 0x2d3c003c, 0xde3f003f, 0x8f3e003e, 0x602d002d, 0x312c002c, + 0xc22f002f, 0x932e002e, 0x942a002a, 0xc52b002b, 0x36280028, + 0x67290029, 0x38200020, 0x69210021, 0x9a220022, 0xcb230023, + 0xcc270027, 0x9d260026, 0x6e250025, 0x3f240024, 0x106d006d, + 0x416c006c, 0xb26f006f, 0xe36e006e, 0xe46a006a, 0xb56b006b, + 0x46680068, 0x17690069, 0x48600060, 0x19610061, 0xea620062, + 0xbb630063, 0xbc670067, 0xed660066, 0x1e650065, 0x4f640064, + 0xa0770077, 0xf1760076, 0x02750075, 0x53740074, 0x54700070, + 0x05710071, 0xf6720072, 0xa7730073, 0xf87a007a, 0xa97b007b, + 0x5a780078, 0x0b790079, 0x0c7d007d, 0x5d7c007c, 0xae7f007f, + 0xff7e007e, 0xc05a005a, 0x915b005b, 0x62580058, 0x33590059, + 0x345d005d, 0x655c005c, 0x965f005f, 0xc75e005e, 0x98570057, + 0xc9560056, 0x3a550055, 0x6b540054, 0x6c500050, 0x3d510051, + 0xce520052, 0x9f530053, 0x70400040, 0x21410041, 0xd2420042, + 0x83430043, 0x84470047, 0xd5460046, 0x26450045, 0x77440044, + 0x284d004d, 0x794c004c, 0x8a4f004f, 0xdb4e004e, 0xdc4a004a, + 0x8d4b004b, 0x7e480048, 0x2f490049, 0x20da00da, 0x71db00db, + 0x82d800d8, 0xd3d900d9, 0xd4dd00dd, 0x85dc00dc, 0x76df00df, + 0x27de00de, 0x78d700d7, 0x29d600d6, 0xdad500d5, 0x8bd400d4, + 0x8cd000d0, 0xddd100d1, 0x2ed200d2, 0x7fd300d3, 0x90c000c0, + 0xc1c100c1, 0x32c200c2, 0x63c300c3, 0x64c700c7, 0x35c600c6, + 0xc6c500c5, 0x97c400c4, 0xc8cd00cd, 0x99cc00cc, 0x6acf00cf, + 0x3bce00ce, 0x3cca00ca, 0x6dcb00cb, 0x9ec800c8, 0xcfc900c9, + 0xf0ed00ed, 0xa1ec00ec, 0x52ef00ef, 0x03ee00ee, 0x04ea00ea, + 0x55eb00eb, 0xa6e800e8, 0xf7e900e9, 0xa8e000e0, 0xf9e100e1, + 0x0ae200e2, 0x5be300e3, 0x5ce700e7, 0x0de600e6, 0xfee500e5, + 0xafe400e4, 0x40f700f7, 0x11f600f6, 0xe2f500f5, 0xb3f400f4, + 0xb4f000f0, 0xe5f100f1, 0x16f200f2, 0x47f300f3, 0x18fa00fa, + 0x49fb00fb, 0xbaf800f8, 0xebf900f9, 0xecfd00fd, 0xbdfc00fc, + 0x4eff00ff, 0x1ffe00fe, 0x30b700b7, 0x61b600b6, 0x92b500b5, + 0xc3b400b4, 0xc4b000b0, 0x95b100b1, 0x66b200b2, 0x37b300b3, + 0x68ba00ba, 0x39bb00bb, 0xcab800b8, 0x9bb900b9, 0x9cbd00bd, + 0xcdbc00bc, 0x3ebf00bf, 0x6fbe00be, 0x80ad00ad, 0xd1ac00ac, + 0x22af00af, 0x73ae00ae, 0x74aa00aa, 0x25ab00ab, 0xd6a800a8, + 0x87a900a9, 0xd8a000a0, 0x89a100a1, 0x7aa200a2, 0x2ba300a3, + 0x2ca700a7, 0x7da600a6, 0x8ea500a5, 0xdfa400a4, 0xe0800080, + 0xb1810081, 0x42820082, 0x13830083, 0x14870087, 0x45860086, + 0xb6850085, 0xe7840084, 0xb88d008d, 0xe98c008c, 0x1a8f008f, + 0x4b8e008e, 0x4c8a008a, 0x1d8b008b, 0xee880088, 0xbf890089, + 0x509a009a, 0x019b009b, 0xf2980098, 0xa3990099, 0xa49d009d, + 0xf59c009c, 0x069f009f, 0x579e009e, 0x08970097, 0x59960096, + 0xaa950095, 0xfb940094, 0xfc900090, 0xad910091, 0x5e920092, + 0x0f930093}, + {0x00000000, 0x41b401b4, 0x83680368, 0xc2dc02dc, 0xb6d306d3, + 0xf7670767, 0x35bb05bb, 0x740f040f, 0xdda50da5, 0x9c110c11, + 0x5ecd0ecd, 0x1f790f79, 0x6b760b76, 0x2ac20ac2, 0xe81e081e, + 0xa9aa09aa, 0x0b491b49, 0x4afd1afd, 0x88211821, 0xc9951995, + 0xbd9a1d9a, 0xfc2e1c2e, 0x3ef21ef2, 0x7f461f46, 0xd6ec16ec, + 0x97581758, 0x55841584, 0x14301430, 0x603f103f, 0x218b118b, + 0xe3571357, 0xa2e312e3, 0x16923692, 0x57263726, 0x95fa35fa, + 0xd44e344e, 0xa0413041, 0xe1f531f5, 0x23293329, 0x629d329d, + 0xcb373b37, 0x8a833a83, 0x485f385f, 0x09eb39eb, 0x7de43de4, + 0x3c503c50, 0xfe8c3e8c, 0xbf383f38, 0x1ddb2ddb, 0x5c6f2c6f, + 0x9eb32eb3, 0xdf072f07, 0xab082b08, 0xeabc2abc, 0x28602860, + 0x69d429d4, 0xc07e207e, 0x81ca21ca, 0x43162316, 0x02a222a2, + 0x76ad26ad, 0x37192719, 0xf5c525c5, 0xb4712471, 0x2d246d24, + 0x6c906c90, 0xae4c6e4c, 0xeff86ff8, 0x9bf76bf7, 0xda436a43, + 0x189f689f, 0x592b692b, 0xf0816081, 0xb1356135, 0x73e963e9, + 0x325d625d, 0x46526652, 0x07e667e6, 0xc53a653a, 0x848e648e, + 0x266d766d, 0x67d977d9, 0xa5057505, 0xe4b174b1, 0x90be70be, + 0xd10a710a, 0x13d673d6, 0x52627262, 0xfbc87bc8, 0xba7c7a7c, + 0x78a078a0, 0x39147914, 0x4d1b7d1b, 0x0caf7caf, 0xce737e73, + 0x8fc77fc7, 0x3bb65bb6, 0x7a025a02, 0xb8de58de, 0xf96a596a, + 0x8d655d65, 0xccd15cd1, 0x0e0d5e0d, 0x4fb95fb9, 0xe6135613, + 0xa7a757a7, 0x657b557b, 0x24cf54cf, 0x50c050c0, 0x11745174, + 0xd3a853a8, 0x921c521c, 0x30ff40ff, 0x714b414b, 0xb3974397, + 0xf2234223, 0x862c462c, 0xc7984798, 0x05444544, 0x44f044f0, + 0xed5a4d5a, 0xacee4cee, 0x6e324e32, 0x2f864f86, 0x5b894b89, + 0x1a3d4a3d, 0xd8e148e1, 0x99554955, 0x5a48da48, 0x1bfcdbfc, + 0xd920d920, 0x9894d894, 0xec9bdc9b, 0xad2fdd2f, 0x6ff3dff3, + 0x2e47de47, 0x87edd7ed, 0xc659d659, 0x0485d485, 0x4531d531, + 0x313ed13e, 0x708ad08a, 0xb256d256, 0xf3e2d3e2, 0x5101c101, + 0x10b5c0b5, 0xd269c269, 0x93ddc3dd, 0xe7d2c7d2, 0xa666c666, + 0x64bac4ba, 0x250ec50e, 0x8ca4cca4, 0xcd10cd10, 0x0fcccfcc, + 0x4e78ce78, 0x3a77ca77, 0x7bc3cbc3, 0xb91fc91f, 0xf8abc8ab, + 0x4cdaecda, 0x0d6eed6e, 0xcfb2efb2, 0x8e06ee06, 0xfa09ea09, + 0xbbbdebbd, 0x7961e961, 0x38d5e8d5, 0x917fe17f, 0xd0cbe0cb, + 0x1217e217, 0x53a3e3a3, 0x27ace7ac, 0x6618e618, 0xa4c4e4c4, + 0xe570e570, 0x4793f793, 0x0627f627, 0xc4fbf4fb, 0x854ff54f, + 0xf140f140, 0xb0f4f0f4, 0x7228f228, 0x339cf39c, 0x9a36fa36, + 0xdb82fb82, 0x195ef95e, 0x58eaf8ea, 0x2ce5fce5, 0x6d51fd51, + 0xaf8dff8d, 0xee39fe39, 0x776cb76c, 0x36d8b6d8, 0xf404b404, + 0xb5b0b5b0, 0xc1bfb1bf, 0x800bb00b, 0x42d7b2d7, 0x0363b363, + 0xaac9bac9, 0xeb7dbb7d, 0x29a1b9a1, 0x6815b815, 0x1c1abc1a, + 0x5daebdae, 0x9f72bf72, 0xdec6bec6, 0x7c25ac25, 0x3d91ad91, + 0xff4daf4d, 0xbef9aef9, 0xcaf6aaf6, 0x8b42ab42, 0x499ea99e, + 0x082aa82a, 0xa180a180, 0xe034a034, 0x22e8a2e8, 0x635ca35c, + 0x1753a753, 0x56e7a6e7, 0x943ba43b, 0xd58fa58f, 0x61fe81fe, + 0x204a804a, 0xe2968296, 0xa3228322, 0xd72d872d, 0x96998699, + 0x54458445, 0x15f185f1, 0xbc5b8c5b, 0xfdef8def, 0x3f338f33, + 0x7e878e87, 0x0a888a88, 0x4b3c8b3c, 0x89e089e0, 0xc8548854, + 0x6ab79ab7, 0x2b039b03, 0xe9df99df, 0xa86b986b, 0xdc649c64, + 0x9dd09dd0, 0x5f0c9f0c, 0x1eb89eb8, 0xb7129712, 0xf6a696a6, + 0x347a947a, 0x75ce95ce, 0x01c191c1, 0x40759075, 0x82a992a9, + 0xc31d931d}, + {0x00000000, 0xb491b490, 0xd9206923, 0x6db1ddb3, 0x0243d245, + 0xb6d266d5, 0xdb63bb66, 0x6ff20ff6, 0x0487a48a, 0xb016101a, + 0xdda7cda9, 0x69367939, 0x06c476cf, 0xb255c25f, 0xdfe41fec, + 0x6b75ab7c, 0x090f4914, 0xbd9efd84, 0xd02f2037, 0x64be94a7, + 0x0b4c9b51, 0xbfdd2fc1, 0xd26cf272, 0x66fd46e2, 0x0d88ed9e, + 0xb919590e, 0xd4a884bd, 0x6039302d, 0x0fcb3fdb, 0xbb5a8b4b, + 0xd6eb56f8, 0x627ae268, 0x121e9228, 0xa68f26b8, 0xcb3efb0b, + 0x7faf4f9b, 0x105d406d, 0xa4ccf4fd, 0xc97d294e, 0x7dec9dde, + 0x169936a2, 0xa2088232, 0xcfb95f81, 0x7b28eb11, 0x14dae4e7, + 0xa04b5077, 0xcdfa8dc4, 0x796b3954, 0x1b11db3c, 0xaf806fac, + 0xc231b21f, 0x76a0068f, 0x19520979, 0xadc3bde9, 0xc072605a, + 0x74e3d4ca, 0x1f967fb6, 0xab07cb26, 0xc6b61695, 0x7227a205, + 0x1dd5adf3, 0xa9441963, 0xc4f5c4d0, 0x70647040, 0x243d2450, + 0x90ac90c0, 0xfd1d4d73, 0x498cf9e3, 0x267ef615, 0x92ef4285, + 0xff5e9f36, 0x4bcf2ba6, 0x20ba80da, 0x942b344a, 0xf99ae9f9, + 0x4d0b5d69, 0x22f9529f, 0x9668e60f, 0xfbd93bbc, 0x4f488f2c, + 0x2d326d44, 0x99a3d9d4, 0xf4120467, 0x4083b0f7, 0x2f71bf01, + 0x9be00b91, 0xf651d622, 0x42c062b2, 0x29b5c9ce, 0x9d247d5e, + 0xf095a0ed, 0x4404147d, 0x2bf61b8b, 0x9f67af1b, 0xf2d672a8, + 0x4647c638, 0x3623b678, 0x82b202e8, 0xef03df5b, 0x5b926bcb, + 0x3460643d, 0x80f1d0ad, 0xed400d1e, 0x59d1b98e, 0x32a412f2, + 0x8635a662, 0xeb847bd1, 0x5f15cf41, 0x30e7c0b7, 0x84767427, + 0xe9c7a994, 0x5d561d04, 0x3f2cff6c, 0x8bbd4bfc, 0xe60c964f, + 0x529d22df, 0x3d6f2d29, 0x89fe99b9, 0xe44f440a, 0x50def09a, + 0x3bab5be6, 0x8f3aef76, 0xe28b32c5, 0x561a8655, 0x39e889a3, + 0x8d793d33, 0xe0c8e080, 0x54595410, 0x487a48a0, 0xfcebfc30, + 0x915a2183, 0x25cb9513, 0x4a399ae5, 0xfea82e75, 0x9319f3c6, + 0x27884756, 0x4cfdec2a, 0xf86c58ba, 0x95dd8509, 0x214c3199, + 0x4ebe3e6f, 0xfa2f8aff, 0x979e574c, 0x230fe3dc, 0x417501b4, + 0xf5e4b524, 0x98556897, 0x2cc4dc07, 0x4336d3f1, 0xf7a76761, + 0x9a16bad2, 0x2e870e42, 0x45f2a53e, 0xf16311ae, 0x9cd2cc1d, + 0x2843788d, 0x47b1777b, 0xf320c3eb, 0x9e911e58, 0x2a00aac8, + 0x5a64da88, 0xeef56e18, 0x8344b3ab, 0x37d5073b, 0x582708cd, + 0xecb6bc5d, 0x810761ee, 0x3596d57e, 0x5ee37e02, 0xea72ca92, + 0x87c31721, 0x3352a3b1, 0x5ca0ac47, 0xe83118d7, 0x8580c564, + 0x311171f4, 0x536b939c, 0xe7fa270c, 0x8a4bfabf, 0x3eda4e2f, + 0x512841d9, 0xe5b9f549, 0x880828fa, 0x3c999c6a, 0x57ec3716, + 0xe37d8386, 0x8ecc5e35, 0x3a5deaa5, 0x55afe553, 0xe13e51c3, + 0x8c8f8c70, 0x381e38e0, 0x6c476cf0, 0xd8d6d860, 0xb56705d3, + 0x01f6b143, 0x6e04beb5, 0xda950a25, 0xb724d796, 0x03b56306, + 0x68c0c87a, 0xdc517cea, 0xb1e0a159, 0x057115c9, 0x6a831a3f, + 0xde12aeaf, 0xb3a3731c, 0x0732c78c, 0x654825e4, 0xd1d99174, + 0xbc684cc7, 0x08f9f857, 0x670bf7a1, 0xd39a4331, 0xbe2b9e82, + 0x0aba2a12, 0x61cf816e, 0xd55e35fe, 0xb8efe84d, 0x0c7e5cdd, + 0x638c532b, 0xd71de7bb, 0xbaac3a08, 0x0e3d8e98, 0x7e59fed8, + 0xcac84a48, 0xa77997fb, 0x13e8236b, 0x7c1a2c9d, 0xc88b980d, + 0xa53a45be, 0x11abf12e, 0x7ade5a52, 0xce4feec2, 0xa3fe3371, + 0x176f87e1, 0x789d8817, 0xcc0c3c87, 0xa1bde134, 0x152c55a4, + 0x7756b7cc, 0xc3c7035c, 0xae76deef, 0x1ae76a7f, 0x75156589, + 0xc184d119, 0xac350caa, 0x18a4b83a, 0x73d11346, 0xc740a7d6, + 0xaaf17a65, 0x1e60cef5, 0x7192c103, 0xc5037593, 0xa8b2a820, + 0x1c231cb0}, + {0x00000000, 0x90f49140, 0x91ea2283, 0x011eb3c3, 0x93d74505, + 0x0323d445, 0x023d6786, 0x92c9f6c6, 0x97ad8a09, 0x07591b49, + 0x0647a88a, 0x96b339ca, 0x047acf0c, 0x948e5e4c, 0x9590ed8f, + 0x05647ccf, 0x9f581411, 0x0fac8551, 0x0eb23692, 0x9e46a7d2, + 0x0c8f5114, 0x9c7bc054, 0x9d657397, 0x0d91e2d7, 0x08f59e18, + 0x98010f58, 0x991fbc9b, 0x09eb2ddb, 0x9b22db1d, 0x0bd64a5d, + 0x0ac8f99e, 0x9a3c68de, 0x8eb32821, 0x1e47b961, 0x1f590aa2, + 0x8fad9be2, 0x1d646d24, 0x8d90fc64, 0x8c8e4fa7, 0x1c7adee7, + 0x191ea228, 0x89ea3368, 0x88f480ab, 0x180011eb, 0x8ac9e72d, + 0x1a3d766d, 0x1b23c5ae, 0x8bd754ee, 0x11eb3c30, 0x811fad70, + 0x80011eb3, 0x10f58ff3, 0x823c7935, 0x12c8e875, 0x13d65bb6, + 0x8322caf6, 0x8646b639, 0x16b22779, 0x17ac94ba, 0x875805fa, + 0x1591f33c, 0x8565627c, 0x847bd1bf, 0x148f40ff, 0xad655041, + 0x3d91c101, 0x3c8f72c2, 0xac7be382, 0x3eb21544, 0xae468404, + 0xaf5837c7, 0x3faca687, 0x3ac8da48, 0xaa3c4b08, 0xab22f8cb, + 0x3bd6698b, 0xa91f9f4d, 0x39eb0e0d, 0x38f5bdce, 0xa8012c8e, + 0x323d4450, 0xa2c9d510, 0xa3d766d3, 0x3323f793, 0xa1ea0155, + 0x311e9015, 0x300023d6, 0xa0f4b296, 0xa590ce59, 0x35645f19, + 0x347aecda, 0xa48e7d9a, 0x36478b5c, 0xa6b31a1c, 0xa7ada9df, + 0x3759389f, 0x23d67860, 0xb322e920, 0xb23c5ae3, 0x22c8cba3, + 0xb0013d65, 0x20f5ac25, 0x21eb1fe6, 0xb11f8ea6, 0xb47bf269, + 0x248f6329, 0x2591d0ea, 0xb56541aa, 0x27acb76c, 0xb758262c, + 0xb64695ef, 0x26b204af, 0xbc8e6c71, 0x2c7afd31, 0x2d644ef2, + 0xbd90dfb2, 0x2f592974, 0xbfadb834, 0xbeb30bf7, 0x2e479ab7, + 0x2b23e678, 0xbbd77738, 0xbac9c4fb, 0x2a3d55bb, 0xb8f4a37d, + 0x2800323d, 0x291e81fe, 0xb9ea10be, 0xeac9a081, 0x7a3d31c1, + 0x7b238202, 0xebd71342, 0x791ee584, 0xe9ea74c4, 0xe8f4c707, + 0x78005647, 0x7d642a88, 0xed90bbc8, 0xec8e080b, 0x7c7a994b, + 0xeeb36f8d, 0x7e47fecd, 0x7f594d0e, 0xefaddc4e, 0x7591b490, + 0xe56525d0, 0xe47b9613, 0x748f0753, 0xe646f195, 0x76b260d5, + 0x77acd316, 0xe7584256, 0xe23c3e99, 0x72c8afd9, 0x73d61c1a, + 0xe3228d5a, 0x71eb7b9c, 0xe11feadc, 0xe001591f, 0x70f5c85f, + 0x647a88a0, 0xf48e19e0, 0xf590aa23, 0x65643b63, 0xf7adcda5, + 0x67595ce5, 0x6647ef26, 0xf6b37e66, 0xf3d702a9, 0x632393e9, + 0x623d202a, 0xf2c9b16a, 0x600047ac, 0xf0f4d6ec, 0xf1ea652f, + 0x611ef46f, 0xfb229cb1, 0x6bd60df1, 0x6ac8be32, 0xfa3c2f72, + 0x68f5d9b4, 0xf80148f4, 0xf91ffb37, 0x69eb6a77, 0x6c8f16b8, + 0xfc7b87f8, 0xfd65343b, 0x6d91a57b, 0xff5853bd, 0x6facc2fd, + 0x6eb2713e, 0xfe46e07e, 0x47acf0c0, 0xd7586180, 0xd646d243, + 0x46b24303, 0xd47bb5c5, 0x448f2485, 0x45919746, 0xd5650606, + 0xd0017ac9, 0x40f5eb89, 0x41eb584a, 0xd11fc90a, 0x43d63fcc, + 0xd322ae8c, 0xd23c1d4f, 0x42c88c0f, 0xd8f4e4d1, 0x48007591, + 0x491ec652, 0xd9ea5712, 0x4b23a1d4, 0xdbd73094, 0xdac98357, + 0x4a3d1217, 0x4f596ed8, 0xdfadff98, 0xdeb34c5b, 0x4e47dd1b, + 0xdc8e2bdd, 0x4c7aba9d, 0x4d64095e, 0xdd90981e, 0xc91fd8e1, + 0x59eb49a1, 0x58f5fa62, 0xc8016b22, 0x5ac89de4, 0xca3c0ca4, + 0xcb22bf67, 0x5bd62e27, 0x5eb252e8, 0xce46c3a8, 0xcf58706b, + 0x5face12b, 0xcd6517ed, 0x5d9186ad, 0x5c8f356e, 0xcc7ba42e, + 0x5647ccf0, 0xc6b35db0, 0xc7adee73, 0x57597f33, 0xc59089f5, + 0x556418b5, 0x547aab76, 0xc48e3a36, 0xc1ea46f9, 0x511ed7b9, + 0x5000647a, 0xc0f4f53a, 0x523d03fc, 0xc2c992bc, 0xc3d7217f, + 0x5323b03f}}; + +static const word_t crc_braid_big_table[][256] = { + {0x00000000, 0x4091f490, 0x8322ea91, 0xc3b31e01, 0x0545d793, + 0x45d42303, 0x86673d02, 0xc6f6c992, 0x098aad97, 0x491b5907, + 0x8aa84706, 0xca39b396, 0x0ccf7a04, 0x4c5e8e94, 0x8fed9095, + 0xcf7c6405, 0x1114589f, 0x5185ac0f, 0x9236b20e, 0xd2a7469e, + 0x14518f0c, 0x54c07b9c, 0x9773659d, 0xd7e2910d, 0x189ef508, + 0x580f0198, 0x9bbc1f99, 0xdb2deb09, 0x1ddb229b, 0x5d4ad60b, + 0x9ef9c80a, 0xde683c9a, 0x2128b38e, 0x61b9471e, 0xa20a591f, + 0xe29bad8f, 0x246d641d, 0x64fc908d, 0xa74f8e8c, 0xe7de7a1c, + 0x28a21e19, 0x6833ea89, 0xab80f488, 0xeb110018, 0x2de7c98a, + 0x6d763d1a, 0xaec5231b, 0xee54d78b, 0x303ceb11, 0x70ad1f81, + 0xb31e0180, 0xf38ff510, 0x35793c82, 0x75e8c812, 0xb65bd613, + 0xf6ca2283, 0x39b64686, 0x7927b216, 0xba94ac17, 0xfa055887, + 0x3cf39115, 0x7c626585, 0xbfd17b84, 0xff408f14, 0x415065ad, + 0x01c1913d, 0xc2728f3c, 0x82e37bac, 0x4415b23e, 0x048446ae, + 0xc73758af, 0x87a6ac3f, 0x48dac83a, 0x084b3caa, 0xcbf822ab, + 0x8b69d63b, 0x4d9f1fa9, 0x0d0eeb39, 0xcebdf538, 0x8e2c01a8, + 0x50443d32, 0x10d5c9a2, 0xd366d7a3, 0x93f72333, 0x5501eaa1, + 0x15901e31, 0xd6230030, 0x96b2f4a0, 0x59ce90a5, 0x195f6435, + 0xdaec7a34, 0x9a7d8ea4, 0x5c8b4736, 0x1c1ab3a6, 0xdfa9ada7, + 0x9f385937, 0x6078d623, 0x20e922b3, 0xe35a3cb2, 0xa3cbc822, + 0x653d01b0, 0x25acf520, 0xe61feb21, 0xa68e1fb1, 0x69f27bb4, + 0x29638f24, 0xead09125, 0xaa4165b5, 0x6cb7ac27, 0x2c2658b7, + 0xef9546b6, 0xaf04b226, 0x716c8ebc, 0x31fd7a2c, 0xf24e642d, + 0xb2df90bd, 0x7429592f, 0x34b8adbf, 0xf70bb3be, 0xb79a472e, + 0x78e6232b, 0x3877d7bb, 0xfbc4c9ba, 0xbb553d2a, 0x7da3f4b8, + 0x3d320028, 0xfe811e29, 0xbe10eab9, 0x81a0c9ea, 0xc1313d7a, + 0x0282237b, 0x4213d7eb, 0x84e51e79, 0xc474eae9, 0x07c7f4e8, + 0x47560078, 0x882a647d, 0xc8bb90ed, 0x0b088eec, 0x4b997a7c, + 0x8d6fb3ee, 0xcdfe477e, 0x0e4d597f, 0x4edcadef, 0x90b49175, + 0xd02565e5, 0x13967be4, 0x53078f74, 0x95f146e6, 0xd560b276, + 0x16d3ac77, 0x564258e7, 0x993e3ce2, 0xd9afc872, 0x1a1cd673, + 0x5a8d22e3, 0x9c7beb71, 0xdcea1fe1, 0x1f5901e0, 0x5fc8f570, + 0xa0887a64, 0xe0198ef4, 0x23aa90f5, 0x633b6465, 0xa5cdadf7, + 0xe55c5967, 0x26ef4766, 0x667eb3f6, 0xa902d7f3, 0xe9932363, + 0x2a203d62, 0x6ab1c9f2, 0xac470060, 0xecd6f4f0, 0x2f65eaf1, + 0x6ff41e61, 0xb19c22fb, 0xf10dd66b, 0x32bec86a, 0x722f3cfa, + 0xb4d9f568, 0xf44801f8, 0x37fb1ff9, 0x776aeb69, 0xb8168f6c, + 0xf8877bfc, 0x3b3465fd, 0x7ba5916d, 0xbd5358ff, 0xfdc2ac6f, + 0x3e71b26e, 0x7ee046fe, 0xc0f0ac47, 0x806158d7, 0x43d246d6, + 0x0343b246, 0xc5b57bd4, 0x85248f44, 0x46979145, 0x060665d5, + 0xc97a01d0, 0x89ebf540, 0x4a58eb41, 0x0ac91fd1, 0xcc3fd643, + 0x8cae22d3, 0x4f1d3cd2, 0x0f8cc842, 0xd1e4f4d8, 0x91750048, + 0x52c61e49, 0x1257ead9, 0xd4a1234b, 0x9430d7db, 0x5783c9da, + 0x17123d4a, 0xd86e594f, 0x98ffaddf, 0x5b4cb3de, 0x1bdd474e, + 0xdd2b8edc, 0x9dba7a4c, 0x5e09644d, 0x1e9890dd, 0xe1d81fc9, + 0xa149eb59, 0x62faf558, 0x226b01c8, 0xe49dc85a, 0xa40c3cca, + 0x67bf22cb, 0x272ed65b, 0xe852b25e, 0xa8c346ce, 0x6b7058cf, + 0x2be1ac5f, 0xed1765cd, 0xad86915d, 0x6e358f5c, 0x2ea47bcc, + 0xf0cc4756, 0xb05db3c6, 0x73eeadc7, 0x337f5957, 0xf58990c5, + 0xb5186455, 0x76ab7a54, 0x363a8ec4, 0xf946eac1, 0xb9d71e51, + 0x7a640050, 0x3af5f4c0, 0xfc033d52, 0xbc92c9c2, 0x7f21d7c3, + 0x3fb02353}, + {0x00000000, 0x90b491b4, 0x236920d9, 0xb3ddb16d, 0x45d24302, + 0xd566d2b6, 0x66bb63db, 0xf60ff26f, 0x8aa48704, 0x1a1016b0, + 0xa9cda7dd, 0x39793669, 0xcf76c406, 0x5fc255b2, 0xec1fe4df, + 0x7cab756b, 0x14490f09, 0x84fd9ebd, 0x37202fd0, 0xa794be64, + 0x519b4c0b, 0xc12fddbf, 0x72f26cd2, 0xe246fd66, 0x9eed880d, + 0x0e5919b9, 0xbd84a8d4, 0x2d303960, 0xdb3fcb0f, 0x4b8b5abb, + 0xf856ebd6, 0x68e27a62, 0x28921e12, 0xb8268fa6, 0x0bfb3ecb, + 0x9b4faf7f, 0x6d405d10, 0xfdf4cca4, 0x4e297dc9, 0xde9dec7d, + 0xa2369916, 0x328208a2, 0x815fb9cf, 0x11eb287b, 0xe7e4da14, + 0x77504ba0, 0xc48dfacd, 0x54396b79, 0x3cdb111b, 0xac6f80af, + 0x1fb231c2, 0x8f06a076, 0x79095219, 0xe9bdc3ad, 0x5a6072c0, + 0xcad4e374, 0xb67f961f, 0x26cb07ab, 0x9516b6c6, 0x05a22772, + 0xf3add51d, 0x631944a9, 0xd0c4f5c4, 0x40706470, 0x50243d24, + 0xc090ac90, 0x734d1dfd, 0xe3f98c49, 0x15f67e26, 0x8542ef92, + 0x369f5eff, 0xa62bcf4b, 0xda80ba20, 0x4a342b94, 0xf9e99af9, + 0x695d0b4d, 0x9f52f922, 0x0fe66896, 0xbc3bd9fb, 0x2c8f484f, + 0x446d322d, 0xd4d9a399, 0x670412f4, 0xf7b08340, 0x01bf712f, + 0x910be09b, 0x22d651f6, 0xb262c042, 0xcec9b529, 0x5e7d249d, + 0xeda095f0, 0x7d140444, 0x8b1bf62b, 0x1baf679f, 0xa872d6f2, + 0x38c64746, 0x78b62336, 0xe802b282, 0x5bdf03ef, 0xcb6b925b, + 0x3d646034, 0xadd0f180, 0x1e0d40ed, 0x8eb9d159, 0xf212a432, + 0x62a63586, 0xd17b84eb, 0x41cf155f, 0xb7c0e730, 0x27747684, + 0x94a9c7e9, 0x041d565d, 0x6cff2c3f, 0xfc4bbd8b, 0x4f960ce6, + 0xdf229d52, 0x292d6f3d, 0xb999fe89, 0x0a444fe4, 0x9af0de50, + 0xe65bab3b, 0x76ef3a8f, 0xc5328be2, 0x55861a56, 0xa389e839, + 0x333d798d, 0x80e0c8e0, 0x10545954, 0xa0487a48, 0x30fcebfc, + 0x83215a91, 0x1395cb25, 0xe59a394a, 0x752ea8fe, 0xc6f31993, + 0x56478827, 0x2aecfd4c, 0xba586cf8, 0x0985dd95, 0x99314c21, + 0x6f3ebe4e, 0xff8a2ffa, 0x4c579e97, 0xdce30f23, 0xb4017541, + 0x24b5e4f5, 0x97685598, 0x07dcc42c, 0xf1d33643, 0x6167a7f7, + 0xd2ba169a, 0x420e872e, 0x3ea5f245, 0xae1163f1, 0x1dccd29c, + 0x8d784328, 0x7b77b147, 0xebc320f3, 0x581e919e, 0xc8aa002a, + 0x88da645a, 0x186ef5ee, 0xabb34483, 0x3b07d537, 0xcd082758, + 0x5dbcb6ec, 0xee610781, 0x7ed59635, 0x027ee35e, 0x92ca72ea, + 0x2117c387, 0xb1a35233, 0x47aca05c, 0xd71831e8, 0x64c58085, + 0xf4711131, 0x9c936b53, 0x0c27fae7, 0xbffa4b8a, 0x2f4eda3e, + 0xd9412851, 0x49f5b9e5, 0xfa280888, 0x6a9c993c, 0x1637ec57, + 0x86837de3, 0x355ecc8e, 0xa5ea5d3a, 0x53e5af55, 0xc3513ee1, + 0x708c8f8c, 0xe0381e38, 0xf06c476c, 0x60d8d6d8, 0xd30567b5, + 0x43b1f601, 0xb5be046e, 0x250a95da, 0x96d724b7, 0x0663b503, + 0x7ac8c068, 0xea7c51dc, 0x59a1e0b1, 0xc9157105, 0x3f1a836a, + 0xafae12de, 0x1c73a3b3, 0x8cc73207, 0xe4254865, 0x7491d9d1, + 0xc74c68bc, 0x57f8f908, 0xa1f70b67, 0x31439ad3, 0x829e2bbe, + 0x122aba0a, 0x6e81cf61, 0xfe355ed5, 0x4de8efb8, 0xdd5c7e0c, + 0x2b538c63, 0xbbe71dd7, 0x083aacba, 0x988e3d0e, 0xd8fe597e, + 0x484ac8ca, 0xfb9779a7, 0x6b23e813, 0x9d2c1a7c, 0x0d988bc8, + 0xbe453aa5, 0x2ef1ab11, 0x525ade7a, 0xc2ee4fce, 0x7133fea3, + 0xe1876f17, 0x17889d78, 0x873c0ccc, 0x34e1bda1, 0xa4552c15, + 0xccb75677, 0x5c03c7c3, 0xefde76ae, 0x7f6ae71a, 0x89651575, + 0x19d184c1, 0xaa0c35ac, 0x3ab8a418, 0x4613d173, 0xd6a740c7, + 0x657af1aa, 0xf5ce601e, 0x03c19271, 0x937503c5, 0x20a8b2a8, + 0xb01c231c}, + {0x00000000, 0xb401b441, 0x68036883, 0xdc02dcc2, 0xd306d3b6, + 0x670767f7, 0xbb05bb35, 0x0f040f74, 0xa50da5dd, 0x110c119c, + 0xcd0ecd5e, 0x790f791f, 0x760b766b, 0xc20ac22a, 0x1e081ee8, + 0xaa09aaa9, 0x491b490b, 0xfd1afd4a, 0x21182188, 0x951995c9, + 0x9a1d9abd, 0x2e1c2efc, 0xf21ef23e, 0x461f467f, 0xec16ecd6, + 0x58175897, 0x84158455, 0x30143014, 0x3f103f60, 0x8b118b21, + 0x571357e3, 0xe312e3a2, 0x92369216, 0x26372657, 0xfa35fa95, + 0x4e344ed4, 0x413041a0, 0xf531f5e1, 0x29332923, 0x9d329d62, + 0x373b37cb, 0x833a838a, 0x5f385f48, 0xeb39eb09, 0xe43de47d, + 0x503c503c, 0x8c3e8cfe, 0x383f38bf, 0xdb2ddb1d, 0x6f2c6f5c, + 0xb32eb39e, 0x072f07df, 0x082b08ab, 0xbc2abcea, 0x60286028, + 0xd429d469, 0x7e207ec0, 0xca21ca81, 0x16231643, 0xa222a202, + 0xad26ad76, 0x19271937, 0xc525c5f5, 0x712471b4, 0x246d242d, + 0x906c906c, 0x4c6e4cae, 0xf86ff8ef, 0xf76bf79b, 0x436a43da, + 0x9f689f18, 0x2b692b59, 0x816081f0, 0x356135b1, 0xe963e973, + 0x5d625d32, 0x52665246, 0xe667e607, 0x3a653ac5, 0x8e648e84, + 0x6d766d26, 0xd977d967, 0x057505a5, 0xb174b1e4, 0xbe70be90, + 0x0a710ad1, 0xd673d613, 0x62726252, 0xc87bc8fb, 0x7c7a7cba, + 0xa078a078, 0x14791439, 0x1b7d1b4d, 0xaf7caf0c, 0x737e73ce, + 0xc77fc78f, 0xb65bb63b, 0x025a027a, 0xde58deb8, 0x6a596af9, + 0x655d658d, 0xd15cd1cc, 0x0d5e0d0e, 0xb95fb94f, 0x135613e6, + 0xa757a7a7, 0x7b557b65, 0xcf54cf24, 0xc050c050, 0x74517411, + 0xa853a8d3, 0x1c521c92, 0xff40ff30, 0x4b414b71, 0x974397b3, + 0x234223f2, 0x2c462c86, 0x984798c7, 0x44454405, 0xf044f044, + 0x5a4d5aed, 0xee4ceeac, 0x324e326e, 0x864f862f, 0x894b895b, + 0x3d4a3d1a, 0xe148e1d8, 0x55495599, 0x48da485a, 0xfcdbfc1b, + 0x20d920d9, 0x94d89498, 0x9bdc9bec, 0x2fdd2fad, 0xf3dff36f, + 0x47de472e, 0xedd7ed87, 0x59d659c6, 0x85d48504, 0x31d53145, + 0x3ed13e31, 0x8ad08a70, 0x56d256b2, 0xe2d3e2f3, 0x01c10151, + 0xb5c0b510, 0x69c269d2, 0xddc3dd93, 0xd2c7d2e7, 0x66c666a6, + 0xbac4ba64, 0x0ec50e25, 0xa4cca48c, 0x10cd10cd, 0xcccfcc0f, + 0x78ce784e, 0x77ca773a, 0xc3cbc37b, 0x1fc91fb9, 0xabc8abf8, + 0xdaecda4c, 0x6eed6e0d, 0xb2efb2cf, 0x06ee068e, 0x09ea09fa, + 0xbdebbdbb, 0x61e96179, 0xd5e8d538, 0x7fe17f91, 0xcbe0cbd0, + 0x17e21712, 0xa3e3a353, 0xace7ac27, 0x18e61866, 0xc4e4c4a4, + 0x70e570e5, 0x93f79347, 0x27f62706, 0xfbf4fbc4, 0x4ff54f85, + 0x40f140f1, 0xf4f0f4b0, 0x28f22872, 0x9cf39c33, 0x36fa369a, + 0x82fb82db, 0x5ef95e19, 0xeaf8ea58, 0xe5fce52c, 0x51fd516d, + 0x8dff8daf, 0x39fe39ee, 0x6cb76c77, 0xd8b6d836, 0x04b404f4, + 0xb0b5b0b5, 0xbfb1bfc1, 0x0bb00b80, 0xd7b2d742, 0x63b36303, + 0xc9bac9aa, 0x7dbb7deb, 0xa1b9a129, 0x15b81568, 0x1abc1a1c, + 0xaebdae5d, 0x72bf729f, 0xc6bec6de, 0x25ac257c, 0x91ad913d, + 0x4daf4dff, 0xf9aef9be, 0xf6aaf6ca, 0x42ab428b, 0x9ea99e49, + 0x2aa82a08, 0x80a180a1, 0x34a034e0, 0xe8a2e822, 0x5ca35c63, + 0x53a75317, 0xe7a6e756, 0x3ba43b94, 0x8fa58fd5, 0xfe81fe61, + 0x4a804a20, 0x968296e2, 0x228322a3, 0x2d872dd7, 0x99869996, + 0x45844554, 0xf185f115, 0x5b8c5bbc, 0xef8deffd, 0x338f333f, + 0x878e877e, 0x888a880a, 0x3c8b3c4b, 0xe089e089, 0x548854c8, + 0xb79ab76a, 0x039b032b, 0xdf99dfe9, 0x6b986ba8, 0x649c64dc, + 0xd09dd09d, 0x0c9f0c5f, 0xb89eb81e, 0x129712b7, 0xa696a6f6, + 0x7a947a34, 0xce95ce75, 0xc191c101, 0x75907540, 0xa992a982, + 0x1d931dc3}, + {0x00000000, 0x01000151, 0x020002a2, 0x030003f3, 0x070007f4, + 0x060006a5, 0x05000556, 0x04000407, 0x0d000d58, 0x0c000c09, + 0x0f000ffa, 0x0e000eab, 0x0a000aac, 0x0b000bfd, 0x0800080e, + 0x0900095f, 0x1a001ab0, 0x1b001be1, 0x18001812, 0x19001943, + 0x1d001d44, 0x1c001c15, 0x1f001fe6, 0x1e001eb7, 0x170017e8, + 0x160016b9, 0x1500154a, 0x1400141b, 0x1000101c, 0x1100114d, + 0x120012be, 0x130013ef, 0x370037d0, 0x36003681, 0x35003572, + 0x34003423, 0x30003024, 0x31003175, 0x32003286, 0x330033d7, + 0x3a003a88, 0x3b003bd9, 0x3800382a, 0x3900397b, 0x3d003d7c, + 0x3c003c2d, 0x3f003fde, 0x3e003e8f, 0x2d002d60, 0x2c002c31, + 0x2f002fc2, 0x2e002e93, 0x2a002a94, 0x2b002bc5, 0x28002836, + 0x29002967, 0x20002038, 0x21002169, 0x2200229a, 0x230023cb, + 0x270027cc, 0x2600269d, 0x2500256e, 0x2400243f, 0x6d006d10, + 0x6c006c41, 0x6f006fb2, 0x6e006ee3, 0x6a006ae4, 0x6b006bb5, + 0x68006846, 0x69006917, 0x60006048, 0x61006119, 0x620062ea, + 0x630063bb, 0x670067bc, 0x660066ed, 0x6500651e, 0x6400644f, + 0x770077a0, 0x760076f1, 0x75007502, 0x74007453, 0x70007054, + 0x71007105, 0x720072f6, 0x730073a7, 0x7a007af8, 0x7b007ba9, + 0x7800785a, 0x7900790b, 0x7d007d0c, 0x7c007c5d, 0x7f007fae, + 0x7e007eff, 0x5a005ac0, 0x5b005b91, 0x58005862, 0x59005933, + 0x5d005d34, 0x5c005c65, 0x5f005f96, 0x5e005ec7, 0x57005798, + 0x560056c9, 0x5500553a, 0x5400546b, 0x5000506c, 0x5100513d, + 0x520052ce, 0x5300539f, 0x40004070, 0x41004121, 0x420042d2, + 0x43004383, 0x47004784, 0x460046d5, 0x45004526, 0x44004477, + 0x4d004d28, 0x4c004c79, 0x4f004f8a, 0x4e004edb, 0x4a004adc, + 0x4b004b8d, 0x4800487e, 0x4900492f, 0xda00da20, 0xdb00db71, + 0xd800d882, 0xd900d9d3, 0xdd00ddd4, 0xdc00dc85, 0xdf00df76, + 0xde00de27, 0xd700d778, 0xd600d629, 0xd500d5da, 0xd400d48b, + 0xd000d08c, 0xd100d1dd, 0xd200d22e, 0xd300d37f, 0xc000c090, + 0xc100c1c1, 0xc200c232, 0xc300c363, 0xc700c764, 0xc600c635, + 0xc500c5c6, 0xc400c497, 0xcd00cdc8, 0xcc00cc99, 0xcf00cf6a, + 0xce00ce3b, 0xca00ca3c, 0xcb00cb6d, 0xc800c89e, 0xc900c9cf, + 0xed00edf0, 0xec00eca1, 0xef00ef52, 0xee00ee03, 0xea00ea04, + 0xeb00eb55, 0xe800e8a6, 0xe900e9f7, 0xe000e0a8, 0xe100e1f9, + 0xe200e20a, 0xe300e35b, 0xe700e75c, 0xe600e60d, 0xe500e5fe, + 0xe400e4af, 0xf700f740, 0xf600f611, 0xf500f5e2, 0xf400f4b3, + 0xf000f0b4, 0xf100f1e5, 0xf200f216, 0xf300f347, 0xfa00fa18, + 0xfb00fb49, 0xf800f8ba, 0xf900f9eb, 0xfd00fdec, 0xfc00fcbd, + 0xff00ff4e, 0xfe00fe1f, 0xb700b730, 0xb600b661, 0xb500b592, + 0xb400b4c3, 0xb000b0c4, 0xb100b195, 0xb200b266, 0xb300b337, + 0xba00ba68, 0xbb00bb39, 0xb800b8ca, 0xb900b99b, 0xbd00bd9c, + 0xbc00bccd, 0xbf00bf3e, 0xbe00be6f, 0xad00ad80, 0xac00acd1, + 0xaf00af22, 0xae00ae73, 0xaa00aa74, 0xab00ab25, 0xa800a8d6, + 0xa900a987, 0xa000a0d8, 0xa100a189, 0xa200a27a, 0xa300a32b, + 0xa700a72c, 0xa600a67d, 0xa500a58e, 0xa400a4df, 0x800080e0, + 0x810081b1, 0x82008242, 0x83008313, 0x87008714, 0x86008645, + 0x850085b6, 0x840084e7, 0x8d008db8, 0x8c008ce9, 0x8f008f1a, + 0x8e008e4b, 0x8a008a4c, 0x8b008b1d, 0x880088ee, 0x890089bf, + 0x9a009a50, 0x9b009b01, 0x980098f2, 0x990099a3, 0x9d009da4, + 0x9c009cf5, 0x9f009f06, 0x9e009e57, 0x97009708, 0x96009659, + 0x950095aa, 0x940094fb, 0x900090fc, 0x910091ad, 0x9200925e, + 0x9300930f}}; + +#endif + +#endif + +#if N == 4 + +#if W == 8 + +static const crc_t crc_braid_table[][256] = { + {0x00000000, 0xbd01c000, 0xca008003, 0x77014003, 0x24020005, + 0x9903c005, 0xee028006, 0x53034006, 0x4804000a, 0xf505c00a, + 0x82048009, 0x3f054009, 0x6c06000f, 0xd107c00f, 0xa606800c, + 0x1b07400c, 0x90080014, 0x2d09c014, 0x5a088017, 0xe7094017, + 0xb40a0011, 0x090bc011, 0x7e0a8012, 0xc30b4012, 0xd80c001e, + 0x650dc01e, 0x120c801d, 0xaf0d401d, 0xfc0e001b, 0x410fc01b, + 0x360e8018, 0x8b0f4018, 0x9013002b, 0x2d12c02b, 0x5a138028, + 0xe7124028, 0xb411002e, 0x0910c02e, 0x7e11802d, 0xc310402d, + 0xd8170021, 0x6516c021, 0x12178022, 0xaf164022, 0xfc150024, + 0x4114c024, 0x36158027, 0x8b144027, 0x001b003f, 0xbd1ac03f, + 0xca1b803c, 0x771a403c, 0x2419003a, 0x9918c03a, 0xee198039, + 0x53184039, 0x481f0035, 0xf51ec035, 0x821f8036, 0x3f1e4036, + 0x6c1d0030, 0xd11cc030, 0xa61d8033, 0x1b1c4033, 0x90250055, + 0x2d24c055, 0x5a258056, 0xe7244056, 0xb4270050, 0x0926c050, + 0x7e278053, 0xc3264053, 0xd821005f, 0x6520c05f, 0x1221805c, + 0xaf20405c, 0xfc23005a, 0x4122c05a, 0x36238059, 0x8b224059, + 0x002d0041, 0xbd2cc041, 0xca2d8042, 0x772c4042, 0x242f0044, + 0x992ec044, 0xee2f8047, 0x532e4047, 0x4829004b, 0xf528c04b, + 0x82298048, 0x3f284048, 0x6c2b004e, 0xd12ac04e, 0xa62b804d, + 0x1b2a404d, 0x0036007e, 0xbd37c07e, 0xca36807d, 0x7737407d, + 0x2434007b, 0x9935c07b, 0xee348078, 0x53354078, 0x48320074, + 0xf533c074, 0x82328077, 0x3f334077, 0x6c300071, 0xd131c071, + 0xa6308072, 0x1b314072, 0x903e006a, 0x2d3fc06a, 0x5a3e8069, + 0xe73f4069, 0xb43c006f, 0x093dc06f, 0x7e3c806c, 0xc33d406c, + 0xd83a0060, 0x653bc060, 0x123a8063, 0xaf3b4063, 0xfc380065, + 0x4139c065, 0x36388066, 0x8b394066, 0x904900a9, 0x2d48c0a9, + 0x5a4980aa, 0xe74840aa, 0xb44b00ac, 0x094ac0ac, 0x7e4b80af, + 0xc34a40af, 0xd84d00a3, 0x654cc0a3, 0x124d80a0, 0xaf4c40a0, + 0xfc4f00a6, 0x414ec0a6, 0x364f80a5, 0x8b4e40a5, 0x004100bd, + 0xbd40c0bd, 0xca4180be, 0x774040be, 0x244300b8, 0x9942c0b8, + 0xee4380bb, 0x534240bb, 0x484500b7, 0xf544c0b7, 0x824580b4, + 0x3f4440b4, 0x6c4700b2, 0xd146c0b2, 0xa64780b1, 0x1b4640b1, + 0x005a0082, 0xbd5bc082, 0xca5a8081, 0x775b4081, 0x24580087, + 0x9959c087, 0xee588084, 0x53594084, 0x485e0088, 0xf55fc088, + 0x825e808b, 0x3f5f408b, 0x6c5c008d, 0xd15dc08d, 0xa65c808e, + 0x1b5d408e, 0x90520096, 0x2d53c096, 0x5a528095, 0xe7534095, + 0xb4500093, 0x0951c093, 0x7e508090, 0xc3514090, 0xd856009c, + 0x6557c09c, 0x1256809f, 0xaf57409f, 0xfc540099, 0x4155c099, + 0x3654809a, 0x8b55409a, 0x006c00fc, 0xbd6dc0fc, 0xca6c80ff, + 0x776d40ff, 0x246e00f9, 0x996fc0f9, 0xee6e80fa, 0x536f40fa, + 0x486800f6, 0xf569c0f6, 0x826880f5, 0x3f6940f5, 0x6c6a00f3, + 0xd16bc0f3, 0xa66a80f0, 0x1b6b40f0, 0x906400e8, 0x2d65c0e8, + 0x5a6480eb, 0xe76540eb, 0xb46600ed, 0x0967c0ed, 0x7e6680ee, + 0xc36740ee, 0xd86000e2, 0x6561c0e2, 0x126080e1, 0xaf6140e1, + 0xfc6200e7, 0x4163c0e7, 0x366280e4, 0x8b6340e4, 0x907f00d7, + 0x2d7ec0d7, 0x5a7f80d4, 0xe77e40d4, 0xb47d00d2, 0x097cc0d2, + 0x7e7d80d1, 0xc37c40d1, 0xd87b00dd, 0x657ac0dd, 0x127b80de, + 0xaf7a40de, 0xfc7900d8, 0x4178c0d8, 0x367980db, 0x8b7840db, + 0x007700c3, 0xbd76c0c3, 0xca7780c0, 0x777640c0, 0x247500c6, + 0x9974c0c6, 0xee7580c5, 0x537440c5, 0x487300c9, 0xf572c0c9, + 0x827380ca, 0x3f7240ca, 0x6c7100cc, 0xd170c0cc, 0xa67180cf, + 0x1b7040cf}, + {0x00000000, 0x90910151, 0x912102a1, 0x01b003f0, 0x92410541, + 0x02d00410, 0x036007e0, 0x93f106b1, 0x94810a81, 0x04100bd0, + 0x05a00820, 0x95310971, 0x06c00fc0, 0x96510e91, 0x97e10d61, + 0x07700c30, 0x99011501, 0x09901450, 0x082017a0, 0x98b116f1, + 0x0b401040, 0x9bd11111, 0x9a6112e1, 0x0af013b0, 0x0d801f80, + 0x9d111ed1, 0x9ca11d21, 0x0c301c70, 0x9fc11ac1, 0x0f501b90, + 0x0ee01860, 0x9e711931, 0x82012a01, 0x12902b50, 0x132028a0, + 0x83b129f1, 0x10402f40, 0x80d12e11, 0x81612de1, 0x11f02cb0, + 0x16802080, 0x861121d1, 0x87a12221, 0x17302370, 0x84c125c1, + 0x14502490, 0x15e02760, 0x85712631, 0x1b003f00, 0x8b913e51, + 0x8a213da1, 0x1ab03cf0, 0x89413a41, 0x19d03b10, 0x186038e0, + 0x88f139b1, 0x8f813581, 0x1f1034d0, 0x1ea03720, 0x8e313671, + 0x1dc030c0, 0x8d513191, 0x8ce13261, 0x1c703330, 0xb4015401, + 0x24905550, 0x252056a0, 0xb5b157f1, 0x26405140, 0xb6d15011, + 0xb76153e1, 0x27f052b0, 0x20805e80, 0xb0115fd1, 0xb1a15c21, + 0x21305d70, 0xb2c15bc1, 0x22505a90, 0x23e05960, 0xb3715831, + 0x2d004100, 0xbd914051, 0xbc2143a1, 0x2cb042f0, 0xbf414441, + 0x2fd04510, 0x2e6046e0, 0xbef147b1, 0xb9814b81, 0x29104ad0, + 0x28a04920, 0xb8314871, 0x2bc04ec0, 0xbb514f91, 0xbae14c61, + 0x2a704d30, 0x36007e00, 0xa6917f51, 0xa7217ca1, 0x37b07df0, + 0xa4417b41, 0x34d07a10, 0x356079e0, 0xa5f178b1, 0xa2817481, + 0x321075d0, 0x33a07620, 0xa3317771, 0x30c071c0, 0xa0517091, + 0xa1e17361, 0x31707230, 0xaf016b01, 0x3f906a50, 0x3e2069a0, + 0xaeb168f1, 0x3d406e40, 0xadd16f11, 0xac616ce1, 0x3cf06db0, + 0x3b806180, 0xab1160d1, 0xaaa16321, 0x3a306270, 0xa9c164c1, + 0x39506590, 0x38e06660, 0xa8716731, 0xd801a801, 0x4890a950, + 0x4920aaa0, 0xd9b1abf1, 0x4a40ad40, 0xdad1ac11, 0xdb61afe1, + 0x4bf0aeb0, 0x4c80a280, 0xdc11a3d1, 0xdda1a021, 0x4d30a170, + 0xdec1a7c1, 0x4e50a690, 0x4fe0a560, 0xdf71a431, 0x4100bd00, + 0xd191bc51, 0xd021bfa1, 0x40b0bef0, 0xd341b841, 0x43d0b910, + 0x4260bae0, 0xd2f1bbb1, 0xd581b781, 0x4510b6d0, 0x44a0b520, + 0xd431b471, 0x47c0b2c0, 0xd751b391, 0xd6e1b061, 0x4670b130, + 0x5a008200, 0xca918351, 0xcb2180a1, 0x5bb081f0, 0xc8418741, + 0x58d08610, 0x596085e0, 0xc9f184b1, 0xce818881, 0x5e1089d0, + 0x5fa08a20, 0xcf318b71, 0x5cc08dc0, 0xcc518c91, 0xcde18f61, + 0x5d708e30, 0xc3019701, 0x53909650, 0x522095a0, 0xc2b194f1, + 0x51409240, 0xc1d19311, 0xc06190e1, 0x50f091b0, 0x57809d80, + 0xc7119cd1, 0xc6a19f21, 0x56309e70, 0xc5c198c1, 0x55509990, + 0x54e09a60, 0xc4719b31, 0x6c00fc00, 0xfc91fd51, 0xfd21fea1, + 0x6db0fff0, 0xfe41f941, 0x6ed0f810, 0x6f60fbe0, 0xfff1fab1, + 0xf881f681, 0x6810f7d0, 0x69a0f420, 0xf931f571, 0x6ac0f3c0, + 0xfa51f291, 0xfbe1f161, 0x6b70f030, 0xf501e901, 0x6590e850, + 0x6420eba0, 0xf4b1eaf1, 0x6740ec40, 0xf7d1ed11, 0xf661eee1, + 0x66f0efb0, 0x6180e380, 0xf111e2d1, 0xf0a1e121, 0x6030e070, + 0xf3c1e6c1, 0x6350e790, 0x62e0e460, 0xf271e531, 0xee01d601, + 0x7e90d750, 0x7f20d4a0, 0xefb1d5f1, 0x7c40d340, 0xecd1d211, + 0xed61d1e1, 0x7df0d0b0, 0x7a80dc80, 0xea11ddd1, 0xeba1de21, + 0x7b30df70, 0xe8c1d9c1, 0x7850d890, 0x79e0db60, 0xe971da31, + 0x7700c300, 0xe791c251, 0xe621c1a1, 0x76b0c0f0, 0xe541c641, + 0x75d0c710, 0x7460c4e0, 0xe4f1c5b1, 0xe381c981, 0x7310c8d0, + 0x72a0cb20, 0xe231ca71, 0x71c0ccc0, 0xe151cd91, 0xe0e1ce61, + 0x7070cf30}, + {0x00000000, 0x00005001, 0x0000a002, 0x0000f003, 0x00014004, + 0x00011005, 0x0001e006, 0x0001b007, 0x00028008, 0x0002d009, + 0x0002200a, 0x0002700b, 0x0003c00c, 0x0003900d, 0x0003600e, + 0x0003300f, 0x00050010, 0x00055011, 0x0005a012, 0x0005f013, + 0x00044014, 0x00041015, 0x0004e016, 0x0004b017, 0x00078018, + 0x0007d019, 0x0007201a, 0x0007701b, 0x0006c01c, 0x0006901d, + 0x0006601e, 0x0006301f, 0x000a0020, 0x000a5021, 0x000aa022, + 0x000af023, 0x000b4024, 0x000b1025, 0x000be026, 0x000bb027, + 0x00088028, 0x0008d029, 0x0008202a, 0x0008702b, 0x0009c02c, + 0x0009902d, 0x0009602e, 0x0009302f, 0x000f0030, 0x000f5031, + 0x000fa032, 0x000ff033, 0x000e4034, 0x000e1035, 0x000ee036, + 0x000eb037, 0x000d8038, 0x000dd039, 0x000d203a, 0x000d703b, + 0x000cc03c, 0x000c903d, 0x000c603e, 0x000c303f, 0x00140040, + 0x00145041, 0x0014a042, 0x0014f043, 0x00154044, 0x00151045, + 0x0015e046, 0x0015b047, 0x00168048, 0x0016d049, 0x0016204a, + 0x0016704b, 0x0017c04c, 0x0017904d, 0x0017604e, 0x0017304f, + 0x00110050, 0x00115051, 0x0011a052, 0x0011f053, 0x00104054, + 0x00101055, 0x0010e056, 0x0010b057, 0x00138058, 0x0013d059, + 0x0013205a, 0x0013705b, 0x0012c05c, 0x0012905d, 0x0012605e, + 0x0012305f, 0x001e0060, 0x001e5061, 0x001ea062, 0x001ef063, + 0x001f4064, 0x001f1065, 0x001fe066, 0x001fb067, 0x001c8068, + 0x001cd069, 0x001c206a, 0x001c706b, 0x001dc06c, 0x001d906d, + 0x001d606e, 0x001d306f, 0x001b0070, 0x001b5071, 0x001ba072, + 0x001bf073, 0x001a4074, 0x001a1075, 0x001ae076, 0x001ab077, + 0x00198078, 0x0019d079, 0x0019207a, 0x0019707b, 0x0018c07c, + 0x0018907d, 0x0018607e, 0x0018307f, 0x00280080, 0x00285081, + 0x0028a082, 0x0028f083, 0x00294084, 0x00291085, 0x0029e086, + 0x0029b087, 0x002a8088, 0x002ad089, 0x002a208a, 0x002a708b, + 0x002bc08c, 0x002b908d, 0x002b608e, 0x002b308f, 0x002d0090, + 0x002d5091, 0x002da092, 0x002df093, 0x002c4094, 0x002c1095, + 0x002ce096, 0x002cb097, 0x002f8098, 0x002fd099, 0x002f209a, + 0x002f709b, 0x002ec09c, 0x002e909d, 0x002e609e, 0x002e309f, + 0x002200a0, 0x002250a1, 0x0022a0a2, 0x0022f0a3, 0x002340a4, + 0x002310a5, 0x0023e0a6, 0x0023b0a7, 0x002080a8, 0x0020d0a9, + 0x002020aa, 0x002070ab, 0x0021c0ac, 0x002190ad, 0x002160ae, + 0x002130af, 0x002700b0, 0x002750b1, 0x0027a0b2, 0x0027f0b3, + 0x002640b4, 0x002610b5, 0x0026e0b6, 0x0026b0b7, 0x002580b8, + 0x0025d0b9, 0x002520ba, 0x002570bb, 0x0024c0bc, 0x002490bd, + 0x002460be, 0x002430bf, 0x003c00c0, 0x003c50c1, 0x003ca0c2, + 0x003cf0c3, 0x003d40c4, 0x003d10c5, 0x003de0c6, 0x003db0c7, + 0x003e80c8, 0x003ed0c9, 0x003e20ca, 0x003e70cb, 0x003fc0cc, + 0x003f90cd, 0x003f60ce, 0x003f30cf, 0x003900d0, 0x003950d1, + 0x0039a0d2, 0x0039f0d3, 0x003840d4, 0x003810d5, 0x0038e0d6, + 0x0038b0d7, 0x003b80d8, 0x003bd0d9, 0x003b20da, 0x003b70db, + 0x003ac0dc, 0x003a90dd, 0x003a60de, 0x003a30df, 0x003600e0, + 0x003650e1, 0x0036a0e2, 0x0036f0e3, 0x003740e4, 0x003710e5, + 0x0037e0e6, 0x0037b0e7, 0x003480e8, 0x0034d0e9, 0x003420ea, + 0x003470eb, 0x0035c0ec, 0x003590ed, 0x003560ee, 0x003530ef, + 0x003300f0, 0x003350f1, 0x0033a0f2, 0x0033f0f3, 0x003240f4, + 0x003210f5, 0x0032e0f6, 0x0032b0f7, 0x003180f8, 0x0031d0f9, + 0x003120fa, 0x003170fb, 0x0030c0fc, 0x003090fd, 0x003060fe, + 0x003030ff}, + {0x00000000, 0x00500100, 0x00a00200, 0x00f00300, 0x01400400, + 0x01100500, 0x01e00600, 0x01b00700, 0x02800800, 0x02d00900, + 0x02200a00, 0x02700b00, 0x03c00c00, 0x03900d00, 0x03600e00, + 0x03300f00, 0x05001000, 0x05501100, 0x05a01200, 0x05f01300, + 0x04401400, 0x04101500, 0x04e01600, 0x04b01700, 0x07801800, + 0x07d01900, 0x07201a00, 0x07701b00, 0x06c01c00, 0x06901d00, + 0x06601e00, 0x06301f00, 0x0a002000, 0x0a502100, 0x0aa02200, + 0x0af02300, 0x0b402400, 0x0b102500, 0x0be02600, 0x0bb02700, + 0x08802800, 0x08d02900, 0x08202a00, 0x08702b00, 0x09c02c00, + 0x09902d00, 0x09602e00, 0x09302f00, 0x0f003000, 0x0f503100, + 0x0fa03200, 0x0ff03300, 0x0e403400, 0x0e103500, 0x0ee03600, + 0x0eb03700, 0x0d803800, 0x0dd03900, 0x0d203a00, 0x0d703b00, + 0x0cc03c00, 0x0c903d00, 0x0c603e00, 0x0c303f00, 0x14004000, + 0x14504100, 0x14a04200, 0x14f04300, 0x15404400, 0x15104500, + 0x15e04600, 0x15b04700, 0x16804800, 0x16d04900, 0x16204a00, + 0x16704b00, 0x17c04c00, 0x17904d00, 0x17604e00, 0x17304f00, + 0x11005000, 0x11505100, 0x11a05200, 0x11f05300, 0x10405400, + 0x10105500, 0x10e05600, 0x10b05700, 0x13805800, 0x13d05900, + 0x13205a00, 0x13705b00, 0x12c05c00, 0x12905d00, 0x12605e00, + 0x12305f00, 0x1e006000, 0x1e506100, 0x1ea06200, 0x1ef06300, + 0x1f406400, 0x1f106500, 0x1fe06600, 0x1fb06700, 0x1c806800, + 0x1cd06900, 0x1c206a00, 0x1c706b00, 0x1dc06c00, 0x1d906d00, + 0x1d606e00, 0x1d306f00, 0x1b007000, 0x1b507100, 0x1ba07200, + 0x1bf07300, 0x1a407400, 0x1a107500, 0x1ae07600, 0x1ab07700, + 0x19807800, 0x19d07900, 0x19207a00, 0x19707b00, 0x18c07c00, + 0x18907d00, 0x18607e00, 0x18307f00, 0x28008000, 0x28508100, + 0x28a08200, 0x28f08300, 0x29408400, 0x29108500, 0x29e08600, + 0x29b08700, 0x2a808800, 0x2ad08900, 0x2a208a00, 0x2a708b00, + 0x2bc08c00, 0x2b908d00, 0x2b608e00, 0x2b308f00, 0x2d009000, + 0x2d509100, 0x2da09200, 0x2df09300, 0x2c409400, 0x2c109500, + 0x2ce09600, 0x2cb09700, 0x2f809800, 0x2fd09900, 0x2f209a00, + 0x2f709b00, 0x2ec09c00, 0x2e909d00, 0x2e609e00, 0x2e309f00, + 0x2200a000, 0x2250a100, 0x22a0a200, 0x22f0a300, 0x2340a400, + 0x2310a500, 0x23e0a600, 0x23b0a700, 0x2080a800, 0x20d0a900, + 0x2020aa00, 0x2070ab00, 0x21c0ac00, 0x2190ad00, 0x2160ae00, + 0x2130af00, 0x2700b000, 0x2750b100, 0x27a0b200, 0x27f0b300, + 0x2640b400, 0x2610b500, 0x26e0b600, 0x26b0b700, 0x2580b800, + 0x25d0b900, 0x2520ba00, 0x2570bb00, 0x24c0bc00, 0x2490bd00, + 0x2460be00, 0x2430bf00, 0x3c00c000, 0x3c50c100, 0x3ca0c200, + 0x3cf0c300, 0x3d40c400, 0x3d10c500, 0x3de0c600, 0x3db0c700, + 0x3e80c800, 0x3ed0c900, 0x3e20ca00, 0x3e70cb00, 0x3fc0cc00, + 0x3f90cd00, 0x3f60ce00, 0x3f30cf00, 0x3900d000, 0x3950d100, + 0x39a0d200, 0x39f0d300, 0x3840d400, 0x3810d500, 0x38e0d600, + 0x38b0d700, 0x3b80d800, 0x3bd0d900, 0x3b20da00, 0x3b70db00, + 0x3ac0dc00, 0x3a90dd00, 0x3a60de00, 0x3a30df00, 0x3600e000, + 0x3650e100, 0x36a0e200, 0x36f0e300, 0x3740e400, 0x3710e500, + 0x37e0e600, 0x37b0e700, 0x3480e800, 0x34d0e900, 0x3420ea00, + 0x3470eb00, 0x35c0ec00, 0x3590ed00, 0x3560ee00, 0x3530ef00, + 0x3300f000, 0x3350f100, 0x33a0f200, 0x33f0f300, 0x3240f400, + 0x3210f500, 0x32e0f600, 0x32b0f700, 0x3180f800, 0x31d0f900, + 0x3120fa00, 0x3170fb00, 0x30c0fc00, 0x3090fd00, 0x3060fe00, + 0x3030ff00}, + {0x00000000, 0x50010000, 0xa0020000, 0xf0030000, 0xf0070003, + 0xa0060003, 0x50050003, 0x00040003, 0x500d0005, 0x000c0005, + 0xf00f0005, 0xa00e0005, 0xa00a0006, 0xf00b0006, 0x00080006, + 0x50090006, 0xa01a000a, 0xf01b000a, 0x0018000a, 0x5019000a, + 0x501d0009, 0x001c0009, 0xf01f0009, 0xa01e0009, 0xf017000f, + 0xa016000f, 0x5015000f, 0x0014000f, 0x0010000c, 0x5011000c, + 0xa012000c, 0xf013000c, 0xf0370017, 0xa0360017, 0x50350017, + 0x00340017, 0x00300014, 0x50310014, 0xa0320014, 0xf0330014, + 0xa03a0012, 0xf03b0012, 0x00380012, 0x50390012, 0x503d0011, + 0x003c0011, 0xf03f0011, 0xa03e0011, 0x502d001d, 0x002c001d, + 0xf02f001d, 0xa02e001d, 0xa02a001e, 0xf02b001e, 0x0028001e, + 0x5029001e, 0x00200018, 0x50210018, 0xa0220018, 0xf0230018, + 0xf027001b, 0xa026001b, 0x5025001b, 0x0024001b, 0x506d002d, + 0x006c002d, 0xf06f002d, 0xa06e002d, 0xa06a002e, 0xf06b002e, + 0x0068002e, 0x5069002e, 0x00600028, 0x50610028, 0xa0620028, + 0xf0630028, 0xf067002b, 0xa066002b, 0x5065002b, 0x0064002b, + 0xf0770027, 0xa0760027, 0x50750027, 0x00740027, 0x00700024, + 0x50710024, 0xa0720024, 0xf0730024, 0xa07a0022, 0xf07b0022, + 0x00780022, 0x50790022, 0x507d0021, 0x007c0021, 0xf07f0021, + 0xa07e0021, 0xa05a003a, 0xf05b003a, 0x0058003a, 0x5059003a, + 0x505d0039, 0x005c0039, 0xf05f0039, 0xa05e0039, 0xf057003f, + 0xa056003f, 0x5055003f, 0x0054003f, 0x0050003c, 0x5051003c, + 0xa052003c, 0xf053003c, 0x00400030, 0x50410030, 0xa0420030, + 0xf0430030, 0xf0470033, 0xa0460033, 0x50450033, 0x00440033, + 0x504d0035, 0x004c0035, 0xf04f0035, 0xa04e0035, 0xa04a0036, + 0xf04b0036, 0x00480036, 0x50490036, 0xa0da005a, 0xf0db005a, + 0x00d8005a, 0x50d9005a, 0x50dd0059, 0x00dc0059, 0xf0df0059, + 0xa0de0059, 0xf0d7005f, 0xa0d6005f, 0x50d5005f, 0x00d4005f, + 0x00d0005c, 0x50d1005c, 0xa0d2005c, 0xf0d3005c, 0x00c00050, + 0x50c10050, 0xa0c20050, 0xf0c30050, 0xf0c70053, 0xa0c60053, + 0x50c50053, 0x00c40053, 0x50cd0055, 0x00cc0055, 0xf0cf0055, + 0xa0ce0055, 0xa0ca0056, 0xf0cb0056, 0x00c80056, 0x50c90056, + 0x50ed004d, 0x00ec004d, 0xf0ef004d, 0xa0ee004d, 0xa0ea004e, + 0xf0eb004e, 0x00e8004e, 0x50e9004e, 0x00e00048, 0x50e10048, + 0xa0e20048, 0xf0e30048, 0xf0e7004b, 0xa0e6004b, 0x50e5004b, + 0x00e4004b, 0xf0f70047, 0xa0f60047, 0x50f50047, 0x00f40047, + 0x00f00044, 0x50f10044, 0xa0f20044, 0xf0f30044, 0xa0fa0042, + 0xf0fb0042, 0x00f80042, 0x50f90042, 0x50fd0041, 0x00fc0041, + 0xf0ff0041, 0xa0fe0041, 0xf0b70077, 0xa0b60077, 0x50b50077, + 0x00b40077, 0x00b00074, 0x50b10074, 0xa0b20074, 0xf0b30074, + 0xa0ba0072, 0xf0bb0072, 0x00b80072, 0x50b90072, 0x50bd0071, + 0x00bc0071, 0xf0bf0071, 0xa0be0071, 0x50ad007d, 0x00ac007d, + 0xf0af007d, 0xa0ae007d, 0xa0aa007e, 0xf0ab007e, 0x00a8007e, + 0x50a9007e, 0x00a00078, 0x50a10078, 0xa0a20078, 0xf0a30078, + 0xf0a7007b, 0xa0a6007b, 0x50a5007b, 0x00a4007b, 0x00800060, + 0x50810060, 0xa0820060, 0xf0830060, 0xf0870063, 0xa0860063, + 0x50850063, 0x00840063, 0x508d0065, 0x008c0065, 0xf08f0065, + 0xa08e0065, 0xa08a0066, 0xf08b0066, 0x00880066, 0x50890066, + 0xa09a006a, 0xf09b006a, 0x0098006a, 0x5099006a, 0x509d0069, + 0x009c0069, 0xf09f0069, 0xa09e0069, 0xf097006f, 0xa096006f, + 0x5095006f, 0x0094006f, 0x0090006c, 0x5091006c, 0xa092006c, + 0xf093006c}, + {0x00000000, 0xf1b700b7, 0x536d016d, 0xa2da01da, 0xa6da02da, + 0x576d026d, 0xf5b703b7, 0x04000300, 0xfdb705b7, 0x0c000500, + 0xaeda04da, 0x5f6d046d, 0x5b6d076d, 0xaada07da, 0x08000600, + 0xf9b706b7, 0x4b6d0b6d, 0xbada0bda, 0x18000a00, 0xe9b70ab7, + 0xedb709b7, 0x1c000900, 0xbeda08da, 0x4f6d086d, 0xb6da0eda, + 0x476d0e6d, 0xe5b70fb7, 0x14000f00, 0x10000c00, 0xe1b70cb7, + 0x436d0d6d, 0xb2da0dda, 0x96da16da, 0x676d166d, 0xc5b717b7, + 0x34001700, 0x30001400, 0xc1b714b7, 0x636d156d, 0x92da15da, + 0x6b6d136d, 0x9ada13da, 0x38001200, 0xc9b712b7, 0xcdb711b7, + 0x3c001100, 0x9eda10da, 0x6f6d106d, 0xddb71db7, 0x2c001d00, + 0x8eda1cda, 0x7f6d1c6d, 0x7b6d1f6d, 0x8ada1fda, 0x28001e00, + 0xd9b71eb7, 0x20001800, 0xd1b718b7, 0x736d196d, 0x82da19da, + 0x86da1ada, 0x776d1a6d, 0xd5b71bb7, 0x24001b00, 0x9db72db7, + 0x6c002d00, 0xceda2cda, 0x3f6d2c6d, 0x3b6d2f6d, 0xcada2fda, + 0x68002e00, 0x99b72eb7, 0x60002800, 0x91b728b7, 0x336d296d, + 0xc2da29da, 0xc6da2ada, 0x376d2a6d, 0x95b72bb7, 0x64002b00, + 0xd6da26da, 0x276d266d, 0x85b727b7, 0x74002700, 0x70002400, + 0x81b724b7, 0x236d256d, 0xd2da25da, 0x2b6d236d, 0xdada23da, + 0x78002200, 0x89b722b7, 0x8db721b7, 0x7c002100, 0xdeda20da, + 0x2f6d206d, 0x0b6d3b6d, 0xfada3bda, 0x58003a00, 0xa9b73ab7, + 0xadb739b7, 0x5c003900, 0xfeda38da, 0x0f6d386d, 0xf6da3eda, + 0x076d3e6d, 0xa5b73fb7, 0x54003f00, 0x50003c00, 0xa1b73cb7, + 0x036d3d6d, 0xf2da3dda, 0x40003000, 0xb1b730b7, 0x136d316d, + 0xe2da31da, 0xe6da32da, 0x176d326d, 0xb5b733b7, 0x44003300, + 0xbdb735b7, 0x4c003500, 0xeeda34da, 0x1f6d346d, 0x1b6d376d, + 0xeada37da, 0x48003600, 0xb9b736b7, 0x8b6d5b6d, 0x7ada5bda, + 0xd8005a00, 0x29b75ab7, 0x2db759b7, 0xdc005900, 0x7eda58da, + 0x8f6d586d, 0x76da5eda, 0x876d5e6d, 0x25b75fb7, 0xd4005f00, + 0xd0005c00, 0x21b75cb7, 0x836d5d6d, 0x72da5dda, 0xc0005000, + 0x31b750b7, 0x936d516d, 0x62da51da, 0x66da52da, 0x976d526d, + 0x35b753b7, 0xc4005300, 0x3db755b7, 0xcc005500, 0x6eda54da, + 0x9f6d546d, 0x9b6d576d, 0x6ada57da, 0xc8005600, 0x39b756b7, + 0x1db74db7, 0xec004d00, 0x4eda4cda, 0xbf6d4c6d, 0xbb6d4f6d, + 0x4ada4fda, 0xe8004e00, 0x19b74eb7, 0xe0004800, 0x11b748b7, + 0xb36d496d, 0x42da49da, 0x46da4ada, 0xb76d4a6d, 0x15b74bb7, + 0xe4004b00, 0x56da46da, 0xa76d466d, 0x05b747b7, 0xf4004700, + 0xf0004400, 0x01b744b7, 0xa36d456d, 0x52da45da, 0xab6d436d, + 0x5ada43da, 0xf8004200, 0x09b742b7, 0x0db741b7, 0xfc004100, + 0x5eda40da, 0xaf6d406d, 0x16da76da, 0xe76d766d, 0x45b777b7, + 0xb4007700, 0xb0007400, 0x41b774b7, 0xe36d756d, 0x12da75da, + 0xeb6d736d, 0x1ada73da, 0xb8007200, 0x49b772b7, 0x4db771b7, + 0xbc007100, 0x1eda70da, 0xef6d706d, 0x5db77db7, 0xac007d00, + 0x0eda7cda, 0xff6d7c6d, 0xfb6d7f6d, 0x0ada7fda, 0xa8007e00, + 0x59b77eb7, 0xa0007800, 0x51b778b7, 0xf36d796d, 0x02da79da, + 0x06da7ada, 0xf76d7a6d, 0x55b77bb7, 0xa4007b00, 0x80006000, + 0x71b760b7, 0xd36d616d, 0x22da61da, 0x26da62da, 0xd76d626d, + 0x75b763b7, 0x84006300, 0x7db765b7, 0x8c006500, 0x2eda64da, + 0xdf6d646d, 0xdb6d676d, 0x2ada67da, 0x88006600, 0x79b766b7, + 0xcb6d6b6d, 0x3ada6bda, 0x98006a00, 0x69b76ab7, 0x6db769b7, + 0x9c006900, 0x3eda68da, 0xcf6d686d, 0x36da6eda, 0xc76d6e6d, + 0x65b76fb7, 0x94006f00, 0x90006c00, 0x61b76cb7, 0xc36d6d6d, + 0x32da6dda}, + {0x00000000, 0xa6d9b6d9, 0xfdb06db1, 0x5b69db68, 0x4b63db61, + 0xedba6db8, 0xb6d3b6d0, 0x100a0009, 0x96c7b6c2, 0x301e001b, + 0x6b77db73, 0xcdae6daa, 0xdda46da3, 0x7b7ddb7a, 0x20140012, + 0x86cdb6cb, 0x9d8c6d87, 0x3b55db5e, 0x603c0036, 0xc6e5b6ef, + 0xd6efb6e6, 0x7036003f, 0x2b5fdb57, 0x8d866d8e, 0x0b4bdb45, + 0xad926d9c, 0xf6fbb6f4, 0x5022002d, 0x40280024, 0xe6f1b6fd, + 0xbd986d95, 0x1b41db4c, 0x8b1bdb0d, 0x2dc26dd4, 0x76abb6bc, + 0xd0720065, 0xc078006c, 0x66a1b6b5, 0x3dc86ddd, 0x9b11db04, + 0x1ddc6dcf, 0xbb05db16, 0xe06c007e, 0x46b5b6a7, 0x56bfb6ae, + 0xf0660077, 0xab0fdb1f, 0x0dd66dc6, 0x1697b68a, 0xb04e0053, + 0xeb27db3b, 0x4dfe6de2, 0x5df46deb, 0xfb2ddb32, 0xa044005a, + 0x069db683, 0x80500048, 0x2689b691, 0x7de06df9, 0xdb39db20, + 0xcb33db29, 0x6dea6df0, 0x3683b698, 0x905a0041, 0xa634b619, + 0x00ed00c0, 0x5b84dba8, 0xfd5d6d71, 0xed576d78, 0x4b8edba1, + 0x10e700c9, 0xb63eb610, 0x30f300db, 0x962ab602, 0xcd436d6a, + 0x6b9adbb3, 0x7b90dbba, 0xdd496d63, 0x8620b60b, 0x20f900d2, + 0x3bb8db9e, 0x9d616d47, 0xc608b62f, 0x60d100f6, 0x70db00ff, + 0xd602b626, 0x8d6b6d4e, 0x2bb2db97, 0xad7f6d5c, 0x0ba6db85, + 0x50cf00ed, 0xf616b634, 0xe61cb63d, 0x40c500e4, 0x1bacdb8c, + 0xbd756d55, 0x2d2f6d14, 0x8bf6dbcd, 0xd09f00a5, 0x7646b67c, + 0x664cb675, 0xc09500ac, 0x9bfcdbc4, 0x3d256d1d, 0xbbe8dbd6, + 0x1d316d0f, 0x4658b667, 0xe08100be, 0xf08b00b7, 0x5652b66e, + 0x0d3b6d06, 0xabe2dbdf, 0xb0a30093, 0x167ab64a, 0x4d136d22, + 0xebcadbfb, 0xfbc0dbf2, 0x5d196d2b, 0x0670b643, 0xa0a9009a, + 0x2664b651, 0x80bd0088, 0xdbd4dbe0, 0x7d0d6d39, 0x6d076d30, + 0xcbdedbe9, 0x90b70081, 0x366eb658, 0xfc6a6c31, 0x5ab3dae8, + 0x01da0180, 0xa703b759, 0xb709b750, 0x11d00189, 0x4ab9dae1, + 0xec606c38, 0x6aaddaf3, 0xcc746c2a, 0x971db742, 0x31c4019b, + 0x21ce0192, 0x8717b74b, 0xdc7e6c23, 0x7aa7dafa, 0x61e601b6, + 0xc73fb76f, 0x9c566c07, 0x3a8fdade, 0x2a85dad7, 0x8c5c6c0e, + 0xd735b766, 0x71ec01bf, 0xf721b774, 0x51f801ad, 0x0a91dac5, + 0xac486c1c, 0xbc426c15, 0x1a9bdacc, 0x41f201a4, 0xe72bb77d, + 0x7771b73c, 0xd1a801e5, 0x8ac1da8d, 0x2c186c54, 0x3c126c5d, + 0x9acbda84, 0xc1a201ec, 0x677bb735, 0xe1b601fe, 0x476fb727, + 0x1c066c4f, 0xbadfda96, 0xaad5da9f, 0x0c0c6c46, 0x5765b72e, + 0xf1bc01f7, 0xeafddabb, 0x4c246c62, 0x174db70a, 0xb19401d3, + 0xa19e01da, 0x0747b703, 0x5c2e6c6b, 0xfaf7dab2, 0x7c3a6c79, + 0xdae3daa0, 0x818a01c8, 0x2753b711, 0x3759b718, 0x918001c1, + 0xcae9daa9, 0x6c306c70, 0x5a5eda28, 0xfc876cf1, 0xa7eeb799, + 0x01370140, 0x113d0149, 0xb7e4b790, 0xec8d6cf8, 0x4a54da21, + 0xcc996cea, 0x6a40da33, 0x3129015b, 0x97f0b782, 0x87fab78b, + 0x21230152, 0x7a4ada3a, 0xdc936ce3, 0xc7d2b7af, 0x610b0176, + 0x3a62da1e, 0x9cbb6cc7, 0x8cb16cce, 0x2a68da17, 0x7101017f, + 0xd7d8b7a6, 0x5115016d, 0xf7ccb7b4, 0xaca56cdc, 0x0a7cda05, + 0x1a76da0c, 0xbcaf6cd5, 0xe7c6b7bd, 0x411f0164, 0xd1450125, + 0x779cb7fc, 0x2cf56c94, 0x8a2cda4d, 0x9a26da44, 0x3cff6c9d, + 0x6796b7f5, 0xc14f012c, 0x4782b7e7, 0xe15b013e, 0xba32da56, + 0x1ceb6c8f, 0x0ce16c86, 0xaa38da5f, 0xf1510137, 0x5788b7ee, + 0x4cc96ca2, 0xea10da7b, 0xb1790113, 0x17a0b7ca, 0x07aab7c3, + 0xa173011a, 0xfa1ada72, 0x5cc36cab, 0xda0eda60, 0x7cd76cb9, + 0x27beb7d1, 0x81670108, 0x916d0101, 0x37b4b7d8, 0x6cdd6cb0, + 0xca04da69}, + {0x00000000, 0x48d7d861, 0x91afb0c2, 0xd97868a3, 0x935c6187, + 0xdb8bb9e6, 0x02f3d145, 0x4a240924, 0x96bbc30d, 0xde6c1b6c, + 0x071473cf, 0x4fc3abae, 0x05e7a28a, 0x4d307aeb, 0x94481248, + 0xdc9fca29, 0x9d748619, 0xd5a35e78, 0x0cdb36db, 0x440ceeba, + 0x0e28e79e, 0x46ff3fff, 0x9f87575c, 0xd7508f3d, 0x0bcf4514, + 0x43189d75, 0x9a60f5d6, 0xd2b72db7, 0x98932493, 0xd044fcf2, + 0x093c9451, 0x41eb4c30, 0x8aea0c31, 0xc23dd450, 0x1b45bcf3, + 0x53926492, 0x19b66db6, 0x5161b5d7, 0x8819dd74, 0xc0ce0515, + 0x1c51cf3c, 0x5486175d, 0x8dfe7ffe, 0xc529a79f, 0x8f0daebb, + 0xc7da76da, 0x1ea21e79, 0x5675c618, 0x179e8a28, 0x5f495249, + 0x86313aea, 0xcee6e28b, 0x84c2ebaf, 0xcc1533ce, 0x156d5b6d, + 0x5dba830c, 0x81254925, 0xc9f29144, 0x108af9e7, 0x585d2186, + 0x127928a2, 0x5aaef0c3, 0x83d69860, 0xcb014001, 0xa5d71861, + 0xed00c000, 0x3478a8a3, 0x7caf70c2, 0x368b79e6, 0x7e5ca187, + 0xa724c924, 0xeff31145, 0x336cdb6c, 0x7bbb030d, 0xa2c36bae, + 0xea14b3cf, 0xa030baeb, 0xe8e7628a, 0x319f0a29, 0x7948d248, + 0x38a39e78, 0x70744619, 0xa90c2eba, 0xe1dbf6db, 0xabffffff, + 0xe328279e, 0x3a504f3d, 0x7287975c, 0xae185d75, 0xe6cf8514, + 0x3fb7edb7, 0x776035d6, 0x3d443cf2, 0x7593e493, 0xaceb8c30, + 0xe43c5451, 0x2f3d1450, 0x67eacc31, 0xbe92a492, 0xf6457cf3, + 0xbc6175d7, 0xf4b6adb6, 0x2dcec515, 0x65191d74, 0xb986d75d, + 0xf1510f3c, 0x2829679f, 0x60febffe, 0x2adab6da, 0x620d6ebb, + 0xbb750618, 0xf3a2de79, 0xb2499249, 0xfa9e4a28, 0x23e6228b, + 0x6b31faea, 0x2115f3ce, 0x69c22baf, 0xb0ba430c, 0xf86d9b6d, + 0x24f25144, 0x6c258925, 0xb55de186, 0xfd8a39e7, 0xb7ae30c3, + 0xff79e8a2, 0x26018001, 0x6ed65860, 0xfbad30c1, 0xb37ae8a0, + 0x6a028003, 0x22d55862, 0x68f15146, 0x20268927, 0xf95ee184, + 0xb18939e5, 0x6d16f3cc, 0x25c12bad, 0xfcb9430e, 0xb46e9b6f, + 0xfe4a924b, 0xb69d4a2a, 0x6fe52289, 0x2732fae8, 0x66d9b6d8, + 0x2e0e6eb9, 0xf776061a, 0xbfa1de7b, 0xf585d75f, 0xbd520f3e, + 0x642a679d, 0x2cfdbffc, 0xf06275d5, 0xb8b5adb4, 0x61cdc517, + 0x291a1d76, 0x633e1452, 0x2be9cc33, 0xf291a490, 0xba467cf1, + 0x71473cf0, 0x3990e491, 0xe0e88c32, 0xa83f5453, 0xe21b5d77, + 0xaacc8516, 0x73b4edb5, 0x3b6335d4, 0xe7fcfffd, 0xaf2b279c, + 0x76534f3f, 0x3e84975e, 0x74a09e7a, 0x3c77461b, 0xe50f2eb8, + 0xadd8f6d9, 0xec33bae9, 0xa4e46288, 0x7d9c0a2b, 0x354bd24a, + 0x7f6fdb6e, 0x37b8030f, 0xeec06bac, 0xa617b3cd, 0x7a8879e4, + 0x325fa185, 0xeb27c926, 0xa3f01147, 0xe9d41863, 0xa103c002, + 0x787ba8a1, 0x30ac70c0, 0x5e7a28a0, 0x16adf0c1, 0xcfd59862, + 0x87024003, 0xcd264927, 0x85f19146, 0x5c89f9e5, 0x145e2184, + 0xc8c1ebad, 0x801633cc, 0x596e5b6f, 0x11b9830e, 0x5b9d8a2a, + 0x134a524b, 0xca323ae8, 0x82e5e289, 0xc30eaeb9, 0x8bd976d8, + 0x52a11e7b, 0x1a76c61a, 0x5052cf3e, 0x1885175f, 0xc1fd7ffc, + 0x892aa79d, 0x55b56db4, 0x1d62b5d5, 0xc41add76, 0x8ccd0517, + 0xc6e90c33, 0x8e3ed452, 0x5746bcf1, 0x1f916490, 0xd4902491, + 0x9c47fcf0, 0x453f9453, 0x0de84c32, 0x47cc4516, 0x0f1b9d77, + 0xd663f5d4, 0x9eb42db5, 0x422be79c, 0x0afc3ffd, 0xd384575e, + 0x9b538f3f, 0xd177861b, 0x99a05e7a, 0x40d836d9, 0x080feeb8, + 0x49e4a288, 0x01337ae9, 0xd84b124a, 0x909cca2b, 0xdab8c30f, + 0x926f1b6e, 0x4b1773cd, 0x03c0abac, 0xdf5f6185, 0x9788b9e4, + 0x4ef0d147, 0x06270926, 0x4c030002, 0x04d4d863, 0xddacb0c0, + 0x957b68a1}}; + +static const word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x61d8d74800000000, 0xc2b0af9100000000, + 0xa36878d900000000, 0x87615c9300000000, 0xe6b98bdb00000000, + 0x45d1f30200000000, 0x2409244a00000000, 0x0dc3bb9600000000, + 0x6c1b6cde00000000, 0xcf73140700000000, 0xaeabc34f00000000, + 0x8aa2e70500000000, 0xeb7a304d00000000, 0x4812489400000000, + 0x29ca9fdc00000000, 0x1986749d00000000, 0x785ea3d500000000, + 0xdb36db0c00000000, 0xbaee0c4400000000, 0x9ee7280e00000000, + 0xff3fff4600000000, 0x5c57879f00000000, 0x3d8f50d700000000, + 0x1445cf0b00000000, 0x759d184300000000, 0xd6f5609a00000000, + 0xb72db7d200000000, 0x9324939800000000, 0xf2fc44d000000000, + 0x51943c0900000000, 0x304ceb4100000000, 0x310cea8a00000000, + 0x50d43dc200000000, 0xf3bc451b00000000, 0x9264925300000000, + 0xb66db61900000000, 0xd7b5615100000000, 0x74dd198800000000, + 0x1505cec000000000, 0x3ccf511c00000000, 0x5d17865400000000, + 0xfe7ffe8d00000000, 0x9fa729c500000000, 0xbbae0d8f00000000, + 0xda76dac700000000, 0x791ea21e00000000, 0x18c6755600000000, + 0x288a9e1700000000, 0x4952495f00000000, 0xea3a318600000000, + 0x8be2e6ce00000000, 0xafebc28400000000, 0xce3315cc00000000, + 0x6d5b6d1500000000, 0x0c83ba5d00000000, 0x2549258100000000, + 0x4491f2c900000000, 0xe7f98a1000000000, 0x86215d5800000000, + 0xa228791200000000, 0xc3f0ae5a00000000, 0x6098d68300000000, + 0x014001cb00000000, 0x6118d7a500000000, 0x00c000ed00000000, + 0xa3a8783400000000, 0xc270af7c00000000, 0xe6798b3600000000, + 0x87a15c7e00000000, 0x24c924a700000000, 0x4511f3ef00000000, + 0x6cdb6c3300000000, 0x0d03bb7b00000000, 0xae6bc3a200000000, + 0xcfb314ea00000000, 0xebba30a000000000, 0x8a62e7e800000000, + 0x290a9f3100000000, 0x48d2487900000000, 0x789ea33800000000, + 0x1946747000000000, 0xba2e0ca900000000, 0xdbf6dbe100000000, + 0xffffffab00000000, 0x9e2728e300000000, 0x3d4f503a00000000, + 0x5c97877200000000, 0x755d18ae00000000, 0x1485cfe600000000, + 0xb7edb73f00000000, 0xd635607700000000, 0xf23c443d00000000, + 0x93e4937500000000, 0x308cebac00000000, 0x51543ce400000000, + 0x50143d2f00000000, 0x31ccea6700000000, 0x92a492be00000000, + 0xf37c45f600000000, 0xd77561bc00000000, 0xb6adb6f400000000, + 0x15c5ce2d00000000, 0x741d196500000000, 0x5dd786b900000000, + 0x3c0f51f100000000, 0x9f67292800000000, 0xfebffe6000000000, + 0xdab6da2a00000000, 0xbb6e0d6200000000, 0x180675bb00000000, + 0x79dea2f300000000, 0x499249b200000000, 0x284a9efa00000000, + 0x8b22e62300000000, 0xeafa316b00000000, 0xcef3152100000000, + 0xaf2bc26900000000, 0x0c43bab000000000, 0x6d9b6df800000000, + 0x4451f22400000000, 0x2589256c00000000, 0x86e15db500000000, + 0xe7398afd00000000, 0xc330aeb700000000, 0xa2e879ff00000000, + 0x0180012600000000, 0x6058d66e00000000, 0xc130adfb00000000, + 0xa0e87ab300000000, 0x0380026a00000000, 0x6258d52200000000, + 0x4651f16800000000, 0x2789262000000000, 0x84e15ef900000000, + 0xe53989b100000000, 0xccf3166d00000000, 0xad2bc12500000000, + 0x0e43b9fc00000000, 0x6f9b6eb400000000, 0x4b924afe00000000, + 0x2a4a9db600000000, 0x8922e56f00000000, 0xe8fa322700000000, + 0xd8b6d96600000000, 0xb96e0e2e00000000, 0x1a0676f700000000, + 0x7bdea1bf00000000, 0x5fd785f500000000, 0x3e0f52bd00000000, + 0x9d672a6400000000, 0xfcbffd2c00000000, 0xd57562f000000000, + 0xb4adb5b800000000, 0x17c5cd6100000000, 0x761d1a2900000000, + 0x52143e6300000000, 0x33cce92b00000000, 0x90a491f200000000, + 0xf17c46ba00000000, 0xf03c477100000000, 0x91e4903900000000, + 0x328ce8e000000000, 0x53543fa800000000, 0x775d1be200000000, + 0x1685ccaa00000000, 0xb5edb47300000000, 0xd435633b00000000, + 0xfdfffce700000000, 0x9c272baf00000000, 0x3f4f537600000000, + 0x5e97843e00000000, 0x7a9ea07400000000, 0x1b46773c00000000, + 0xb82e0fe500000000, 0xd9f6d8ad00000000, 0xe9ba33ec00000000, + 0x8862e4a400000000, 0x2b0a9c7d00000000, 0x4ad24b3500000000, + 0x6edb6f7f00000000, 0x0f03b83700000000, 0xac6bc0ee00000000, + 0xcdb317a600000000, 0xe479887a00000000, 0x85a15f3200000000, + 0x26c927eb00000000, 0x4711f0a300000000, 0x6318d4e900000000, + 0x02c003a100000000, 0xa1a87b7800000000, 0xc070ac3000000000, + 0xa0287a5e00000000, 0xc1f0ad1600000000, 0x6298d5cf00000000, + 0x0340028700000000, 0x274926cd00000000, 0x4691f18500000000, + 0xe5f9895c00000000, 0x84215e1400000000, 0xadebc1c800000000, + 0xcc33168000000000, 0x6f5b6e5900000000, 0x0e83b91100000000, + 0x2a8a9d5b00000000, 0x4b524a1300000000, 0xe83a32ca00000000, + 0x89e2e58200000000, 0xb9ae0ec300000000, 0xd876d98b00000000, + 0x7b1ea15200000000, 0x1ac6761a00000000, 0x3ecf525000000000, + 0x5f17851800000000, 0xfc7ffdc100000000, 0x9da72a8900000000, + 0xb46db55500000000, 0xd5b5621d00000000, 0x76dd1ac400000000, + 0x1705cd8c00000000, 0x330ce9c600000000, 0x52d43e8e00000000, + 0xf1bc465700000000, 0x9064911f00000000, 0x912490d400000000, + 0xf0fc479c00000000, 0x53943f4500000000, 0x324ce80d00000000, + 0x1645cc4700000000, 0x779d1b0f00000000, 0xd4f563d600000000, + 0xb52db49e00000000, 0x9ce72b4200000000, 0xfd3ffc0a00000000, + 0x5e5784d300000000, 0x3f8f539b00000000, 0x1b8677d100000000, + 0x7a5ea09900000000, 0xd936d84000000000, 0xb8ee0f0800000000, + 0x88a2e44900000000, 0xe97a330100000000, 0x4a124bd800000000, + 0x2bca9c9000000000, 0x0fc3b8da00000000, 0x6e1b6f9200000000, + 0xcd73174b00000000, 0xacabc00300000000, 0x85615fdf00000000, + 0xe4b9889700000000, 0x47d1f04e00000000, 0x2609270600000000, + 0x0200034c00000000, 0x63d8d40400000000, 0xc0b0acdd00000000, + 0xa1687b9500000000}, + {0x0000000000000000, 0xd9b6d9a600000000, 0xb16db0fd00000000, + 0x68db695b00000000, 0x61db634b00000000, 0xb86dbaed00000000, + 0xd0b6d3b600000000, 0x09000a1000000000, 0xc2b6c79600000000, + 0x1b001e3000000000, 0x73db776b00000000, 0xaa6daecd00000000, + 0xa36da4dd00000000, 0x7adb7d7b00000000, 0x1200142000000000, + 0xcbb6cd8600000000, 0x876d8c9d00000000, 0x5edb553b00000000, + 0x36003c6000000000, 0xefb6e5c600000000, 0xe6b6efd600000000, + 0x3f00367000000000, 0x57db5f2b00000000, 0x8e6d868d00000000, + 0x45db4b0b00000000, 0x9c6d92ad00000000, 0xf4b6fbf600000000, + 0x2d00225000000000, 0x2400284000000000, 0xfdb6f1e600000000, + 0x956d98bd00000000, 0x4cdb411b00000000, 0x0ddb1b8b00000000, + 0xd46dc22d00000000, 0xbcb6ab7600000000, 0x650072d000000000, + 0x6c0078c000000000, 0xb5b6a16600000000, 0xdd6dc83d00000000, + 0x04db119b00000000, 0xcf6ddc1d00000000, 0x16db05bb00000000, + 0x7e006ce000000000, 0xa7b6b54600000000, 0xaeb6bf5600000000, + 0x770066f000000000, 0x1fdb0fab00000000, 0xc66dd60d00000000, + 0x8ab6971600000000, 0x53004eb000000000, 0x3bdb27eb00000000, + 0xe26dfe4d00000000, 0xeb6df45d00000000, 0x32db2dfb00000000, + 0x5a0044a000000000, 0x83b69d0600000000, 0x4800508000000000, + 0x91b6892600000000, 0xf96de07d00000000, 0x20db39db00000000, + 0x29db33cb00000000, 0xf06dea6d00000000, 0x98b6833600000000, + 0x41005a9000000000, 0x19b634a600000000, 0xc000ed0000000000, + 0xa8db845b00000000, 0x716d5dfd00000000, 0x786d57ed00000000, + 0xa1db8e4b00000000, 0xc900e71000000000, 0x10b63eb600000000, + 0xdb00f33000000000, 0x02b62a9600000000, 0x6a6d43cd00000000, + 0xb3db9a6b00000000, 0xbadb907b00000000, 0x636d49dd00000000, + 0x0bb6208600000000, 0xd200f92000000000, 0x9edbb83b00000000, + 0x476d619d00000000, 0x2fb608c600000000, 0xf600d16000000000, + 0xff00db7000000000, 0x26b602d600000000, 0x4e6d6b8d00000000, + 0x97dbb22b00000000, 0x5c6d7fad00000000, 0x85dba60b00000000, + 0xed00cf5000000000, 0x34b616f600000000, 0x3db61ce600000000, + 0xe400c54000000000, 0x8cdbac1b00000000, 0x556d75bd00000000, + 0x146d2f2d00000000, 0xcddbf68b00000000, 0xa5009fd000000000, + 0x7cb6467600000000, 0x75b64c6600000000, 0xac0095c000000000, + 0xc4dbfc9b00000000, 0x1d6d253d00000000, 0xd6dbe8bb00000000, + 0x0f6d311d00000000, 0x67b6584600000000, 0xbe0081e000000000, + 0xb7008bf000000000, 0x6eb6525600000000, 0x066d3b0d00000000, + 0xdfdbe2ab00000000, 0x9300a3b000000000, 0x4ab67a1600000000, + 0x226d134d00000000, 0xfbdbcaeb00000000, 0xf2dbc0fb00000000, + 0x2b6d195d00000000, 0x43b6700600000000, 0x9a00a9a000000000, + 0x51b6642600000000, 0x8800bd8000000000, 0xe0dbd4db00000000, + 0x396d0d7d00000000, 0x306d076d00000000, 0xe9dbdecb00000000, + 0x8100b79000000000, 0x58b66e3600000000, 0x316c6afc00000000, + 0xe8dab35a00000000, 0x8001da0100000000, 0x59b703a700000000, + 0x50b709b700000000, 0x8901d01100000000, 0xe1dab94a00000000, + 0x386c60ec00000000, 0xf3daad6a00000000, 0x2a6c74cc00000000, + 0x42b71d9700000000, 0x9b01c43100000000, 0x9201ce2100000000, + 0x4bb7178700000000, 0x236c7edc00000000, 0xfadaa77a00000000, + 0xb601e66100000000, 0x6fb73fc700000000, 0x076c569c00000000, + 0xdeda8f3a00000000, 0xd7da852a00000000, 0x0e6c5c8c00000000, + 0x66b735d700000000, 0xbf01ec7100000000, 0x74b721f700000000, + 0xad01f85100000000, 0xc5da910a00000000, 0x1c6c48ac00000000, + 0x156c42bc00000000, 0xccda9b1a00000000, 0xa401f24100000000, + 0x7db72be700000000, 0x3cb7717700000000, 0xe501a8d100000000, + 0x8ddac18a00000000, 0x546c182c00000000, 0x5d6c123c00000000, + 0x84dacb9a00000000, 0xec01a2c100000000, 0x35b77b6700000000, + 0xfe01b6e100000000, 0x27b76f4700000000, 0x4f6c061c00000000, + 0x96dadfba00000000, 0x9fdad5aa00000000, 0x466c0c0c00000000, + 0x2eb7655700000000, 0xf701bcf100000000, 0xbbdafdea00000000, + 0x626c244c00000000, 0x0ab74d1700000000, 0xd30194b100000000, + 0xda019ea100000000, 0x03b7470700000000, 0x6b6c2e5c00000000, + 0xb2daf7fa00000000, 0x796c3a7c00000000, 0xa0dae3da00000000, + 0xc8018a8100000000, 0x11b7532700000000, 0x18b7593700000000, + 0xc101809100000000, 0xa9dae9ca00000000, 0x706c306c00000000, + 0x28da5e5a00000000, 0xf16c87fc00000000, 0x99b7eea700000000, + 0x4001370100000000, 0x49013d1100000000, 0x90b7e4b700000000, + 0xf86c8dec00000000, 0x21da544a00000000, 0xea6c99cc00000000, + 0x33da406a00000000, 0x5b01293100000000, 0x82b7f09700000000, + 0x8bb7fa8700000000, 0x5201232100000000, 0x3ada4a7a00000000, + 0xe36c93dc00000000, 0xafb7d2c700000000, 0x76010b6100000000, + 0x1eda623a00000000, 0xc76cbb9c00000000, 0xce6cb18c00000000, + 0x17da682a00000000, 0x7f01017100000000, 0xa6b7d8d700000000, + 0x6d01155100000000, 0xb4b7ccf700000000, 0xdc6ca5ac00000000, + 0x05da7c0a00000000, 0x0cda761a00000000, 0xd56cafbc00000000, + 0xbdb7c6e700000000, 0x64011f4100000000, 0x250145d100000000, + 0xfcb79c7700000000, 0x946cf52c00000000, 0x4dda2c8a00000000, + 0x44da269a00000000, 0x9d6cff3c00000000, 0xf5b7966700000000, + 0x2c014fc100000000, 0xe7b7824700000000, 0x3e015be100000000, + 0x56da32ba00000000, 0x8f6ceb1c00000000, 0x866ce10c00000000, + 0x5fda38aa00000000, 0x370151f100000000, 0xeeb7885700000000, + 0xa26cc94c00000000, 0x7bda10ea00000000, 0x130179b100000000, + 0xcab7a01700000000, 0xc3b7aa0700000000, 0x1a0173a100000000, + 0x72da1afa00000000, 0xab6cc35c00000000, 0x60da0eda00000000, + 0xb96cd77c00000000, 0xd1b7be2700000000, 0x0801678100000000, + 0x01016d9100000000, 0xd8b7b43700000000, 0xb06cdd6c00000000, + 0x69da04ca00000000}, + {0x0000000000000000, 0xb700b7f100000000, 0x6d016d5300000000, + 0xda01daa200000000, 0xda02daa600000000, 0x6d026d5700000000, + 0xb703b7f500000000, 0x0003000400000000, 0xb705b7fd00000000, + 0x0005000c00000000, 0xda04daae00000000, 0x6d046d5f00000000, + 0x6d076d5b00000000, 0xda07daaa00000000, 0x0006000800000000, + 0xb706b7f900000000, 0x6d0b6d4b00000000, 0xda0bdaba00000000, + 0x000a001800000000, 0xb70ab7e900000000, 0xb709b7ed00000000, + 0x0009001c00000000, 0xda08dabe00000000, 0x6d086d4f00000000, + 0xda0edab600000000, 0x6d0e6d4700000000, 0xb70fb7e500000000, + 0x000f001400000000, 0x000c001000000000, 0xb70cb7e100000000, + 0x6d0d6d4300000000, 0xda0ddab200000000, 0xda16da9600000000, + 0x6d166d6700000000, 0xb717b7c500000000, 0x0017003400000000, + 0x0014003000000000, 0xb714b7c100000000, 0x6d156d6300000000, + 0xda15da9200000000, 0x6d136d6b00000000, 0xda13da9a00000000, + 0x0012003800000000, 0xb712b7c900000000, 0xb711b7cd00000000, + 0x0011003c00000000, 0xda10da9e00000000, 0x6d106d6f00000000, + 0xb71db7dd00000000, 0x001d002c00000000, 0xda1cda8e00000000, + 0x6d1c6d7f00000000, 0x6d1f6d7b00000000, 0xda1fda8a00000000, + 0x001e002800000000, 0xb71eb7d900000000, 0x0018002000000000, + 0xb718b7d100000000, 0x6d196d7300000000, 0xda19da8200000000, + 0xda1ada8600000000, 0x6d1a6d7700000000, 0xb71bb7d500000000, + 0x001b002400000000, 0xb72db79d00000000, 0x002d006c00000000, + 0xda2cdace00000000, 0x6d2c6d3f00000000, 0x6d2f6d3b00000000, + 0xda2fdaca00000000, 0x002e006800000000, 0xb72eb79900000000, + 0x0028006000000000, 0xb728b79100000000, 0x6d296d3300000000, + 0xda29dac200000000, 0xda2adac600000000, 0x6d2a6d3700000000, + 0xb72bb79500000000, 0x002b006400000000, 0xda26dad600000000, + 0x6d266d2700000000, 0xb727b78500000000, 0x0027007400000000, + 0x0024007000000000, 0xb724b78100000000, 0x6d256d2300000000, + 0xda25dad200000000, 0x6d236d2b00000000, 0xda23dada00000000, + 0x0022007800000000, 0xb722b78900000000, 0xb721b78d00000000, + 0x0021007c00000000, 0xda20dade00000000, 0x6d206d2f00000000, + 0x6d3b6d0b00000000, 0xda3bdafa00000000, 0x003a005800000000, + 0xb73ab7a900000000, 0xb739b7ad00000000, 0x0039005c00000000, + 0xda38dafe00000000, 0x6d386d0f00000000, 0xda3edaf600000000, + 0x6d3e6d0700000000, 0xb73fb7a500000000, 0x003f005400000000, + 0x003c005000000000, 0xb73cb7a100000000, 0x6d3d6d0300000000, + 0xda3ddaf200000000, 0x0030004000000000, 0xb730b7b100000000, + 0x6d316d1300000000, 0xda31dae200000000, 0xda32dae600000000, + 0x6d326d1700000000, 0xb733b7b500000000, 0x0033004400000000, + 0xb735b7bd00000000, 0x0035004c00000000, 0xda34daee00000000, + 0x6d346d1f00000000, 0x6d376d1b00000000, 0xda37daea00000000, + 0x0036004800000000, 0xb736b7b900000000, 0x6d5b6d8b00000000, + 0xda5bda7a00000000, 0x005a00d800000000, 0xb75ab72900000000, + 0xb759b72d00000000, 0x005900dc00000000, 0xda58da7e00000000, + 0x6d586d8f00000000, 0xda5eda7600000000, 0x6d5e6d8700000000, + 0xb75fb72500000000, 0x005f00d400000000, 0x005c00d000000000, + 0xb75cb72100000000, 0x6d5d6d8300000000, 0xda5dda7200000000, + 0x005000c000000000, 0xb750b73100000000, 0x6d516d9300000000, + 0xda51da6200000000, 0xda52da6600000000, 0x6d526d9700000000, + 0xb753b73500000000, 0x005300c400000000, 0xb755b73d00000000, + 0x005500cc00000000, 0xda54da6e00000000, 0x6d546d9f00000000, + 0x6d576d9b00000000, 0xda57da6a00000000, 0x005600c800000000, + 0xb756b73900000000, 0xb74db71d00000000, 0x004d00ec00000000, + 0xda4cda4e00000000, 0x6d4c6dbf00000000, 0x6d4f6dbb00000000, + 0xda4fda4a00000000, 0x004e00e800000000, 0xb74eb71900000000, + 0x004800e000000000, 0xb748b71100000000, 0x6d496db300000000, + 0xda49da4200000000, 0xda4ada4600000000, 0x6d4a6db700000000, + 0xb74bb71500000000, 0x004b00e400000000, 0xda46da5600000000, + 0x6d466da700000000, 0xb747b70500000000, 0x004700f400000000, + 0x004400f000000000, 0xb744b70100000000, 0x6d456da300000000, + 0xda45da5200000000, 0x6d436dab00000000, 0xda43da5a00000000, + 0x004200f800000000, 0xb742b70900000000, 0xb741b70d00000000, + 0x004100fc00000000, 0xda40da5e00000000, 0x6d406daf00000000, + 0xda76da1600000000, 0x6d766de700000000, 0xb777b74500000000, + 0x007700b400000000, 0x007400b000000000, 0xb774b74100000000, + 0x6d756de300000000, 0xda75da1200000000, 0x6d736deb00000000, + 0xda73da1a00000000, 0x007200b800000000, 0xb772b74900000000, + 0xb771b74d00000000, 0x007100bc00000000, 0xda70da1e00000000, + 0x6d706def00000000, 0xb77db75d00000000, 0x007d00ac00000000, + 0xda7cda0e00000000, 0x6d7c6dff00000000, 0x6d7f6dfb00000000, + 0xda7fda0a00000000, 0x007e00a800000000, 0xb77eb75900000000, + 0x007800a000000000, 0xb778b75100000000, 0x6d796df300000000, + 0xda79da0200000000, 0xda7ada0600000000, 0x6d7a6df700000000, + 0xb77bb75500000000, 0x007b00a400000000, 0x0060008000000000, + 0xb760b77100000000, 0x6d616dd300000000, 0xda61da2200000000, + 0xda62da2600000000, 0x6d626dd700000000, 0xb763b77500000000, + 0x0063008400000000, 0xb765b77d00000000, 0x0065008c00000000, + 0xda64da2e00000000, 0x6d646ddf00000000, 0x6d676ddb00000000, + 0xda67da2a00000000, 0x0066008800000000, 0xb766b77900000000, + 0x6d6b6dcb00000000, 0xda6bda3a00000000, 0x006a009800000000, + 0xb76ab76900000000, 0xb769b76d00000000, 0x0069009c00000000, + 0xda68da3e00000000, 0x6d686dcf00000000, 0xda6eda3600000000, + 0x6d6e6dc700000000, 0xb76fb76500000000, 0x006f009400000000, + 0x006c009000000000, 0xb76cb76100000000, 0x6d6d6dc300000000, + 0xda6dda3200000000}, + {0x0000000000000000, 0x0000015000000000, 0x000002a000000000, + 0x000003f000000000, 0x030007f000000000, 0x030006a000000000, + 0x0300055000000000, 0x0300040000000000, 0x05000d5000000000, + 0x05000c0000000000, 0x05000ff000000000, 0x05000ea000000000, + 0x06000aa000000000, 0x06000bf000000000, 0x0600080000000000, + 0x0600095000000000, 0x0a001aa000000000, 0x0a001bf000000000, + 0x0a00180000000000, 0x0a00195000000000, 0x09001d5000000000, + 0x09001c0000000000, 0x09001ff000000000, 0x09001ea000000000, + 0x0f0017f000000000, 0x0f0016a000000000, 0x0f00155000000000, + 0x0f00140000000000, 0x0c00100000000000, 0x0c00115000000000, + 0x0c0012a000000000, 0x0c0013f000000000, 0x170037f000000000, + 0x170036a000000000, 0x1700355000000000, 0x1700340000000000, + 0x1400300000000000, 0x1400315000000000, 0x140032a000000000, + 0x140033f000000000, 0x12003aa000000000, 0x12003bf000000000, + 0x1200380000000000, 0x1200395000000000, 0x11003d5000000000, + 0x11003c0000000000, 0x11003ff000000000, 0x11003ea000000000, + 0x1d002d5000000000, 0x1d002c0000000000, 0x1d002ff000000000, + 0x1d002ea000000000, 0x1e002aa000000000, 0x1e002bf000000000, + 0x1e00280000000000, 0x1e00295000000000, 0x1800200000000000, + 0x1800215000000000, 0x180022a000000000, 0x180023f000000000, + 0x1b0027f000000000, 0x1b0026a000000000, 0x1b00255000000000, + 0x1b00240000000000, 0x2d006d5000000000, 0x2d006c0000000000, + 0x2d006ff000000000, 0x2d006ea000000000, 0x2e006aa000000000, + 0x2e006bf000000000, 0x2e00680000000000, 0x2e00695000000000, + 0x2800600000000000, 0x2800615000000000, 0x280062a000000000, + 0x280063f000000000, 0x2b0067f000000000, 0x2b0066a000000000, + 0x2b00655000000000, 0x2b00640000000000, 0x270077f000000000, + 0x270076a000000000, 0x2700755000000000, 0x2700740000000000, + 0x2400700000000000, 0x2400715000000000, 0x240072a000000000, + 0x240073f000000000, 0x22007aa000000000, 0x22007bf000000000, + 0x2200780000000000, 0x2200795000000000, 0x21007d5000000000, + 0x21007c0000000000, 0x21007ff000000000, 0x21007ea000000000, + 0x3a005aa000000000, 0x3a005bf000000000, 0x3a00580000000000, + 0x3a00595000000000, 0x39005d5000000000, 0x39005c0000000000, + 0x39005ff000000000, 0x39005ea000000000, 0x3f0057f000000000, + 0x3f0056a000000000, 0x3f00555000000000, 0x3f00540000000000, + 0x3c00500000000000, 0x3c00515000000000, 0x3c0052a000000000, + 0x3c0053f000000000, 0x3000400000000000, 0x3000415000000000, + 0x300042a000000000, 0x300043f000000000, 0x330047f000000000, + 0x330046a000000000, 0x3300455000000000, 0x3300440000000000, + 0x35004d5000000000, 0x35004c0000000000, 0x35004ff000000000, + 0x35004ea000000000, 0x36004aa000000000, 0x36004bf000000000, + 0x3600480000000000, 0x3600495000000000, 0x5a00daa000000000, + 0x5a00dbf000000000, 0x5a00d80000000000, 0x5a00d95000000000, + 0x5900dd5000000000, 0x5900dc0000000000, 0x5900dff000000000, + 0x5900dea000000000, 0x5f00d7f000000000, 0x5f00d6a000000000, + 0x5f00d55000000000, 0x5f00d40000000000, 0x5c00d00000000000, + 0x5c00d15000000000, 0x5c00d2a000000000, 0x5c00d3f000000000, + 0x5000c00000000000, 0x5000c15000000000, 0x5000c2a000000000, + 0x5000c3f000000000, 0x5300c7f000000000, 0x5300c6a000000000, + 0x5300c55000000000, 0x5300c40000000000, 0x5500cd5000000000, + 0x5500cc0000000000, 0x5500cff000000000, 0x5500cea000000000, + 0x5600caa000000000, 0x5600cbf000000000, 0x5600c80000000000, + 0x5600c95000000000, 0x4d00ed5000000000, 0x4d00ec0000000000, + 0x4d00eff000000000, 0x4d00eea000000000, 0x4e00eaa000000000, + 0x4e00ebf000000000, 0x4e00e80000000000, 0x4e00e95000000000, + 0x4800e00000000000, 0x4800e15000000000, 0x4800e2a000000000, + 0x4800e3f000000000, 0x4b00e7f000000000, 0x4b00e6a000000000, + 0x4b00e55000000000, 0x4b00e40000000000, 0x4700f7f000000000, + 0x4700f6a000000000, 0x4700f55000000000, 0x4700f40000000000, + 0x4400f00000000000, 0x4400f15000000000, 0x4400f2a000000000, + 0x4400f3f000000000, 0x4200faa000000000, 0x4200fbf000000000, + 0x4200f80000000000, 0x4200f95000000000, 0x4100fd5000000000, + 0x4100fc0000000000, 0x4100fff000000000, 0x4100fea000000000, + 0x7700b7f000000000, 0x7700b6a000000000, 0x7700b55000000000, + 0x7700b40000000000, 0x7400b00000000000, 0x7400b15000000000, + 0x7400b2a000000000, 0x7400b3f000000000, 0x7200baa000000000, + 0x7200bbf000000000, 0x7200b80000000000, 0x7200b95000000000, + 0x7100bd5000000000, 0x7100bc0000000000, 0x7100bff000000000, + 0x7100bea000000000, 0x7d00ad5000000000, 0x7d00ac0000000000, + 0x7d00aff000000000, 0x7d00aea000000000, 0x7e00aaa000000000, + 0x7e00abf000000000, 0x7e00a80000000000, 0x7e00a95000000000, + 0x7800a00000000000, 0x7800a15000000000, 0x7800a2a000000000, + 0x7800a3f000000000, 0x7b00a7f000000000, 0x7b00a6a000000000, + 0x7b00a55000000000, 0x7b00a40000000000, 0x6000800000000000, + 0x6000815000000000, 0x600082a000000000, 0x600083f000000000, + 0x630087f000000000, 0x630086a000000000, 0x6300855000000000, + 0x6300840000000000, 0x65008d5000000000, 0x65008c0000000000, + 0x65008ff000000000, 0x65008ea000000000, 0x66008aa000000000, + 0x66008bf000000000, 0x6600880000000000, 0x6600895000000000, + 0x6a009aa000000000, 0x6a009bf000000000, 0x6a00980000000000, + 0x6a00995000000000, 0x69009d5000000000, 0x69009c0000000000, + 0x69009ff000000000, 0x69009ea000000000, 0x6f0097f000000000, + 0x6f0096a000000000, 0x6f00955000000000, 0x6f00940000000000, + 0x6c00900000000000, 0x6c00915000000000, 0x6c0092a000000000, + 0x6c0093f000000000}, + {0x0000000000000000, 0x0001500000000000, 0x0002a00000000000, + 0x0003f00000000000, 0x0004400100000000, 0x0005100100000000, + 0x0006e00100000000, 0x0007b00100000000, 0x0008800200000000, + 0x0009d00200000000, 0x000a200200000000, 0x000b700200000000, + 0x000cc00300000000, 0x000d900300000000, 0x000e600300000000, + 0x000f300300000000, 0x0010000500000000, 0x0011500500000000, + 0x0012a00500000000, 0x0013f00500000000, 0x0014400400000000, + 0x0015100400000000, 0x0016e00400000000, 0x0017b00400000000, + 0x0018800700000000, 0x0019d00700000000, 0x001a200700000000, + 0x001b700700000000, 0x001cc00600000000, 0x001d900600000000, + 0x001e600600000000, 0x001f300600000000, 0x0020000a00000000, + 0x0021500a00000000, 0x0022a00a00000000, 0x0023f00a00000000, + 0x0024400b00000000, 0x0025100b00000000, 0x0026e00b00000000, + 0x0027b00b00000000, 0x0028800800000000, 0x0029d00800000000, + 0x002a200800000000, 0x002b700800000000, 0x002cc00900000000, + 0x002d900900000000, 0x002e600900000000, 0x002f300900000000, + 0x0030000f00000000, 0x0031500f00000000, 0x0032a00f00000000, + 0x0033f00f00000000, 0x0034400e00000000, 0x0035100e00000000, + 0x0036e00e00000000, 0x0037b00e00000000, 0x0038800d00000000, + 0x0039d00d00000000, 0x003a200d00000000, 0x003b700d00000000, + 0x003cc00c00000000, 0x003d900c00000000, 0x003e600c00000000, + 0x003f300c00000000, 0x0040001400000000, 0x0041501400000000, + 0x0042a01400000000, 0x0043f01400000000, 0x0044401500000000, + 0x0045101500000000, 0x0046e01500000000, 0x0047b01500000000, + 0x0048801600000000, 0x0049d01600000000, 0x004a201600000000, + 0x004b701600000000, 0x004cc01700000000, 0x004d901700000000, + 0x004e601700000000, 0x004f301700000000, 0x0050001100000000, + 0x0051501100000000, 0x0052a01100000000, 0x0053f01100000000, + 0x0054401000000000, 0x0055101000000000, 0x0056e01000000000, + 0x0057b01000000000, 0x0058801300000000, 0x0059d01300000000, + 0x005a201300000000, 0x005b701300000000, 0x005cc01200000000, + 0x005d901200000000, 0x005e601200000000, 0x005f301200000000, + 0x0060001e00000000, 0x0061501e00000000, 0x0062a01e00000000, + 0x0063f01e00000000, 0x0064401f00000000, 0x0065101f00000000, + 0x0066e01f00000000, 0x0067b01f00000000, 0x0068801c00000000, + 0x0069d01c00000000, 0x006a201c00000000, 0x006b701c00000000, + 0x006cc01d00000000, 0x006d901d00000000, 0x006e601d00000000, + 0x006f301d00000000, 0x0070001b00000000, 0x0071501b00000000, + 0x0072a01b00000000, 0x0073f01b00000000, 0x0074401a00000000, + 0x0075101a00000000, 0x0076e01a00000000, 0x0077b01a00000000, + 0x0078801900000000, 0x0079d01900000000, 0x007a201900000000, + 0x007b701900000000, 0x007cc01800000000, 0x007d901800000000, + 0x007e601800000000, 0x007f301800000000, 0x0080002800000000, + 0x0081502800000000, 0x0082a02800000000, 0x0083f02800000000, + 0x0084402900000000, 0x0085102900000000, 0x0086e02900000000, + 0x0087b02900000000, 0x0088802a00000000, 0x0089d02a00000000, + 0x008a202a00000000, 0x008b702a00000000, 0x008cc02b00000000, + 0x008d902b00000000, 0x008e602b00000000, 0x008f302b00000000, + 0x0090002d00000000, 0x0091502d00000000, 0x0092a02d00000000, + 0x0093f02d00000000, 0x0094402c00000000, 0x0095102c00000000, + 0x0096e02c00000000, 0x0097b02c00000000, 0x0098802f00000000, + 0x0099d02f00000000, 0x009a202f00000000, 0x009b702f00000000, + 0x009cc02e00000000, 0x009d902e00000000, 0x009e602e00000000, + 0x009f302e00000000, 0x00a0002200000000, 0x00a1502200000000, + 0x00a2a02200000000, 0x00a3f02200000000, 0x00a4402300000000, + 0x00a5102300000000, 0x00a6e02300000000, 0x00a7b02300000000, + 0x00a8802000000000, 0x00a9d02000000000, 0x00aa202000000000, + 0x00ab702000000000, 0x00acc02100000000, 0x00ad902100000000, + 0x00ae602100000000, 0x00af302100000000, 0x00b0002700000000, + 0x00b1502700000000, 0x00b2a02700000000, 0x00b3f02700000000, + 0x00b4402600000000, 0x00b5102600000000, 0x00b6e02600000000, + 0x00b7b02600000000, 0x00b8802500000000, 0x00b9d02500000000, + 0x00ba202500000000, 0x00bb702500000000, 0x00bcc02400000000, + 0x00bd902400000000, 0x00be602400000000, 0x00bf302400000000, + 0x00c0003c00000000, 0x00c1503c00000000, 0x00c2a03c00000000, + 0x00c3f03c00000000, 0x00c4403d00000000, 0x00c5103d00000000, + 0x00c6e03d00000000, 0x00c7b03d00000000, 0x00c8803e00000000, + 0x00c9d03e00000000, 0x00ca203e00000000, 0x00cb703e00000000, + 0x00ccc03f00000000, 0x00cd903f00000000, 0x00ce603f00000000, + 0x00cf303f00000000, 0x00d0003900000000, 0x00d1503900000000, + 0x00d2a03900000000, 0x00d3f03900000000, 0x00d4403800000000, + 0x00d5103800000000, 0x00d6e03800000000, 0x00d7b03800000000, + 0x00d8803b00000000, 0x00d9d03b00000000, 0x00da203b00000000, + 0x00db703b00000000, 0x00dcc03a00000000, 0x00dd903a00000000, + 0x00de603a00000000, 0x00df303a00000000, 0x00e0003600000000, + 0x00e1503600000000, 0x00e2a03600000000, 0x00e3f03600000000, + 0x00e4403700000000, 0x00e5103700000000, 0x00e6e03700000000, + 0x00e7b03700000000, 0x00e8803400000000, 0x00e9d03400000000, + 0x00ea203400000000, 0x00eb703400000000, 0x00ecc03500000000, + 0x00ed903500000000, 0x00ee603500000000, 0x00ef303500000000, + 0x00f0003300000000, 0x00f1503300000000, 0x00f2a03300000000, + 0x00f3f03300000000, 0x00f4403200000000, 0x00f5103200000000, + 0x00f6e03200000000, 0x00f7b03200000000, 0x00f8803100000000, + 0x00f9d03100000000, 0x00fa203100000000, 0x00fb703100000000, + 0x00fcc03000000000, 0x00fd903000000000, 0x00fe603000000000, + 0x00ff303000000000}, + {0x0000000000000000, 0x0150000000000000, 0x02a0000000000000, + 0x03f0000000000000, 0x0440010000000000, 0x0510010000000000, + 0x06e0010000000000, 0x07b0010000000000, 0x0880020000000000, + 0x09d0020000000000, 0x0a20020000000000, 0x0b70020000000000, + 0x0cc0030000000000, 0x0d90030000000000, 0x0e60030000000000, + 0x0f30030000000000, 0x1000050000000000, 0x1150050000000000, + 0x12a0050000000000, 0x13f0050000000000, 0x1440040000000000, + 0x1510040000000000, 0x16e0040000000000, 0x17b0040000000000, + 0x1880070000000000, 0x19d0070000000000, 0x1a20070000000000, + 0x1b70070000000000, 0x1cc0060000000000, 0x1d90060000000000, + 0x1e60060000000000, 0x1f30060000000000, 0x20000a0000000000, + 0x21500a0000000000, 0x22a00a0000000000, 0x23f00a0000000000, + 0x24400b0000000000, 0x25100b0000000000, 0x26e00b0000000000, + 0x27b00b0000000000, 0x2880080000000000, 0x29d0080000000000, + 0x2a20080000000000, 0x2b70080000000000, 0x2cc0090000000000, + 0x2d90090000000000, 0x2e60090000000000, 0x2f30090000000000, + 0x30000f0000000000, 0x31500f0000000000, 0x32a00f0000000000, + 0x33f00f0000000000, 0x34400e0000000000, 0x35100e0000000000, + 0x36e00e0000000000, 0x37b00e0000000000, 0x38800d0000000000, + 0x39d00d0000000000, 0x3a200d0000000000, 0x3b700d0000000000, + 0x3cc00c0000000000, 0x3d900c0000000000, 0x3e600c0000000000, + 0x3f300c0000000000, 0x4000140000000000, 0x4150140000000000, + 0x42a0140000000000, 0x43f0140000000000, 0x4440150000000000, + 0x4510150000000000, 0x46e0150000000000, 0x47b0150000000000, + 0x4880160000000000, 0x49d0160000000000, 0x4a20160000000000, + 0x4b70160000000000, 0x4cc0170000000000, 0x4d90170000000000, + 0x4e60170000000000, 0x4f30170000000000, 0x5000110000000000, + 0x5150110000000000, 0x52a0110000000000, 0x53f0110000000000, + 0x5440100000000000, 0x5510100000000000, 0x56e0100000000000, + 0x57b0100000000000, 0x5880130000000000, 0x59d0130000000000, + 0x5a20130000000000, 0x5b70130000000000, 0x5cc0120000000000, + 0x5d90120000000000, 0x5e60120000000000, 0x5f30120000000000, + 0x60001e0000000000, 0x61501e0000000000, 0x62a01e0000000000, + 0x63f01e0000000000, 0x64401f0000000000, 0x65101f0000000000, + 0x66e01f0000000000, 0x67b01f0000000000, 0x68801c0000000000, + 0x69d01c0000000000, 0x6a201c0000000000, 0x6b701c0000000000, + 0x6cc01d0000000000, 0x6d901d0000000000, 0x6e601d0000000000, + 0x6f301d0000000000, 0x70001b0000000000, 0x71501b0000000000, + 0x72a01b0000000000, 0x73f01b0000000000, 0x74401a0000000000, + 0x75101a0000000000, 0x76e01a0000000000, 0x77b01a0000000000, + 0x7880190000000000, 0x79d0190000000000, 0x7a20190000000000, + 0x7b70190000000000, 0x7cc0180000000000, 0x7d90180000000000, + 0x7e60180000000000, 0x7f30180000000000, 0x8000280000000000, + 0x8150280000000000, 0x82a0280000000000, 0x83f0280000000000, + 0x8440290000000000, 0x8510290000000000, 0x86e0290000000000, + 0x87b0290000000000, 0x88802a0000000000, 0x89d02a0000000000, + 0x8a202a0000000000, 0x8b702a0000000000, 0x8cc02b0000000000, + 0x8d902b0000000000, 0x8e602b0000000000, 0x8f302b0000000000, + 0x90002d0000000000, 0x91502d0000000000, 0x92a02d0000000000, + 0x93f02d0000000000, 0x94402c0000000000, 0x95102c0000000000, + 0x96e02c0000000000, 0x97b02c0000000000, 0x98802f0000000000, + 0x99d02f0000000000, 0x9a202f0000000000, 0x9b702f0000000000, + 0x9cc02e0000000000, 0x9d902e0000000000, 0x9e602e0000000000, + 0x9f302e0000000000, 0xa000220000000000, 0xa150220000000000, + 0xa2a0220000000000, 0xa3f0220000000000, 0xa440230000000000, + 0xa510230000000000, 0xa6e0230000000000, 0xa7b0230000000000, + 0xa880200000000000, 0xa9d0200000000000, 0xaa20200000000000, + 0xab70200000000000, 0xacc0210000000000, 0xad90210000000000, + 0xae60210000000000, 0xaf30210000000000, 0xb000270000000000, + 0xb150270000000000, 0xb2a0270000000000, 0xb3f0270000000000, + 0xb440260000000000, 0xb510260000000000, 0xb6e0260000000000, + 0xb7b0260000000000, 0xb880250000000000, 0xb9d0250000000000, + 0xba20250000000000, 0xbb70250000000000, 0xbcc0240000000000, + 0xbd90240000000000, 0xbe60240000000000, 0xbf30240000000000, + 0xc0003c0000000000, 0xc1503c0000000000, 0xc2a03c0000000000, + 0xc3f03c0000000000, 0xc4403d0000000000, 0xc5103d0000000000, + 0xc6e03d0000000000, 0xc7b03d0000000000, 0xc8803e0000000000, + 0xc9d03e0000000000, 0xca203e0000000000, 0xcb703e0000000000, + 0xccc03f0000000000, 0xcd903f0000000000, 0xce603f0000000000, + 0xcf303f0000000000, 0xd000390000000000, 0xd150390000000000, + 0xd2a0390000000000, 0xd3f0390000000000, 0xd440380000000000, + 0xd510380000000000, 0xd6e0380000000000, 0xd7b0380000000000, + 0xd8803b0000000000, 0xd9d03b0000000000, 0xda203b0000000000, + 0xdb703b0000000000, 0xdcc03a0000000000, 0xdd903a0000000000, + 0xde603a0000000000, 0xdf303a0000000000, 0xe000360000000000, + 0xe150360000000000, 0xe2a0360000000000, 0xe3f0360000000000, + 0xe440370000000000, 0xe510370000000000, 0xe6e0370000000000, + 0xe7b0370000000000, 0xe880340000000000, 0xe9d0340000000000, + 0xea20340000000000, 0xeb70340000000000, 0xecc0350000000000, + 0xed90350000000000, 0xee60350000000000, 0xef30350000000000, + 0xf000330000000000, 0xf150330000000000, 0xf2a0330000000000, + 0xf3f0330000000000, 0xf440320000000000, 0xf510320000000000, + 0xf6e0320000000000, 0xf7b0320000000000, 0xf880310000000000, + 0xf9d0310000000000, 0xfa20310000000000, 0xfb70310000000000, + 0xfcc0300000000000, 0xfd90300000000000, 0xfe60300000000000, + 0xff30300000000000}, + {0x0000000000000000, 0x5101919000000000, 0xa102219100000000, + 0xf003b00100000000, 0x4105419200000000, 0x1004d00200000000, + 0xe007600300000000, 0xb106f19300000000, 0x810a819400000000, + 0xd00b100400000000, 0x2008a00500000000, 0x7109319500000000, + 0xc00fc00600000000, 0x910e519600000000, 0x610de19700000000, + 0x300c700700000000, 0x0115019900000000, 0x5014900900000000, + 0xa017200800000000, 0xf116b19800000000, 0x4010400b00000000, + 0x1111d19b00000000, 0xe112619a00000000, 0xb013f00a00000000, + 0x801f800d00000000, 0xd11e119d00000000, 0x211da19c00000000, + 0x701c300c00000000, 0xc11ac19f00000000, 0x901b500f00000000, + 0x6018e00e00000000, 0x3119719e00000000, 0x012a018200000000, + 0x502b901200000000, 0xa028201300000000, 0xf129b18300000000, + 0x402f401000000000, 0x112ed18000000000, 0xe12d618100000000, + 0xb02cf01100000000, 0x8020801600000000, 0xd121118600000000, + 0x2122a18700000000, 0x7023301700000000, 0xc125c18400000000, + 0x9024501400000000, 0x6027e01500000000, 0x3126718500000000, + 0x003f001b00000000, 0x513e918b00000000, 0xa13d218a00000000, + 0xf03cb01a00000000, 0x413a418900000000, 0x103bd01900000000, + 0xe038601800000000, 0xb139f18800000000, 0x8135818f00000000, + 0xd034101f00000000, 0x2037a01e00000000, 0x7136318e00000000, + 0xc030c01d00000000, 0x9131518d00000000, 0x6132e18c00000000, + 0x3033701c00000000, 0x015401b400000000, 0x5055902400000000, + 0xa056202500000000, 0xf157b1b500000000, 0x4051402600000000, + 0x1150d1b600000000, 0xe15361b700000000, 0xb052f02700000000, + 0x805e802000000000, 0xd15f11b000000000, 0x215ca1b100000000, + 0x705d302100000000, 0xc15bc1b200000000, 0x905a502200000000, + 0x6059e02300000000, 0x315871b300000000, 0x0041002d00000000, + 0x514091bd00000000, 0xa14321bc00000000, 0xf042b02c00000000, + 0x414441bf00000000, 0x1045d02f00000000, 0xe046602e00000000, + 0xb147f1be00000000, 0x814b81b900000000, 0xd04a102900000000, + 0x2049a02800000000, 0x714831b800000000, 0xc04ec02b00000000, + 0x914f51bb00000000, 0x614ce1ba00000000, 0x304d702a00000000, + 0x007e003600000000, 0x517f91a600000000, 0xa17c21a700000000, + 0xf07db03700000000, 0x417b41a400000000, 0x107ad03400000000, + 0xe079603500000000, 0xb178f1a500000000, 0x817481a200000000, + 0xd075103200000000, 0x2076a03300000000, 0x717731a300000000, + 0xc071c03000000000, 0x917051a000000000, 0x6173e1a100000000, + 0x3072703100000000, 0x016b01af00000000, 0x506a903f00000000, + 0xa069203e00000000, 0xf168b1ae00000000, 0x406e403d00000000, + 0x116fd1ad00000000, 0xe16c61ac00000000, 0xb06df03c00000000, + 0x8061803b00000000, 0xd16011ab00000000, 0x2163a1aa00000000, + 0x7062303a00000000, 0xc164c1a900000000, 0x9065503900000000, + 0x6066e03800000000, 0x316771a800000000, 0x01a801d800000000, + 0x50a9904800000000, 0xa0aa204900000000, 0xf1abb1d900000000, + 0x40ad404a00000000, 0x11acd1da00000000, 0xe1af61db00000000, + 0xb0aef04b00000000, 0x80a2804c00000000, 0xd1a311dc00000000, + 0x21a0a1dd00000000, 0x70a1304d00000000, 0xc1a7c1de00000000, + 0x90a6504e00000000, 0x60a5e04f00000000, 0x31a471df00000000, + 0x00bd004100000000, 0x51bc91d100000000, 0xa1bf21d000000000, + 0xf0beb04000000000, 0x41b841d300000000, 0x10b9d04300000000, + 0xe0ba604200000000, 0xb1bbf1d200000000, 0x81b781d500000000, + 0xd0b6104500000000, 0x20b5a04400000000, 0x71b431d400000000, + 0xc0b2c04700000000, 0x91b351d700000000, 0x61b0e1d600000000, + 0x30b1704600000000, 0x0082005a00000000, 0x518391ca00000000, + 0xa18021cb00000000, 0xf081b05b00000000, 0x418741c800000000, + 0x1086d05800000000, 0xe085605900000000, 0xb184f1c900000000, + 0x818881ce00000000, 0xd089105e00000000, 0x208aa05f00000000, + 0x718b31cf00000000, 0xc08dc05c00000000, 0x918c51cc00000000, + 0x618fe1cd00000000, 0x308e705d00000000, 0x019701c300000000, + 0x5096905300000000, 0xa095205200000000, 0xf194b1c200000000, + 0x4092405100000000, 0x1193d1c100000000, 0xe19061c000000000, + 0xb091f05000000000, 0x809d805700000000, 0xd19c11c700000000, + 0x219fa1c600000000, 0x709e305600000000, 0xc198c1c500000000, + 0x9099505500000000, 0x609ae05400000000, 0x319b71c400000000, + 0x00fc006c00000000, 0x51fd91fc00000000, 0xa1fe21fd00000000, + 0xf0ffb06d00000000, 0x41f941fe00000000, 0x10f8d06e00000000, + 0xe0fb606f00000000, 0xb1faf1ff00000000, 0x81f681f800000000, + 0xd0f7106800000000, 0x20f4a06900000000, 0x71f531f900000000, + 0xc0f3c06a00000000, 0x91f251fa00000000, 0x61f1e1fb00000000, + 0x30f0706b00000000, 0x01e901f500000000, 0x50e8906500000000, + 0xa0eb206400000000, 0xf1eab1f400000000, 0x40ec406700000000, + 0x11edd1f700000000, 0xe1ee61f600000000, 0xb0eff06600000000, + 0x80e3806100000000, 0xd1e211f100000000, 0x21e1a1f000000000, + 0x70e0306000000000, 0xc1e6c1f300000000, 0x90e7506300000000, + 0x60e4e06200000000, 0x31e571f200000000, 0x01d601ee00000000, + 0x50d7907e00000000, 0xa0d4207f00000000, 0xf1d5b1ef00000000, + 0x40d3407c00000000, 0x11d2d1ec00000000, 0xe1d161ed00000000, + 0xb0d0f07d00000000, 0x80dc807a00000000, 0xd1dd11ea00000000, + 0x21dea1eb00000000, 0x70df307b00000000, 0xc1d9c1e800000000, + 0x90d8507800000000, 0x60dbe07900000000, 0x31da71e900000000, + 0x00c3007700000000, 0x51c291e700000000, 0xa1c121e600000000, + 0xf0c0b07600000000, 0x41c641e500000000, 0x10c7d07500000000, + 0xe0c4607400000000, 0xb1c5f1e400000000, 0x81c981e300000000, + 0xd0c8107300000000, 0x20cba07200000000, 0x71ca31e200000000, + 0xc0ccc07100000000, 0x91cd51e100000000, 0x61cee1e000000000, + 0x30cf707000000000}, + {0x0000000000000000, 0x00c001bd00000000, 0x038000ca00000000, + 0x0340017700000000, 0x0500022400000000, 0x05c0039900000000, + 0x068002ee00000000, 0x0640035300000000, 0x0a00044800000000, + 0x0ac005f500000000, 0x0980048200000000, 0x0940053f00000000, + 0x0f00066c00000000, 0x0fc007d100000000, 0x0c8006a600000000, + 0x0c40071b00000000, 0x1400089000000000, 0x14c0092d00000000, + 0x1780085a00000000, 0x174009e700000000, 0x11000ab400000000, + 0x11c00b0900000000, 0x12800a7e00000000, 0x12400bc300000000, + 0x1e000cd800000000, 0x1ec00d6500000000, 0x1d800c1200000000, + 0x1d400daf00000000, 0x1b000efc00000000, 0x1bc00f4100000000, + 0x18800e3600000000, 0x18400f8b00000000, 0x2b00139000000000, + 0x2bc0122d00000000, 0x2880135a00000000, 0x284012e700000000, + 0x2e0011b400000000, 0x2ec0100900000000, 0x2d80117e00000000, + 0x2d4010c300000000, 0x210017d800000000, 0x21c0166500000000, + 0x2280171200000000, 0x224016af00000000, 0x240015fc00000000, + 0x24c0144100000000, 0x2780153600000000, 0x2740148b00000000, + 0x3f001b0000000000, 0x3fc01abd00000000, 0x3c801bca00000000, + 0x3c401a7700000000, 0x3a00192400000000, 0x3ac0189900000000, + 0x398019ee00000000, 0x3940185300000000, 0x35001f4800000000, + 0x35c01ef500000000, 0x36801f8200000000, 0x36401e3f00000000, + 0x30001d6c00000000, 0x30c01cd100000000, 0x33801da600000000, + 0x33401c1b00000000, 0x5500259000000000, 0x55c0242d00000000, + 0x5680255a00000000, 0x564024e700000000, 0x500027b400000000, + 0x50c0260900000000, 0x5380277e00000000, 0x534026c300000000, + 0x5f0021d800000000, 0x5fc0206500000000, 0x5c80211200000000, + 0x5c4020af00000000, 0x5a0023fc00000000, 0x5ac0224100000000, + 0x5980233600000000, 0x5940228b00000000, 0x41002d0000000000, + 0x41c02cbd00000000, 0x42802dca00000000, 0x42402c7700000000, + 0x44002f2400000000, 0x44c02e9900000000, 0x47802fee00000000, + 0x47402e5300000000, 0x4b00294800000000, 0x4bc028f500000000, + 0x4880298200000000, 0x4840283f00000000, 0x4e002b6c00000000, + 0x4ec02ad100000000, 0x4d802ba600000000, 0x4d402a1b00000000, + 0x7e00360000000000, 0x7ec037bd00000000, 0x7d8036ca00000000, + 0x7d40377700000000, 0x7b00342400000000, 0x7bc0359900000000, + 0x788034ee00000000, 0x7840355300000000, 0x7400324800000000, + 0x74c033f500000000, 0x7780328200000000, 0x7740333f00000000, + 0x7100306c00000000, 0x71c031d100000000, 0x728030a600000000, + 0x7240311b00000000, 0x6a003e9000000000, 0x6ac03f2d00000000, + 0x69803e5a00000000, 0x69403fe700000000, 0x6f003cb400000000, + 0x6fc03d0900000000, 0x6c803c7e00000000, 0x6c403dc300000000, + 0x60003ad800000000, 0x60c03b6500000000, 0x63803a1200000000, + 0x63403baf00000000, 0x650038fc00000000, 0x65c0394100000000, + 0x6680383600000000, 0x6640398b00000000, 0xa900499000000000, + 0xa9c0482d00000000, 0xaa80495a00000000, 0xaa4048e700000000, + 0xac004bb400000000, 0xacc04a0900000000, 0xaf804b7e00000000, + 0xaf404ac300000000, 0xa3004dd800000000, 0xa3c04c6500000000, + 0xa0804d1200000000, 0xa0404caf00000000, 0xa6004ffc00000000, + 0xa6c04e4100000000, 0xa5804f3600000000, 0xa5404e8b00000000, + 0xbd00410000000000, 0xbdc040bd00000000, 0xbe8041ca00000000, + 0xbe40407700000000, 0xb800432400000000, 0xb8c0429900000000, + 0xbb8043ee00000000, 0xbb40425300000000, 0xb700454800000000, + 0xb7c044f500000000, 0xb480458200000000, 0xb440443f00000000, + 0xb200476c00000000, 0xb2c046d100000000, 0xb18047a600000000, + 0xb140461b00000000, 0x82005a0000000000, 0x82c05bbd00000000, + 0x81805aca00000000, 0x81405b7700000000, 0x8700582400000000, + 0x87c0599900000000, 0x848058ee00000000, 0x8440595300000000, + 0x88005e4800000000, 0x88c05ff500000000, 0x8b805e8200000000, + 0x8b405f3f00000000, 0x8d005c6c00000000, 0x8dc05dd100000000, + 0x8e805ca600000000, 0x8e405d1b00000000, 0x9600529000000000, + 0x96c0532d00000000, 0x9580525a00000000, 0x954053e700000000, + 0x930050b400000000, 0x93c0510900000000, 0x9080507e00000000, + 0x904051c300000000, 0x9c0056d800000000, 0x9cc0576500000000, + 0x9f80561200000000, 0x9f4057af00000000, 0x990054fc00000000, + 0x99c0554100000000, 0x9a80543600000000, 0x9a40558b00000000, + 0xfc006c0000000000, 0xfcc06dbd00000000, 0xff806cca00000000, + 0xff406d7700000000, 0xf9006e2400000000, 0xf9c06f9900000000, + 0xfa806eee00000000, 0xfa406f5300000000, 0xf600684800000000, + 0xf6c069f500000000, 0xf580688200000000, 0xf540693f00000000, + 0xf3006a6c00000000, 0xf3c06bd100000000, 0xf0806aa600000000, + 0xf0406b1b00000000, 0xe800649000000000, 0xe8c0652d00000000, + 0xeb80645a00000000, 0xeb4065e700000000, 0xed0066b400000000, + 0xedc0670900000000, 0xee80667e00000000, 0xee4067c300000000, + 0xe20060d800000000, 0xe2c0616500000000, 0xe180601200000000, + 0xe14061af00000000, 0xe70062fc00000000, 0xe7c0634100000000, + 0xe480623600000000, 0xe440638b00000000, 0xd7007f9000000000, + 0xd7c07e2d00000000, 0xd4807f5a00000000, 0xd4407ee700000000, + 0xd2007db400000000, 0xd2c07c0900000000, 0xd1807d7e00000000, + 0xd1407cc300000000, 0xdd007bd800000000, 0xddc07a6500000000, + 0xde807b1200000000, 0xde407aaf00000000, 0xd80079fc00000000, + 0xd8c0784100000000, 0xdb80793600000000, 0xdb40788b00000000, + 0xc300770000000000, 0xc3c076bd00000000, 0xc08077ca00000000, + 0xc040767700000000, 0xc600752400000000, 0xc6c0749900000000, + 0xc58075ee00000000, 0xc540745300000000, 0xc900734800000000, + 0xc9c072f500000000, 0xca80738200000000, 0xca40723f00000000, + 0xcc00716c00000000, 0xccc070d100000000, 0xcf8071a600000000, + 0xcf40701b00000000}}; + +#else /* W == 4 */ + +static const crc_t crc_braid_table[][256] = { + {0x00000000, 0x6c90c100, 0xd9218200, 0xb5b14300, 0x02400403, + 0x6ed0c503, 0xdb618603, 0xb7f14703, 0x04800806, 0x6810c906, + 0xdda18a06, 0xb1314b06, 0x06c00c05, 0x6a50cd05, 0xdfe18e05, + 0xb3714f05, 0x0900100c, 0x6590d10c, 0xd021920c, 0xbcb1530c, + 0x0b40140f, 0x67d0d50f, 0xd261960f, 0xbef1570f, 0x0d80180a, + 0x6110d90a, 0xd4a19a0a, 0xb8315b0a, 0x0fc01c09, 0x6350dd09, + 0xd6e19e09, 0xba715f09, 0x12002018, 0x7e90e118, 0xcb21a218, + 0xa7b16318, 0x1040241b, 0x7cd0e51b, 0xc961a61b, 0xa5f1671b, + 0x1680281e, 0x7a10e91e, 0xcfa1aa1e, 0xa3316b1e, 0x14c02c1d, + 0x7850ed1d, 0xcde1ae1d, 0xa1716f1d, 0x1b003014, 0x7790f114, + 0xc221b214, 0xaeb17314, 0x19403417, 0x75d0f517, 0xc061b617, + 0xacf17717, 0x1f803812, 0x7310f912, 0xc6a1ba12, 0xaa317b12, + 0x1dc03c11, 0x7150fd11, 0xc4e1be11, 0xa8717f11, 0x24004030, + 0x48908130, 0xfd21c230, 0x91b10330, 0x26404433, 0x4ad08533, + 0xff61c633, 0x93f10733, 0x20804836, 0x4c108936, 0xf9a1ca36, + 0x95310b36, 0x22c04c35, 0x4e508d35, 0xfbe1ce35, 0x97710f35, + 0x2d00503c, 0x4190913c, 0xf421d23c, 0x98b1133c, 0x2f40543f, + 0x43d0953f, 0xf661d63f, 0x9af1173f, 0x2980583a, 0x4510993a, + 0xf0a1da3a, 0x9c311b3a, 0x2bc05c39, 0x47509d39, 0xf2e1de39, + 0x9e711f39, 0x36006028, 0x5a90a128, 0xef21e228, 0x83b12328, + 0x3440642b, 0x58d0a52b, 0xed61e62b, 0x81f1272b, 0x3280682e, + 0x5e10a92e, 0xeba1ea2e, 0x87312b2e, 0x30c06c2d, 0x5c50ad2d, + 0xe9e1ee2d, 0x85712f2d, 0x3f007024, 0x5390b124, 0xe621f224, + 0x8ab13324, 0x3d407427, 0x51d0b527, 0xe461f627, 0x88f13727, + 0x3b807822, 0x5710b922, 0xe2a1fa22, 0x8e313b22, 0x39c07c21, + 0x5550bd21, 0xe0e1fe21, 0x8c713f21, 0x48008060, 0x24904160, + 0x91210260, 0xfdb1c360, 0x4a408463, 0x26d04563, 0x93610663, + 0xfff1c763, 0x4c808866, 0x20104966, 0x95a10a66, 0xf931cb66, + 0x4ec08c65, 0x22504d65, 0x97e10e65, 0xfb71cf65, 0x4100906c, + 0x2d90516c, 0x9821126c, 0xf4b1d36c, 0x4340946f, 0x2fd0556f, + 0x9a61166f, 0xf6f1d76f, 0x4580986a, 0x2910596a, 0x9ca11a6a, + 0xf031db6a, 0x47c09c69, 0x2b505d69, 0x9ee11e69, 0xf271df69, + 0x5a00a078, 0x36906178, 0x83212278, 0xefb1e378, 0x5840a47b, + 0x34d0657b, 0x8161267b, 0xedf1e77b, 0x5e80a87e, 0x3210697e, + 0x87a12a7e, 0xeb31eb7e, 0x5cc0ac7d, 0x30506d7d, 0x85e12e7d, + 0xe971ef7d, 0x5300b074, 0x3f907174, 0x8a213274, 0xe6b1f374, + 0x5140b477, 0x3dd07577, 0x88613677, 0xe4f1f777, 0x5780b872, + 0x3b107972, 0x8ea13a72, 0xe231fb72, 0x55c0bc71, 0x39507d71, + 0x8ce13e71, 0xe071ff71, 0x6c00c050, 0x00900150, 0xb5214250, + 0xd9b18350, 0x6e40c453, 0x02d00553, 0xb7614653, 0xdbf18753, + 0x6880c856, 0x04100956, 0xb1a14a56, 0xdd318b56, 0x6ac0cc55, + 0x06500d55, 0xb3e14e55, 0xdf718f55, 0x6500d05c, 0x0990115c, + 0xbc21525c, 0xd0b1935c, 0x6740d45f, 0x0bd0155f, 0xbe61565f, + 0xd2f1975f, 0x6180d85a, 0x0d10195a, 0xb8a15a5a, 0xd4319b5a, + 0x63c0dc59, 0x0f501d59, 0xbae15e59, 0xd6719f59, 0x7e00e048, + 0x12902148, 0xa7216248, 0xcbb1a348, 0x7c40e44b, 0x10d0254b, + 0xa561664b, 0xc9f1a74b, 0x7a80e84e, 0x1610294e, 0xa3a16a4e, + 0xcf31ab4e, 0x78c0ec4d, 0x14502d4d, 0xa1e16e4d, 0xcd71af4d, + 0x7700f044, 0x1b903144, 0xae217244, 0xc2b1b344, 0x7540f447, + 0x19d03547, 0xac617647, 0xc0f1b747, 0x7380f842, 0x1f103942, + 0xaaa17a42, 0xc631bb42, 0x71c0fc41, 0x1d503d41, 0xa8e17e41, + 0xc471bf41}, + {0x00000000, 0x900100c0, 0x90010183, 0x00000143, 0x90010305, + 0x000003c5, 0x00000286, 0x90010246, 0x90010609, 0x000006c9, + 0x0000078a, 0x9001074a, 0x0000050c, 0x900105cc, 0x9001048f, + 0x0000044f, 0x90010c11, 0x00000cd1, 0x00000d92, 0x90010d52, + 0x00000f14, 0x90010fd4, 0x90010e97, 0x00000e57, 0x00000a18, + 0x90010ad8, 0x90010b9b, 0x00000b5b, 0x9001091d, 0x000009dd, + 0x0000089e, 0x9001085e, 0x90011821, 0x000018e1, 0x000019a2, + 0x90011962, 0x00001b24, 0x90011be4, 0x90011aa7, 0x00001a67, + 0x00001e28, 0x90011ee8, 0x90011fab, 0x00001f6b, 0x90011d2d, + 0x00001ded, 0x00001cae, 0x90011c6e, 0x00001430, 0x900114f0, + 0x900115b3, 0x00001573, 0x90011735, 0x000017f5, 0x000016b6, + 0x90011676, 0x90011239, 0x000012f9, 0x000013ba, 0x9001137a, + 0x0000113c, 0x900111fc, 0x900110bf, 0x0000107f, 0x90013041, + 0x00003081, 0x000031c2, 0x90013102, 0x00003344, 0x90013384, + 0x900132c7, 0x00003207, 0x00003648, 0x90013688, 0x900137cb, + 0x0000370b, 0x9001354d, 0x0000358d, 0x000034ce, 0x9001340e, + 0x00003c50, 0x90013c90, 0x90013dd3, 0x00003d13, 0x90013f55, + 0x00003f95, 0x00003ed6, 0x90013e16, 0x90013a59, 0x00003a99, + 0x00003bda, 0x90013b1a, 0x0000395c, 0x9001399c, 0x900138df, + 0x0000381f, 0x00002860, 0x900128a0, 0x900129e3, 0x00002923, + 0x90012b65, 0x00002ba5, 0x00002ae6, 0x90012a26, 0x90012e69, + 0x00002ea9, 0x00002fea, 0x90012f2a, 0x00002d6c, 0x90012dac, + 0x90012cef, 0x00002c2f, 0x90012471, 0x000024b1, 0x000025f2, + 0x90012532, 0x00002774, 0x900127b4, 0x900126f7, 0x00002637, + 0x00002278, 0x900122b8, 0x900123fb, 0x0000233b, 0x9001217d, + 0x000021bd, 0x000020fe, 0x9001203e, 0x90016081, 0x00006041, + 0x00006102, 0x900161c2, 0x00006384, 0x90016344, 0x90016207, + 0x000062c7, 0x00006688, 0x90016648, 0x9001670b, 0x000067cb, + 0x9001658d, 0x0000654d, 0x0000640e, 0x900164ce, 0x00006c90, + 0x90016c50, 0x90016d13, 0x00006dd3, 0x90016f95, 0x00006f55, + 0x00006e16, 0x90016ed6, 0x90016a99, 0x00006a59, 0x00006b1a, + 0x90016bda, 0x0000699c, 0x9001695c, 0x9001681f, 0x000068df, + 0x000078a0, 0x90017860, 0x90017923, 0x000079e3, 0x90017ba5, + 0x00007b65, 0x00007a26, 0x90017ae6, 0x90017ea9, 0x00007e69, + 0x00007f2a, 0x90017fea, 0x00007dac, 0x90017d6c, 0x90017c2f, + 0x00007cef, 0x900174b1, 0x00007471, 0x00007532, 0x900175f2, + 0x000077b4, 0x90017774, 0x90017637, 0x000076f7, 0x000072b8, + 0x90017278, 0x9001733b, 0x000073fb, 0x900171bd, 0x0000717d, + 0x0000703e, 0x900170fe, 0x000050c0, 0x90015000, 0x90015143, + 0x00005183, 0x900153c5, 0x00005305, 0x00005246, 0x90015286, + 0x900156c9, 0x00005609, 0x0000574a, 0x9001578a, 0x000055cc, + 0x9001550c, 0x9001544f, 0x0000548f, 0x90015cd1, 0x00005c11, + 0x00005d52, 0x90015d92, 0x00005fd4, 0x90015f14, 0x90015e57, + 0x00005e97, 0x00005ad8, 0x90015a18, 0x90015b5b, 0x00005b9b, + 0x900159dd, 0x0000591d, 0x0000585e, 0x9001589e, 0x900148e1, + 0x00004821, 0x00004962, 0x900149a2, 0x00004be4, 0x90014b24, + 0x90014a67, 0x00004aa7, 0x00004ee8, 0x90014e28, 0x90014f6b, + 0x00004fab, 0x90014ded, 0x00004d2d, 0x00004c6e, 0x90014cae, + 0x000044f0, 0x90014430, 0x90014573, 0x000045b3, 0x900147f5, + 0x00004735, 0x00004676, 0x900146b6, 0x900142f9, 0x00004239, + 0x0000437a, 0x900143ba, 0x000041fc, 0x9001413c, 0x9001407f, + 0x000040bf}, + {0x00000000, 0x9001c101, 0x90008201, 0x00014300, 0x90020401, + 0x0003c500, 0x00028600, 0x90034701, 0x90070801, 0x0006c900, + 0x00078a00, 0x90064b01, 0x00050c00, 0x9004cd01, 0x90058e01, + 0x00044f00, 0x900d1001, 0x000cd100, 0x000d9200, 0x900c5301, + 0x000f1400, 0x900ed501, 0x900f9601, 0x000e5700, 0x000a1800, + 0x900bd901, 0x900a9a01, 0x000b5b00, 0x90081c01, 0x0009dd00, + 0x00089e00, 0x90095f01, 0x90192001, 0x0018e100, 0x0019a200, + 0x90186301, 0x001b2400, 0x901ae501, 0x901ba601, 0x001a6700, + 0x001e2800, 0x901fe901, 0x901eaa01, 0x001f6b00, 0x901c2c01, + 0x001ded00, 0x001cae00, 0x901d6f01, 0x00143000, 0x9015f101, + 0x9014b201, 0x00157300, 0x90163401, 0x0017f500, 0x0016b600, + 0x90177701, 0x90133801, 0x0012f900, 0x0013ba00, 0x90127b01, + 0x00113c00, 0x9010fd01, 0x9011be01, 0x00107f00, 0x90314001, + 0x00308100, 0x0031c200, 0x90300301, 0x00334400, 0x90328501, + 0x9033c601, 0x00320700, 0x00364800, 0x90378901, 0x9036ca01, + 0x00370b00, 0x90344c01, 0x00358d00, 0x0034ce00, 0x90350f01, + 0x003c5000, 0x903d9101, 0x903cd201, 0x003d1300, 0x903e5401, + 0x003f9500, 0x003ed600, 0x903f1701, 0x903b5801, 0x003a9900, + 0x003bda00, 0x903a1b01, 0x00395c00, 0x90389d01, 0x9039de01, + 0x00381f00, 0x00286000, 0x9029a101, 0x9028e201, 0x00292300, + 0x902a6401, 0x002ba500, 0x002ae600, 0x902b2701, 0x902f6801, + 0x002ea900, 0x002fea00, 0x902e2b01, 0x002d6c00, 0x902cad01, + 0x902dee01, 0x002c2f00, 0x90257001, 0x0024b100, 0x0025f200, + 0x90243301, 0x00277400, 0x9026b501, 0x9027f601, 0x00263700, + 0x00227800, 0x9023b901, 0x9022fa01, 0x00233b00, 0x90207c01, + 0x0021bd00, 0x0020fe00, 0x90213f01, 0x90618001, 0x00604100, + 0x00610200, 0x9060c301, 0x00638400, 0x90624501, 0x90630601, + 0x0062c700, 0x00668800, 0x90674901, 0x90660a01, 0x0067cb00, + 0x90648c01, 0x00654d00, 0x00640e00, 0x9065cf01, 0x006c9000, + 0x906d5101, 0x906c1201, 0x006dd300, 0x906e9401, 0x006f5500, + 0x006e1600, 0x906fd701, 0x906b9801, 0x006a5900, 0x006b1a00, + 0x906adb01, 0x00699c00, 0x90685d01, 0x90691e01, 0x0068df00, + 0x0078a000, 0x90796101, 0x90782201, 0x0079e300, 0x907aa401, + 0x007b6500, 0x007a2600, 0x907be701, 0x907fa801, 0x007e6900, + 0x007f2a00, 0x907eeb01, 0x007dac00, 0x907c6d01, 0x907d2e01, + 0x007cef00, 0x9075b001, 0x00747100, 0x00753200, 0x9074f301, + 0x0077b400, 0x90767501, 0x90773601, 0x0076f700, 0x0072b800, + 0x90737901, 0x90723a01, 0x0073fb00, 0x9070bc01, 0x00717d00, + 0x00703e00, 0x9071ff01, 0x0050c000, 0x90510101, 0x90504201, + 0x00518300, 0x9052c401, 0x00530500, 0x00524600, 0x90538701, + 0x9057c801, 0x00560900, 0x00574a00, 0x90568b01, 0x0055cc00, + 0x90540d01, 0x90554e01, 0x00548f00, 0x905dd001, 0x005c1100, + 0x005d5200, 0x905c9301, 0x005fd400, 0x905e1501, 0x905f5601, + 0x005e9700, 0x005ad800, 0x905b1901, 0x905a5a01, 0x005b9b00, + 0x9058dc01, 0x00591d00, 0x00585e00, 0x90599f01, 0x9049e001, + 0x00482100, 0x00496200, 0x9048a301, 0x004be400, 0x904a2501, + 0x904b6601, 0x004aa700, 0x004ee800, 0x904f2901, 0x904e6a01, + 0x004fab00, 0x904cec01, 0x004d2d00, 0x004c6e00, 0x904daf01, + 0x0044f000, 0x90453101, 0x90447201, 0x0045b300, 0x9046f401, + 0x00473500, 0x00467600, 0x9047b701, 0x9043f801, 0x00423900, + 0x00437a00, 0x9042bb01, 0x0041fc00, 0x90403d01, 0x90417e01, + 0x0040bf00}, + {0x00000000, 0x90c00001, 0x91830001, 0x01430000, 0x93050001, + 0x03c50000, 0x02860000, 0x92460001, 0x96090001, 0x06c90000, + 0x078a0000, 0x974a0001, 0x050c0000, 0x95cc0001, 0x948f0001, + 0x044f0000, 0x9c110001, 0x0cd10000, 0x0d920000, 0x9d520001, + 0x0f140000, 0x9fd40001, 0x9e970001, 0x0e570000, 0x0a180000, + 0x9ad80001, 0x9b9b0001, 0x0b5b0000, 0x991d0001, 0x09dd0000, + 0x089e0000, 0x985e0001, 0x88210001, 0x18e10000, 0x19a20000, + 0x89620001, 0x1b240000, 0x8be40001, 0x8aa70001, 0x1a670000, + 0x1e280000, 0x8ee80001, 0x8fab0001, 0x1f6b0000, 0x8d2d0001, + 0x1ded0000, 0x1cae0000, 0x8c6e0001, 0x14300000, 0x84f00001, + 0x85b30001, 0x15730000, 0x87350001, 0x17f50000, 0x16b60000, + 0x86760001, 0x82390001, 0x12f90000, 0x13ba0000, 0x837a0001, + 0x113c0000, 0x81fc0001, 0x80bf0001, 0x107f0000, 0xa0410001, + 0x30810000, 0x31c20000, 0xa1020001, 0x33440000, 0xa3840001, + 0xa2c70001, 0x32070000, 0x36480000, 0xa6880001, 0xa7cb0001, + 0x370b0000, 0xa54d0001, 0x358d0000, 0x34ce0000, 0xa40e0001, + 0x3c500000, 0xac900001, 0xadd30001, 0x3d130000, 0xaf550001, + 0x3f950000, 0x3ed60000, 0xae160001, 0xaa590001, 0x3a990000, + 0x3bda0000, 0xab1a0001, 0x395c0000, 0xa99c0001, 0xa8df0001, + 0x381f0000, 0x28600000, 0xb8a00001, 0xb9e30001, 0x29230000, + 0xbb650001, 0x2ba50000, 0x2ae60000, 0xba260001, 0xbe690001, + 0x2ea90000, 0x2fea0000, 0xbf2a0001, 0x2d6c0000, 0xbdac0001, + 0xbcef0001, 0x2c2f0000, 0xb4710001, 0x24b10000, 0x25f20000, + 0xb5320001, 0x27740000, 0xb7b40001, 0xb6f70001, 0x26370000, + 0x22780000, 0xb2b80001, 0xb3fb0001, 0x233b0000, 0xb17d0001, + 0x21bd0000, 0x20fe0000, 0xb03e0001, 0xf0810001, 0x60410000, + 0x61020000, 0xf1c20001, 0x63840000, 0xf3440001, 0xf2070001, + 0x62c70000, 0x66880000, 0xf6480001, 0xf70b0001, 0x67cb0000, + 0xf58d0001, 0x654d0000, 0x640e0000, 0xf4ce0001, 0x6c900000, + 0xfc500001, 0xfd130001, 0x6dd30000, 0xff950001, 0x6f550000, + 0x6e160000, 0xfed60001, 0xfa990001, 0x6a590000, 0x6b1a0000, + 0xfbda0001, 0x699c0000, 0xf95c0001, 0xf81f0001, 0x68df0000, + 0x78a00000, 0xe8600001, 0xe9230001, 0x79e30000, 0xeba50001, + 0x7b650000, 0x7a260000, 0xeae60001, 0xeea90001, 0x7e690000, + 0x7f2a0000, 0xefea0001, 0x7dac0000, 0xed6c0001, 0xec2f0001, + 0x7cef0000, 0xe4b10001, 0x74710000, 0x75320000, 0xe5f20001, + 0x77b40000, 0xe7740001, 0xe6370001, 0x76f70000, 0x72b80000, + 0xe2780001, 0xe33b0001, 0x73fb0000, 0xe1bd0001, 0x717d0000, + 0x703e0000, 0xe0fe0001, 0x50c00000, 0xc0000001, 0xc1430001, + 0x51830000, 0xc3c50001, 0x53050000, 0x52460000, 0xc2860001, + 0xc6c90001, 0x56090000, 0x574a0000, 0xc78a0001, 0x55cc0000, + 0xc50c0001, 0xc44f0001, 0x548f0000, 0xccd10001, 0x5c110000, + 0x5d520000, 0xcd920001, 0x5fd40000, 0xcf140001, 0xce570001, + 0x5e970000, 0x5ad80000, 0xca180001, 0xcb5b0001, 0x5b9b0000, + 0xc9dd0001, 0x591d0000, 0x585e0000, 0xc89e0001, 0xd8e10001, + 0x48210000, 0x49620000, 0xd9a20001, 0x4be40000, 0xdb240001, + 0xda670001, 0x4aa70000, 0x4ee80000, 0xde280001, 0xdf6b0001, + 0x4fab0000, 0xdded0001, 0x4d2d0000, 0x4c6e0000, 0xdcae0001, + 0x44f00000, 0xd4300001, 0xd5730001, 0x45b30000, 0xd7f50001, + 0x47350000, 0x46760000, 0xd6b60001, 0xd2f90001, 0x42390000, + 0x437a0000, 0xd3ba0001, 0x41fc0000, 0xd13c0001, 0xd07f0001, + 0x40bf0000}}; + +static const word_t crc_braid_big_table[][256] = { + {0x00000000, 0x0100c090, 0x01008391, 0x00004301, 0x01000593, + 0x0000c503, 0x00008602, 0x01004692, 0x01000996, 0x0000c906, + 0x00008a07, 0x01004a97, 0x00000c05, 0x0100cc95, 0x01008f94, + 0x00004f04, 0x0100119c, 0x0000d10c, 0x0000920d, 0x0100529d, + 0x0000140f, 0x0100d49f, 0x0100979e, 0x0000570e, 0x0000180a, + 0x0100d89a, 0x01009b9b, 0x00005b0b, 0x01001d99, 0x0000dd09, + 0x00009e08, 0x01005e98, 0x01002188, 0x0000e118, 0x0000a219, + 0x01006289, 0x0000241b, 0x0100e48b, 0x0100a78a, 0x0000671a, + 0x0000281e, 0x0100e88e, 0x0100ab8f, 0x00006b1f, 0x01002d8d, + 0x0000ed1d, 0x0000ae1c, 0x01006e8c, 0x00003014, 0x0100f084, + 0x0100b385, 0x00007315, 0x01003587, 0x0000f517, 0x0000b616, + 0x01007686, 0x01003982, 0x0000f912, 0x0000ba13, 0x01007a83, + 0x00003c11, 0x0100fc81, 0x0100bf80, 0x00007f10, 0x010041a0, + 0x00008130, 0x0000c231, 0x010002a1, 0x00004433, 0x010084a3, + 0x0100c7a2, 0x00000732, 0x00004836, 0x010088a6, 0x0100cba7, + 0x00000b37, 0x01004da5, 0x00008d35, 0x0000ce34, 0x01000ea4, + 0x0000503c, 0x010090ac, 0x0100d3ad, 0x0000133d, 0x010055af, + 0x0000953f, 0x0000d63e, 0x010016ae, 0x010059aa, 0x0000993a, + 0x0000da3b, 0x01001aab, 0x00005c39, 0x01009ca9, 0x0100dfa8, + 0x00001f38, 0x00006028, 0x0100a0b8, 0x0100e3b9, 0x00002329, + 0x010065bb, 0x0000a52b, 0x0000e62a, 0x010026ba, 0x010069be, + 0x0000a92e, 0x0000ea2f, 0x01002abf, 0x00006c2d, 0x0100acbd, + 0x0100efbc, 0x00002f2c, 0x010071b4, 0x0000b124, 0x0000f225, + 0x010032b5, 0x00007427, 0x0100b4b7, 0x0100f7b6, 0x00003726, + 0x00007822, 0x0100b8b2, 0x0100fbb3, 0x00003b23, 0x01007db1, + 0x0000bd21, 0x0000fe20, 0x01003eb0, 0x010081f0, 0x00004160, + 0x00000261, 0x0100c2f1, 0x00008463, 0x010044f3, 0x010007f2, + 0x0000c762, 0x00008866, 0x010048f6, 0x01000bf7, 0x0000cb67, + 0x01008df5, 0x00004d65, 0x00000e64, 0x0100cef4, 0x0000906c, + 0x010050fc, 0x010013fd, 0x0000d36d, 0x010095ff, 0x0000556f, + 0x0000166e, 0x0100d6fe, 0x010099fa, 0x0000596a, 0x00001a6b, + 0x0100dafb, 0x00009c69, 0x01005cf9, 0x01001ff8, 0x0000df68, + 0x0000a078, 0x010060e8, 0x010023e9, 0x0000e379, 0x0100a5eb, + 0x0000657b, 0x0000267a, 0x0100e6ea, 0x0100a9ee, 0x0000697e, + 0x00002a7f, 0x0100eaef, 0x0000ac7d, 0x01006ced, 0x01002fec, + 0x0000ef7c, 0x0100b1e4, 0x00007174, 0x00003275, 0x0100f2e5, + 0x0000b477, 0x010074e7, 0x010037e6, 0x0000f776, 0x0000b872, + 0x010078e2, 0x01003be3, 0x0000fb73, 0x0100bde1, 0x00007d71, + 0x00003e70, 0x0100fee0, 0x0000c050, 0x010000c0, 0x010043c1, + 0x00008351, 0x0100c5c3, 0x00000553, 0x00004652, 0x010086c2, + 0x0100c9c6, 0x00000956, 0x00004a57, 0x01008ac7, 0x0000cc55, + 0x01000cc5, 0x01004fc4, 0x00008f54, 0x0100d1cc, 0x0000115c, + 0x0000525d, 0x010092cd, 0x0000d45f, 0x010014cf, 0x010057ce, + 0x0000975e, 0x0000d85a, 0x010018ca, 0x01005bcb, 0x00009b5b, + 0x0100ddc9, 0x00001d59, 0x00005e58, 0x01009ec8, 0x0100e1d8, + 0x00002148, 0x00006249, 0x0100a2d9, 0x0000e44b, 0x010024db, + 0x010067da, 0x0000a74a, 0x0000e84e, 0x010028de, 0x01006bdf, + 0x0000ab4f, 0x0100eddd, 0x00002d4d, 0x00006e4c, 0x0100aedc, + 0x0000f044, 0x010030d4, 0x010073d5, 0x0000b345, 0x0100f5d7, + 0x00003547, 0x00007646, 0x0100b6d6, 0x0100f9d2, 0x00003942, + 0x00007a43, 0x0100bad3, 0x0000fc41, 0x01003cd1, 0x01007fd0, + 0x0000bf40}, + {0x00000000, 0x01c10190, 0x01820090, 0x00430100, 0x01040290, + 0x00c50300, 0x00860200, 0x01470390, 0x01080790, 0x00c90600, + 0x008a0700, 0x014b0690, 0x000c0500, 0x01cd0490, 0x018e0590, + 0x004f0400, 0x01100d90, 0x00d10c00, 0x00920d00, 0x01530c90, + 0x00140f00, 0x01d50e90, 0x01960f90, 0x00570e00, 0x00180a00, + 0x01d90b90, 0x019a0a90, 0x005b0b00, 0x011c0890, 0x00dd0900, + 0x009e0800, 0x015f0990, 0x01201990, 0x00e11800, 0x00a21900, + 0x01631890, 0x00241b00, 0x01e51a90, 0x01a61b90, 0x00671a00, + 0x00281e00, 0x01e91f90, 0x01aa1e90, 0x006b1f00, 0x012c1c90, + 0x00ed1d00, 0x00ae1c00, 0x016f1d90, 0x00301400, 0x01f11590, + 0x01b21490, 0x00731500, 0x01341690, 0x00f51700, 0x00b61600, + 0x01771790, 0x01381390, 0x00f91200, 0x00ba1300, 0x017b1290, + 0x003c1100, 0x01fd1090, 0x01be1190, 0x007f1000, 0x01403190, + 0x00813000, 0x00c23100, 0x01033090, 0x00443300, 0x01853290, + 0x01c63390, 0x00073200, 0x00483600, 0x01893790, 0x01ca3690, + 0x000b3700, 0x014c3490, 0x008d3500, 0x00ce3400, 0x010f3590, + 0x00503c00, 0x01913d90, 0x01d23c90, 0x00133d00, 0x01543e90, + 0x00953f00, 0x00d63e00, 0x01173f90, 0x01583b90, 0x00993a00, + 0x00da3b00, 0x011b3a90, 0x005c3900, 0x019d3890, 0x01de3990, + 0x001f3800, 0x00602800, 0x01a12990, 0x01e22890, 0x00232900, + 0x01642a90, 0x00a52b00, 0x00e62a00, 0x01272b90, 0x01682f90, + 0x00a92e00, 0x00ea2f00, 0x012b2e90, 0x006c2d00, 0x01ad2c90, + 0x01ee2d90, 0x002f2c00, 0x01702590, 0x00b12400, 0x00f22500, + 0x01332490, 0x00742700, 0x01b52690, 0x01f62790, 0x00372600, + 0x00782200, 0x01b92390, 0x01fa2290, 0x003b2300, 0x017c2090, + 0x00bd2100, 0x00fe2000, 0x013f2190, 0x01806190, 0x00416000, + 0x00026100, 0x01c36090, 0x00846300, 0x01456290, 0x01066390, + 0x00c76200, 0x00886600, 0x01496790, 0x010a6690, 0x00cb6700, + 0x018c6490, 0x004d6500, 0x000e6400, 0x01cf6590, 0x00906c00, + 0x01516d90, 0x01126c90, 0x00d36d00, 0x01946e90, 0x00556f00, + 0x00166e00, 0x01d76f90, 0x01986b90, 0x00596a00, 0x001a6b00, + 0x01db6a90, 0x009c6900, 0x015d6890, 0x011e6990, 0x00df6800, + 0x00a07800, 0x01617990, 0x01227890, 0x00e37900, 0x01a47a90, + 0x00657b00, 0x00267a00, 0x01e77b90, 0x01a87f90, 0x00697e00, + 0x002a7f00, 0x01eb7e90, 0x00ac7d00, 0x016d7c90, 0x012e7d90, + 0x00ef7c00, 0x01b07590, 0x00717400, 0x00327500, 0x01f37490, + 0x00b47700, 0x01757690, 0x01367790, 0x00f77600, 0x00b87200, + 0x01797390, 0x013a7290, 0x00fb7300, 0x01bc7090, 0x007d7100, + 0x003e7000, 0x01ff7190, 0x00c05000, 0x01015190, 0x01425090, + 0x00835100, 0x01c45290, 0x00055300, 0x00465200, 0x01875390, + 0x01c85790, 0x00095600, 0x004a5700, 0x018b5690, 0x00cc5500, + 0x010d5490, 0x014e5590, 0x008f5400, 0x01d05d90, 0x00115c00, + 0x00525d00, 0x01935c90, 0x00d45f00, 0x01155e90, 0x01565f90, + 0x00975e00, 0x00d85a00, 0x01195b90, 0x015a5a90, 0x009b5b00, + 0x01dc5890, 0x001d5900, 0x005e5800, 0x019f5990, 0x01e04990, + 0x00214800, 0x00624900, 0x01a34890, 0x00e44b00, 0x01254a90, + 0x01664b90, 0x00a74a00, 0x00e84e00, 0x01294f90, 0x016a4e90, + 0x00ab4f00, 0x01ec4c90, 0x002d4d00, 0x006e4c00, 0x01af4d90, + 0x00f04400, 0x01314590, 0x01724490, 0x00b34500, 0x01f44690, + 0x00354700, 0x00764600, 0x01b74790, 0x01f84390, 0x00394200, + 0x007a4300, 0x01bb4290, 0x00fc4100, 0x013d4090, 0x017e4190, + 0x00bf4000}, + {0x00000000, 0xc0000190, 0x83010190, 0x43010000, 0x05030190, + 0xc5030000, 0x86020000, 0x46020190, 0x09060190, 0xc9060000, + 0x8a070000, 0x4a070190, 0x0c050000, 0xcc050190, 0x8f040190, + 0x4f040000, 0x110c0190, 0xd10c0000, 0x920d0000, 0x520d0190, + 0x140f0000, 0xd40f0190, 0x970e0190, 0x570e0000, 0x180a0000, + 0xd80a0190, 0x9b0b0190, 0x5b0b0000, 0x1d090190, 0xdd090000, + 0x9e080000, 0x5e080190, 0x21180190, 0xe1180000, 0xa2190000, + 0x62190190, 0x241b0000, 0xe41b0190, 0xa71a0190, 0x671a0000, + 0x281e0000, 0xe81e0190, 0xab1f0190, 0x6b1f0000, 0x2d1d0190, + 0xed1d0000, 0xae1c0000, 0x6e1c0190, 0x30140000, 0xf0140190, + 0xb3150190, 0x73150000, 0x35170190, 0xf5170000, 0xb6160000, + 0x76160190, 0x39120190, 0xf9120000, 0xba130000, 0x7a130190, + 0x3c110000, 0xfc110190, 0xbf100190, 0x7f100000, 0x41300190, + 0x81300000, 0xc2310000, 0x02310190, 0x44330000, 0x84330190, + 0xc7320190, 0x07320000, 0x48360000, 0x88360190, 0xcb370190, + 0x0b370000, 0x4d350190, 0x8d350000, 0xce340000, 0x0e340190, + 0x503c0000, 0x903c0190, 0xd33d0190, 0x133d0000, 0x553f0190, + 0x953f0000, 0xd63e0000, 0x163e0190, 0x593a0190, 0x993a0000, + 0xda3b0000, 0x1a3b0190, 0x5c390000, 0x9c390190, 0xdf380190, + 0x1f380000, 0x60280000, 0xa0280190, 0xe3290190, 0x23290000, + 0x652b0190, 0xa52b0000, 0xe62a0000, 0x262a0190, 0x692e0190, + 0xa92e0000, 0xea2f0000, 0x2a2f0190, 0x6c2d0000, 0xac2d0190, + 0xef2c0190, 0x2f2c0000, 0x71240190, 0xb1240000, 0xf2250000, + 0x32250190, 0x74270000, 0xb4270190, 0xf7260190, 0x37260000, + 0x78220000, 0xb8220190, 0xfb230190, 0x3b230000, 0x7d210190, + 0xbd210000, 0xfe200000, 0x3e200190, 0x81600190, 0x41600000, + 0x02610000, 0xc2610190, 0x84630000, 0x44630190, 0x07620190, + 0xc7620000, 0x88660000, 0x48660190, 0x0b670190, 0xcb670000, + 0x8d650190, 0x4d650000, 0x0e640000, 0xce640190, 0x906c0000, + 0x506c0190, 0x136d0190, 0xd36d0000, 0x956f0190, 0x556f0000, + 0x166e0000, 0xd66e0190, 0x996a0190, 0x596a0000, 0x1a6b0000, + 0xda6b0190, 0x9c690000, 0x5c690190, 0x1f680190, 0xdf680000, + 0xa0780000, 0x60780190, 0x23790190, 0xe3790000, 0xa57b0190, + 0x657b0000, 0x267a0000, 0xe67a0190, 0xa97e0190, 0x697e0000, + 0x2a7f0000, 0xea7f0190, 0xac7d0000, 0x6c7d0190, 0x2f7c0190, + 0xef7c0000, 0xb1740190, 0x71740000, 0x32750000, 0xf2750190, + 0xb4770000, 0x74770190, 0x37760190, 0xf7760000, 0xb8720000, + 0x78720190, 0x3b730190, 0xfb730000, 0xbd710190, 0x7d710000, + 0x3e700000, 0xfe700190, 0xc0500000, 0x00500190, 0x43510190, + 0x83510000, 0xc5530190, 0x05530000, 0x46520000, 0x86520190, + 0xc9560190, 0x09560000, 0x4a570000, 0x8a570190, 0xcc550000, + 0x0c550190, 0x4f540190, 0x8f540000, 0xd15c0190, 0x115c0000, + 0x525d0000, 0x925d0190, 0xd45f0000, 0x145f0190, 0x575e0190, + 0x975e0000, 0xd85a0000, 0x185a0190, 0x5b5b0190, 0x9b5b0000, + 0xdd590190, 0x1d590000, 0x5e580000, 0x9e580190, 0xe1480190, + 0x21480000, 0x62490000, 0xa2490190, 0xe44b0000, 0x244b0190, + 0x674a0190, 0xa74a0000, 0xe84e0000, 0x284e0190, 0x6b4f0190, + 0xab4f0000, 0xed4d0190, 0x2d4d0000, 0x6e4c0000, 0xae4c0190, + 0xf0440000, 0x30440190, 0x73450190, 0xb3450000, 0xf5470190, + 0x35470000, 0x76460000, 0xb6460190, 0xf9420190, 0x39420000, + 0x7a430000, 0xba430190, 0xfc410000, 0x3c410190, 0x7f400190, + 0xbf400000}, + {0x00000000, 0x00c1906c, 0x008221d9, 0x0043b1b5, 0x03044002, + 0x03c5d06e, 0x038661db, 0x0347f1b7, 0x06088004, 0x06c91068, + 0x068aa1dd, 0x064b31b1, 0x050cc006, 0x05cd506a, 0x058ee1df, + 0x054f71b3, 0x0c100009, 0x0cd19065, 0x0c9221d0, 0x0c53b1bc, + 0x0f14400b, 0x0fd5d067, 0x0f9661d2, 0x0f57f1be, 0x0a18800d, + 0x0ad91061, 0x0a9aa1d4, 0x0a5b31b8, 0x091cc00f, 0x09dd5063, + 0x099ee1d6, 0x095f71ba, 0x18200012, 0x18e1907e, 0x18a221cb, + 0x1863b1a7, 0x1b244010, 0x1be5d07c, 0x1ba661c9, 0x1b67f1a5, + 0x1e288016, 0x1ee9107a, 0x1eaaa1cf, 0x1e6b31a3, 0x1d2cc014, + 0x1ded5078, 0x1daee1cd, 0x1d6f71a1, 0x1430001b, 0x14f19077, + 0x14b221c2, 0x1473b1ae, 0x17344019, 0x17f5d075, 0x17b661c0, + 0x1777f1ac, 0x1238801f, 0x12f91073, 0x12baa1c6, 0x127b31aa, + 0x113cc01d, 0x11fd5071, 0x11bee1c4, 0x117f71a8, 0x30400024, + 0x30819048, 0x30c221fd, 0x3003b191, 0x33444026, 0x3385d04a, + 0x33c661ff, 0x3307f193, 0x36488020, 0x3689104c, 0x36caa1f9, + 0x360b3195, 0x354cc022, 0x358d504e, 0x35cee1fb, 0x350f7197, + 0x3c50002d, 0x3c919041, 0x3cd221f4, 0x3c13b198, 0x3f54402f, + 0x3f95d043, 0x3fd661f6, 0x3f17f19a, 0x3a588029, 0x3a991045, + 0x3adaa1f0, 0x3a1b319c, 0x395cc02b, 0x399d5047, 0x39dee1f2, + 0x391f719e, 0x28600036, 0x28a1905a, 0x28e221ef, 0x2823b183, + 0x2b644034, 0x2ba5d058, 0x2be661ed, 0x2b27f181, 0x2e688032, + 0x2ea9105e, 0x2eeaa1eb, 0x2e2b3187, 0x2d6cc030, 0x2dad505c, + 0x2deee1e9, 0x2d2f7185, 0x2470003f, 0x24b19053, 0x24f221e6, + 0x2433b18a, 0x2774403d, 0x27b5d051, 0x27f661e4, 0x2737f188, + 0x2278803b, 0x22b91057, 0x22faa1e2, 0x223b318e, 0x217cc039, + 0x21bd5055, 0x21fee1e0, 0x213f718c, 0x60800048, 0x60419024, + 0x60022191, 0x60c3b1fd, 0x6384404a, 0x6345d026, 0x63066193, + 0x63c7f1ff, 0x6688804c, 0x66491020, 0x660aa195, 0x66cb31f9, + 0x658cc04e, 0x654d5022, 0x650ee197, 0x65cf71fb, 0x6c900041, + 0x6c51902d, 0x6c122198, 0x6cd3b1f4, 0x6f944043, 0x6f55d02f, + 0x6f16619a, 0x6fd7f1f6, 0x6a988045, 0x6a591029, 0x6a1aa19c, + 0x6adb31f0, 0x699cc047, 0x695d502b, 0x691ee19e, 0x69df71f2, + 0x78a0005a, 0x78619036, 0x78222183, 0x78e3b1ef, 0x7ba44058, + 0x7b65d034, 0x7b266181, 0x7be7f1ed, 0x7ea8805e, 0x7e691032, + 0x7e2aa187, 0x7eeb31eb, 0x7dacc05c, 0x7d6d5030, 0x7d2ee185, + 0x7def71e9, 0x74b00053, 0x7471903f, 0x7432218a, 0x74f3b1e6, + 0x77b44051, 0x7775d03d, 0x77366188, 0x77f7f1e4, 0x72b88057, + 0x7279103b, 0x723aa18e, 0x72fb31e2, 0x71bcc055, 0x717d5039, + 0x713ee18c, 0x71ff71e0, 0x50c0006c, 0x50019000, 0x504221b5, + 0x5083b1d9, 0x53c4406e, 0x5305d002, 0x534661b7, 0x5387f1db, + 0x56c88068, 0x56091004, 0x564aa1b1, 0x568b31dd, 0x55ccc06a, + 0x550d5006, 0x554ee1b3, 0x558f71df, 0x5cd00065, 0x5c119009, + 0x5c5221bc, 0x5c93b1d0, 0x5fd44067, 0x5f15d00b, 0x5f5661be, + 0x5f97f1d2, 0x5ad88061, 0x5a19100d, 0x5a5aa1b8, 0x5a9b31d4, + 0x59dcc063, 0x591d500f, 0x595ee1ba, 0x599f71d6, 0x48e0007e, + 0x48219012, 0x486221a7, 0x48a3b1cb, 0x4be4407c, 0x4b25d010, + 0x4b6661a5, 0x4ba7f1c9, 0x4ee8807a, 0x4e291016, 0x4e6aa1a3, + 0x4eab31cf, 0x4decc078, 0x4d2d5014, 0x4d6ee1a1, 0x4daf71cd, + 0x44f00077, 0x4431901b, 0x447221ae, 0x44b3b1c2, 0x47f44075, + 0x4735d019, 0x477661ac, 0x47b7f1c0, 0x42f88073, 0x4239101f, + 0x427aa1aa, 0x42bb31c6, 0x41fcc071, 0x413d501d, 0x417ee1a8, + 0x41bf71c4}}; + +#endif + +#endif + +#if N == 5 + +#if W == 8 + +static const crc_t crc_braid_table[][256] = { + {0x00000000, 0x86acf0c0, 0xbd5ae183, 0x3bf61143, 0xcab6c305, + 0x4c1a33c5, 0x77ec2286, 0xf140d246, 0x256e8609, 0xa3c276c9, + 0x9834678a, 0x1e98974a, 0xefd8450c, 0x6974b5cc, 0x5282a48f, + 0xd42e544f, 0x4add0c12, 0xcc71fcd2, 0xf787ed91, 0x712b1d51, + 0x806bcf17, 0x06c73fd7, 0x3d312e94, 0xbb9dde54, 0x6fb38a1b, + 0xe91f7adb, 0xd2e96b98, 0x54459b58, 0xa505491e, 0x23a9b9de, + 0x185fa89d, 0x9ef3585d, 0x95ba1824, 0x1316e8e4, 0x28e0f9a7, + 0xae4c0967, 0x5f0cdb21, 0xd9a02be1, 0xe2563aa2, 0x64faca62, + 0xb0d49e2d, 0x36786eed, 0x0d8e7fae, 0x8b228f6e, 0x7a625d28, + 0xfcceade8, 0xc738bcab, 0x41944c6b, 0xdf671436, 0x59cbe4f6, + 0x623df5b5, 0xe4910575, 0x15d1d733, 0x937d27f3, 0xa88b36b0, + 0x2e27c670, 0xfa09923f, 0x7ca562ff, 0x475373bc, 0xc1ff837c, + 0x30bf513a, 0xb613a1fa, 0x8de5b0b9, 0x0b494079, 0x9b77304b, + 0x1ddbc08b, 0x262dd1c8, 0xa0812108, 0x51c1f34e, 0xd76d038e, + 0xec9b12cd, 0x6a37e20d, 0xbe19b642, 0x38b54682, 0x034357c1, + 0x85efa701, 0x74af7547, 0xf2038587, 0xc9f594c4, 0x4f596404, + 0xd1aa3c59, 0x5706cc99, 0x6cf0ddda, 0xea5c2d1a, 0x1b1cff5c, + 0x9db00f9c, 0xa6461edf, 0x20eaee1f, 0xf4c4ba50, 0x72684a90, + 0x499e5bd3, 0xcf32ab13, 0x3e727955, 0xb8de8995, 0x832898d6, + 0x05846816, 0x0ecd286f, 0x8861d8af, 0xb397c9ec, 0x353b392c, + 0xc47beb6a, 0x42d71baa, 0x79210ae9, 0xff8dfa29, 0x2ba3ae66, + 0xad0f5ea6, 0x96f94fe5, 0x1055bf25, 0xe1156d63, 0x67b99da3, + 0x5c4f8ce0, 0xdae37c20, 0x4410247d, 0xc2bcd4bd, 0xf94ac5fe, + 0x7fe6353e, 0x8ea6e778, 0x080a17b8, 0x33fc06fb, 0xb550f63b, + 0x617ea274, 0xe7d252b4, 0xdc2443f7, 0x5a88b337, 0xabc86171, + 0x2d6491b1, 0x169280f2, 0x903e7032, 0x86ed6095, 0x00419055, + 0x3bb78116, 0xbd1b71d6, 0x4c5ba390, 0xcaf75350, 0xf1014213, + 0x77adb2d3, 0xa383e69c, 0x252f165c, 0x1ed9071f, 0x9875f7df, + 0x69352599, 0xef99d559, 0xd46fc41a, 0x52c334da, 0xcc306c87, + 0x4a9c9c47, 0x716a8d04, 0xf7c67dc4, 0x0686af82, 0x802a5f42, + 0xbbdc4e01, 0x3d70bec1, 0xe95eea8e, 0x6ff21a4e, 0x54040b0d, + 0xd2a8fbcd, 0x23e8298b, 0xa544d94b, 0x9eb2c808, 0x181e38c8, + 0x135778b1, 0x95fb8871, 0xae0d9932, 0x28a169f2, 0xd9e1bbb4, + 0x5f4d4b74, 0x64bb5a37, 0xe217aaf7, 0x3639feb8, 0xb0950e78, + 0x8b631f3b, 0x0dcfeffb, 0xfc8f3dbd, 0x7a23cd7d, 0x41d5dc3e, + 0xc7792cfe, 0x598a74a3, 0xdf268463, 0xe4d09520, 0x627c65e0, + 0x933cb7a6, 0x15904766, 0x2e665625, 0xa8caa6e5, 0x7ce4f2aa, + 0xfa48026a, 0xc1be1329, 0x4712e3e9, 0xb65231af, 0x30fec16f, + 0x0b08d02c, 0x8da420ec, 0x1d9a50de, 0x9b36a01e, 0xa0c0b15d, + 0x266c419d, 0xd72c93db, 0x5180631b, 0x6a767258, 0xecda8298, + 0x38f4d6d7, 0xbe582617, 0x85ae3754, 0x0302c794, 0xf24215d2, + 0x74eee512, 0x4f18f451, 0xc9b40491, 0x57475ccc, 0xd1ebac0c, + 0xea1dbd4f, 0x6cb14d8f, 0x9df19fc9, 0x1b5d6f09, 0x20ab7e4a, + 0xa6078e8a, 0x7229dac5, 0xf4852a05, 0xcf733b46, 0x49dfcb86, + 0xb89f19c0, 0x3e33e900, 0x05c5f843, 0x83690883, 0x882048fa, + 0x0e8cb83a, 0x357aa979, 0xb3d659b9, 0x42968bff, 0xc43a7b3f, + 0xffcc6a7c, 0x79609abc, 0xad4ecef3, 0x2be23e33, 0x10142f70, + 0x96b8dfb0, 0x67f80df6, 0xe154fd36, 0xdaa2ec75, 0x5c0e1cb5, + 0xc2fd44e8, 0x4451b428, 0x7fa7a56b, 0xf90b55ab, 0x084b87ed, + 0x8ee7772d, 0xb511666e, 0x33bd96ae, 0xe793c2e1, 0x613f3221, + 0x5ac92362, 0xdc65d3a2, 0x2d2501e4, 0xab89f124, 0x907fe067, + 0x16d310a7}, + {0x00000000, 0xbdd9c129, 0xcbb08251, 0x76694378, 0x276204a1, + 0x9abbc588, 0xecd286f0, 0x510b47d9, 0x4ec40942, 0xf31dc86b, + 0x85748b13, 0x38ad4a3a, 0x69a60de3, 0xd47fccca, 0xa2168fb2, + 0x1fcf4e9b, 0x9d881284, 0x2051d3ad, 0x563890d5, 0xebe151fc, + 0xbaea1625, 0x0733d70c, 0x715a9474, 0xcc83555d, 0xd34c1bc6, + 0x6e95daef, 0x18fc9997, 0xa52558be, 0xf42e1f67, 0x49f7de4e, + 0x3f9e9d36, 0x82475c1f, 0x8b13250b, 0x36cae422, 0x40a3a75a, + 0xfd7a6673, 0xac7121aa, 0x11a8e083, 0x67c1a3fb, 0xda1862d2, + 0xc5d72c49, 0x780eed60, 0x0e67ae18, 0xb3be6f31, 0xe2b528e8, + 0x5f6ce9c1, 0x2905aab9, 0x94dc6b90, 0x169b378f, 0xab42f6a6, + 0xdd2bb5de, 0x60f274f7, 0x31f9332e, 0x8c20f207, 0xfa49b17f, + 0x47907056, 0x585f3ecd, 0xe586ffe4, 0x93efbc9c, 0x2e367db5, + 0x7f3d3a6c, 0xc2e4fb45, 0xb48db83d, 0x09547914, 0xa6254a15, + 0x1bfc8b3c, 0x6d95c844, 0xd04c096d, 0x81474eb4, 0x3c9e8f9d, + 0x4af7cce5, 0xf72e0dcc, 0xe8e14357, 0x5538827e, 0x2351c106, + 0x9e88002f, 0xcf8347f6, 0x725a86df, 0x0433c5a7, 0xb9ea048e, + 0x3bad5891, 0x867499b8, 0xf01ddac0, 0x4dc41be9, 0x1ccf5c30, + 0xa1169d19, 0xd77fde61, 0x6aa61f48, 0x756951d3, 0xc8b090fa, + 0xbed9d382, 0x030012ab, 0x520b5572, 0xefd2945b, 0x99bbd723, + 0x2462160a, 0x2d366f1e, 0x90efae37, 0xe686ed4f, 0x5b5f2c66, + 0x0a546bbf, 0xb78daa96, 0xc1e4e9ee, 0x7c3d28c7, 0x63f2665c, + 0xde2ba775, 0xa842e40d, 0x159b2524, 0x449062fd, 0xf949a3d4, + 0x8f20e0ac, 0x32f92185, 0xb0be7d9a, 0x0d67bcb3, 0x7b0effcb, + 0xc6d73ee2, 0x97dc793b, 0x2a05b812, 0x5c6cfb6a, 0xe1b53a43, + 0xfe7a74d8, 0x43a3b5f1, 0x35caf689, 0x881337a0, 0xd9187079, + 0x64c1b150, 0x12a8f228, 0xaf713301, 0xfc499429, 0x41905500, + 0x37f91678, 0x8a20d751, 0xdb2b9088, 0x66f251a1, 0x109b12d9, + 0xad42d3f0, 0xb28d9d6b, 0x0f545c42, 0x793d1f3a, 0xc4e4de13, + 0x95ef99ca, 0x283658e3, 0x5e5f1b9b, 0xe386dab2, 0x61c186ad, + 0xdc184784, 0xaa7104fc, 0x17a8c5d5, 0x46a3820c, 0xfb7a4325, + 0x8d13005d, 0x30cac174, 0x2f058fef, 0x92dc4ec6, 0xe4b50dbe, + 0x596ccc97, 0x08678b4e, 0xb5be4a67, 0xc3d7091f, 0x7e0ec836, + 0x775ab122, 0xca83700b, 0xbcea3373, 0x0133f25a, 0x5038b583, + 0xede174aa, 0x9b8837d2, 0x2651f6fb, 0x399eb860, 0x84477949, + 0xf22e3a31, 0x4ff7fb18, 0x1efcbcc1, 0xa3257de8, 0xd54c3e90, + 0x6895ffb9, 0xead2a3a6, 0x570b628f, 0x216221f7, 0x9cbbe0de, + 0xcdb0a707, 0x7069662e, 0x06002556, 0xbbd9e47f, 0xa416aae4, + 0x19cf6bcd, 0x6fa628b5, 0xd27fe99c, 0x8374ae45, 0x3ead6f6c, + 0x48c42c14, 0xf51ded3d, 0x5a6cde3c, 0xe7b51f15, 0x91dc5c6d, + 0x2c059d44, 0x7d0eda9d, 0xc0d71bb4, 0xb6be58cc, 0x0b6799e5, + 0x14a8d77e, 0xa9711657, 0xdf18552f, 0x62c19406, 0x33cad3df, + 0x8e1312f6, 0xf87a518e, 0x45a390a7, 0xc7e4ccb8, 0x7a3d0d91, + 0x0c544ee9, 0xb18d8fc0, 0xe086c819, 0x5d5f0930, 0x2b364a48, + 0x96ef8b61, 0x8920c5fa, 0x34f904d3, 0x429047ab, 0xff498682, + 0xae42c15b, 0x139b0072, 0x65f2430a, 0xd82b8223, 0xd17ffb37, + 0x6ca63a1e, 0x1acf7966, 0xa716b84f, 0xf61dff96, 0x4bc43ebf, + 0x3dad7dc7, 0x8074bcee, 0x9fbbf275, 0x2262335c, 0x540b7024, + 0xe9d2b10d, 0xb8d9f6d4, 0x050037fd, 0x73697485, 0xceb0b5ac, + 0x4cf7e9b3, 0xf12e289a, 0x87476be2, 0x3a9eaacb, 0x6b95ed12, + 0xd64c2c3b, 0xa0256f43, 0x1dfcae6a, 0x0233e0f1, 0xbfea21d8, + 0xc98362a0, 0x745aa389, 0x2551e450, 0x98882579, 0xeee16601, + 0x5338a728}, + {0x00000000, 0x48902851, 0x912050a2, 0xd9b078f3, 0x9243a147, + 0xdad38916, 0x0363f1e5, 0x4bf3d9b4, 0x9484428d, 0xdc146adc, + 0x05a4122f, 0x4d343a7e, 0x06c7e3ca, 0x4e57cb9b, 0x97e7b368, + 0xdf779b39, 0x990b8519, 0xd19bad48, 0x082bd5bb, 0x40bbfdea, + 0x0b48245e, 0x43d80c0f, 0x9a6874fc, 0xd2f85cad, 0x0d8fc794, + 0x451fefc5, 0x9caf9736, 0xd43fbf67, 0x9fcc66d3, 0xd75c4e82, + 0x0eec3671, 0x467c1e20, 0x82140a31, 0xca842260, 0x13345a93, + 0x5ba472c2, 0x1057ab76, 0x58c78327, 0x8177fbd4, 0xc9e7d385, + 0x169048bc, 0x5e0060ed, 0x87b0181e, 0xcf20304f, 0x84d3e9fb, + 0xcc43c1aa, 0x15f3b959, 0x5d639108, 0x1b1f8f28, 0x538fa779, + 0x8a3fdf8a, 0xc2aff7db, 0x895c2e6f, 0xc1cc063e, 0x187c7ecd, + 0x50ec569c, 0x8f9bcda5, 0xc70be5f4, 0x1ebb9d07, 0x562bb556, + 0x1dd86ce2, 0x554844b3, 0x8cf83c40, 0xc4681411, 0xb42b1461, + 0xfcbb3c30, 0x250b44c3, 0x6d9b6c92, 0x2668b526, 0x6ef89d77, + 0xb748e584, 0xffd8cdd5, 0x20af56ec, 0x683f7ebd, 0xb18f064e, + 0xf91f2e1f, 0xb2ecf7ab, 0xfa7cdffa, 0x23cca709, 0x6b5c8f58, + 0x2d209178, 0x65b0b929, 0xbc00c1da, 0xf490e98b, 0xbf63303f, + 0xf7f3186e, 0x2e43609d, 0x66d348cc, 0xb9a4d3f5, 0xf134fba4, + 0x28848357, 0x6014ab06, 0x2be772b2, 0x63775ae3, 0xbac72210, + 0xf2570a41, 0x363f1e50, 0x7eaf3601, 0xa71f4ef2, 0xef8f66a3, + 0xa47cbf17, 0xecec9746, 0x355cefb5, 0x7dccc7e4, 0xa2bb5cdd, + 0xea2b748c, 0x339b0c7f, 0x7b0b242e, 0x30f8fd9a, 0x7868d5cb, + 0xa1d8ad38, 0xe9488569, 0xaf349b49, 0xe7a4b318, 0x3e14cbeb, + 0x7684e3ba, 0x3d773a0e, 0x75e7125f, 0xac576aac, 0xe4c742fd, + 0x3bb0d9c4, 0x7320f195, 0xaa908966, 0xe200a137, 0xa9f37883, + 0xe16350d2, 0x38d32821, 0x70430070, 0xd85528c1, 0x90c50090, + 0x49757863, 0x01e55032, 0x4a168986, 0x0286a1d7, 0xdb36d924, + 0x93a6f175, 0x4cd16a4c, 0x0441421d, 0xddf13aee, 0x956112bf, + 0xde92cb0b, 0x9602e35a, 0x4fb29ba9, 0x0722b3f8, 0x415eadd8, + 0x09ce8589, 0xd07efd7a, 0x98eed52b, 0xd31d0c9f, 0x9b8d24ce, + 0x423d5c3d, 0x0aad746c, 0xd5daef55, 0x9d4ac704, 0x44fabff7, + 0x0c6a97a6, 0x47994e12, 0x0f096643, 0xd6b91eb0, 0x9e2936e1, + 0x5a4122f0, 0x12d10aa1, 0xcb617252, 0x83f15a03, 0xc80283b7, + 0x8092abe6, 0x5922d315, 0x11b2fb44, 0xcec5607d, 0x8655482c, + 0x5fe530df, 0x1775188e, 0x5c86c13a, 0x1416e96b, 0xcda69198, + 0x8536b9c9, 0xc34aa7e9, 0x8bda8fb8, 0x526af74b, 0x1afadf1a, + 0x510906ae, 0x19992eff, 0xc029560c, 0x88b97e5d, 0x57cee564, + 0x1f5ecd35, 0xc6eeb5c6, 0x8e7e9d97, 0xc58d4423, 0x8d1d6c72, + 0x54ad1481, 0x1c3d3cd0, 0x6c7e3ca0, 0x24ee14f1, 0xfd5e6c02, + 0xb5ce4453, 0xfe3d9de7, 0xb6adb5b6, 0x6f1dcd45, 0x278de514, + 0xf8fa7e2d, 0xb06a567c, 0x69da2e8f, 0x214a06de, 0x6ab9df6a, + 0x2229f73b, 0xfb998fc8, 0xb309a799, 0xf575b9b9, 0xbde591e8, + 0x6455e91b, 0x2cc5c14a, 0x673618fe, 0x2fa630af, 0xf616485c, + 0xbe86600d, 0x61f1fb34, 0x2961d365, 0xf0d1ab96, 0xb84183c7, + 0xf3b25a73, 0xbb227222, 0x62920ad1, 0x2a022280, 0xee6a3691, + 0xa6fa1ec0, 0x7f4a6633, 0x37da4e62, 0x7c2997d6, 0x34b9bf87, + 0xed09c774, 0xa599ef25, 0x7aee741c, 0x327e5c4d, 0xebce24be, + 0xa35e0cef, 0xe8add55b, 0xa03dfd0a, 0x798d85f9, 0x311dada8, + 0x7761b388, 0x3ff19bd9, 0xe641e32a, 0xaed1cb7b, 0xe52212cf, + 0xadb23a9e, 0x7402426d, 0x3c926a3c, 0xe3e5f105, 0xab75d954, + 0x72c5a1a7, 0x3a5589f6, 0x71a65042, 0x39367813, 0xe08600e0, + 0xa81628b1}, + {0x00000000, 0x00a95181, 0x0152a302, 0x01fbf283, 0x02a54604, + 0x020c1785, 0x03f7e506, 0x035eb487, 0x054a8c08, 0x05e3dd89, + 0x04182f0a, 0x04b17e8b, 0x07efca0c, 0x07469b8d, 0x06bd690e, + 0x0614388f, 0x0a951810, 0x0a3c4991, 0x0bc7bb12, 0x0b6eea93, + 0x08305e14, 0x08990f95, 0x0962fd16, 0x09cbac97, 0x0fdf9418, + 0x0f76c599, 0x0e8d371a, 0x0e24669b, 0x0d7ad21c, 0x0dd3839d, + 0x0c28711e, 0x0c81209f, 0x152a3020, 0x158361a1, 0x14789322, + 0x14d1c2a3, 0x178f7624, 0x172627a5, 0x16ddd526, 0x167484a7, + 0x1060bc28, 0x10c9eda9, 0x11321f2a, 0x119b4eab, 0x12c5fa2c, + 0x126cabad, 0x1397592e, 0x133e08af, 0x1fbf2830, 0x1f1679b1, + 0x1eed8b32, 0x1e44dab3, 0x1d1a6e34, 0x1db33fb5, 0x1c48cd36, + 0x1ce19cb7, 0x1af5a438, 0x1a5cf5b9, 0x1ba7073a, 0x1b0e56bb, + 0x1850e23c, 0x18f9b3bd, 0x1902413e, 0x19ab10bf, 0x2a546040, + 0x2afd31c1, 0x2b06c342, 0x2baf92c3, 0x28f12644, 0x285877c5, + 0x29a38546, 0x290ad4c7, 0x2f1eec48, 0x2fb7bdc9, 0x2e4c4f4a, + 0x2ee51ecb, 0x2dbbaa4c, 0x2d12fbcd, 0x2ce9094e, 0x2c4058cf, + 0x20c17850, 0x206829d1, 0x2193db52, 0x213a8ad3, 0x22643e54, + 0x22cd6fd5, 0x23369d56, 0x239fccd7, 0x258bf458, 0x2522a5d9, + 0x24d9575a, 0x247006db, 0x272eb25c, 0x2787e3dd, 0x267c115e, + 0x26d540df, 0x3f7e5060, 0x3fd701e1, 0x3e2cf362, 0x3e85a2e3, + 0x3ddb1664, 0x3d7247e5, 0x3c89b566, 0x3c20e4e7, 0x3a34dc68, + 0x3a9d8de9, 0x3b667f6a, 0x3bcf2eeb, 0x38919a6c, 0x3838cbed, + 0x39c3396e, 0x396a68ef, 0x35eb4870, 0x354219f1, 0x34b9eb72, + 0x3410baf3, 0x374e0e74, 0x37e75ff5, 0x361cad76, 0x36b5fcf7, + 0x30a1c478, 0x300895f9, 0x31f3677a, 0x315a36fb, 0x3204827c, + 0x32add3fd, 0x3356217e, 0x33ff70ff, 0x54a8c080, 0x54019101, + 0x55fa6382, 0x55533203, 0x560d8684, 0x56a4d705, 0x575f2586, + 0x57f67407, 0x51e24c88, 0x514b1d09, 0x50b0ef8a, 0x5019be0b, + 0x53470a8c, 0x53ee5b0d, 0x5215a98e, 0x52bcf80f, 0x5e3dd890, + 0x5e948911, 0x5f6f7b92, 0x5fc62a13, 0x5c989e94, 0x5c31cf15, + 0x5dca3d96, 0x5d636c17, 0x5b775498, 0x5bde0519, 0x5a25f79a, + 0x5a8ca61b, 0x59d2129c, 0x597b431d, 0x5880b19e, 0x5829e01f, + 0x4182f0a0, 0x412ba121, 0x40d053a2, 0x40790223, 0x4327b6a4, + 0x438ee725, 0x427515a6, 0x42dc4427, 0x44c87ca8, 0x44612d29, + 0x459adfaa, 0x45338e2b, 0x466d3aac, 0x46c46b2d, 0x473f99ae, + 0x4796c82f, 0x4b17e8b0, 0x4bbeb931, 0x4a454bb2, 0x4aec1a33, + 0x49b2aeb4, 0x491bff35, 0x48e00db6, 0x48495c37, 0x4e5d64b8, + 0x4ef43539, 0x4f0fc7ba, 0x4fa6963b, 0x4cf822bc, 0x4c51733d, + 0x4daa81be, 0x4d03d03f, 0x7efca0c0, 0x7e55f141, 0x7fae03c2, + 0x7f075243, 0x7c59e6c4, 0x7cf0b745, 0x7d0b45c6, 0x7da21447, + 0x7bb62cc8, 0x7b1f7d49, 0x7ae48fca, 0x7a4dde4b, 0x79136acc, + 0x79ba3b4d, 0x7841c9ce, 0x78e8984f, 0x7469b8d0, 0x74c0e951, + 0x753b1bd2, 0x75924a53, 0x76ccfed4, 0x7665af55, 0x779e5dd6, + 0x77370c57, 0x712334d8, 0x718a6559, 0x707197da, 0x70d8c65b, + 0x738672dc, 0x732f235d, 0x72d4d1de, 0x727d805f, 0x6bd690e0, + 0x6b7fc161, 0x6a8433e2, 0x6a2d6263, 0x6973d6e4, 0x69da8765, + 0x682175e6, 0x68882467, 0x6e9c1ce8, 0x6e354d69, 0x6fcebfea, + 0x6f67ee6b, 0x6c395aec, 0x6c900b6d, 0x6d6bf9ee, 0x6dc2a86f, + 0x614388f0, 0x61ead971, 0x60112bf2, 0x60b87a73, 0x63e6cef4, + 0x634f9f75, 0x62b46df6, 0x621d3c77, 0x640904f8, 0x64a05579, + 0x655ba7fa, 0x65f2f67b, 0x66ac42fc, 0x6605137d, 0x67fee1fe, + 0x6757b07f}, + {0x00000000, 0xa9518100, 0xe2a00203, 0x4bf18303, 0x75430405, + 0xdc128505, 0x97e30606, 0x3eb28706, 0xea86080a, 0x43d7890a, + 0x08260a09, 0xa1778b09, 0x9fc50c0f, 0x36948d0f, 0x7d650e0c, + 0xd4348f0c, 0x650f1017, 0xcc5e9117, 0x87af1214, 0x2efe9314, + 0x104c1412, 0xb91d9512, 0xf2ec1611, 0x5bbd9711, 0x8f89181d, + 0x26d8991d, 0x6d291a1e, 0xc4789b1e, 0xfaca1c18, 0x539b9d18, + 0x186a1e1b, 0xb13b9f1b, 0xca1e202e, 0x634fa12e, 0x28be222d, + 0x81efa32d, 0xbf5d242b, 0x160ca52b, 0x5dfd2628, 0xf4aca728, + 0x20982824, 0x89c9a924, 0xc2382a27, 0x6b69ab27, 0x55db2c21, + 0xfc8aad21, 0xb77b2e22, 0x1e2aaf22, 0xaf113039, 0x0640b139, + 0x4db1323a, 0xe4e0b33a, 0xda52343c, 0x7303b53c, 0x38f2363f, + 0x91a3b73f, 0x45973833, 0xecc6b933, 0xa7373a30, 0x0e66bb30, + 0x30d43c36, 0x9985bd36, 0xd2743e35, 0x7b25bf35, 0x243f405f, + 0x8d6ec15f, 0xc69f425c, 0x6fcec35c, 0x517c445a, 0xf82dc55a, + 0xb3dc4659, 0x1a8dc759, 0xceb94855, 0x67e8c955, 0x2c194a56, + 0x8548cb56, 0xbbfa4c50, 0x12abcd50, 0x595a4e53, 0xf00bcf53, + 0x41305048, 0xe861d148, 0xa390524b, 0x0ac1d34b, 0x3473544d, + 0x9d22d54d, 0xd6d3564e, 0x7f82d74e, 0xabb65842, 0x02e7d942, + 0x49165a41, 0xe047db41, 0xdef55c47, 0x77a4dd47, 0x3c555e44, + 0x9504df44, 0xee216071, 0x4770e171, 0x0c816272, 0xa5d0e372, + 0x9b626474, 0x3233e574, 0x79c26677, 0xd093e777, 0x04a7687b, + 0xadf6e97b, 0xe6076a78, 0x4f56eb78, 0x71e46c7e, 0xd8b5ed7e, + 0x93446e7d, 0x3a15ef7d, 0x8b2e7066, 0x227ff166, 0x698e7265, + 0xc0dff365, 0xfe6d7463, 0x573cf563, 0x1ccd7660, 0xb59cf760, + 0x61a8786c, 0xc8f9f96c, 0x83087a6f, 0x2a59fb6f, 0x14eb7c69, + 0xbdbafd69, 0xf64b7e6a, 0x5f1aff6a, 0x487e80be, 0xe12f01be, + 0xaade82bd, 0x038f03bd, 0x3d3d84bb, 0x946c05bb, 0xdf9d86b8, + 0x76cc07b8, 0xa2f888b4, 0x0ba909b4, 0x40588ab7, 0xe9090bb7, + 0xd7bb8cb1, 0x7eea0db1, 0x351b8eb2, 0x9c4a0fb2, 0x2d7190a9, + 0x842011a9, 0xcfd192aa, 0x668013aa, 0x583294ac, 0xf16315ac, + 0xba9296af, 0x13c317af, 0xc7f798a3, 0x6ea619a3, 0x25579aa0, + 0x8c061ba0, 0xb2b49ca6, 0x1be51da6, 0x50149ea5, 0xf9451fa5, + 0x8260a090, 0x2b312190, 0x60c0a293, 0xc9912393, 0xf723a495, + 0x5e722595, 0x1583a696, 0xbcd22796, 0x68e6a89a, 0xc1b7299a, + 0x8a46aa99, 0x23172b99, 0x1da5ac9f, 0xb4f42d9f, 0xff05ae9c, + 0x56542f9c, 0xe76fb087, 0x4e3e3187, 0x05cfb284, 0xac9e3384, + 0x922cb482, 0x3b7d3582, 0x708cb681, 0xd9dd3781, 0x0de9b88d, + 0xa4b8398d, 0xef49ba8e, 0x46183b8e, 0x78aabc88, 0xd1fb3d88, + 0x9a0abe8b, 0x335b3f8b, 0x6c41c0e1, 0xc51041e1, 0x8ee1c2e2, + 0x27b043e2, 0x1902c4e4, 0xb05345e4, 0xfba2c6e7, 0x52f347e7, + 0x86c7c8eb, 0x2f9649eb, 0x6467cae8, 0xcd364be8, 0xf384ccee, + 0x5ad54dee, 0x1124ceed, 0xb8754fed, 0x094ed0f6, 0xa01f51f6, + 0xebeed2f5, 0x42bf53f5, 0x7c0dd4f3, 0xd55c55f3, 0x9eadd6f0, + 0x37fc57f0, 0xe3c8d8fc, 0x4a9959fc, 0x0168daff, 0xa8395bff, + 0x968bdcf9, 0x3fda5df9, 0x742bdefa, 0xdd7a5ffa, 0xa65fe0cf, + 0x0f0e61cf, 0x44ffe2cc, 0xedae63cc, 0xd31ce4ca, 0x7a4d65ca, + 0x31bce6c9, 0x98ed67c9, 0x4cd9e8c5, 0xe58869c5, 0xae79eac6, + 0x07286bc6, 0x399aecc0, 0x90cb6dc0, 0xdb3aeec3, 0x726b6fc3, + 0xc350f0d8, 0x6a0171d8, 0x21f0f2db, 0x88a173db, 0xb613f4dd, + 0x1f4275dd, 0x54b3f6de, 0xfde277de, 0x29d6f8d2, 0x808779d2, + 0xcb76fad1, 0x62277bd1, 0x5c95fcd7, 0xf5c47dd7, 0xbe35fed4, + 0x17647fd4}, + {0x00000000, 0x90fd017c, 0x91f902fb, 0x01040387, 0x93f105f5, + 0x030c0489, 0x0208070e, 0x92f50672, 0x97e10be9, 0x071c0a95, + 0x06180912, 0x96e5086e, 0x04100e1c, 0x94ed0f60, 0x95e90ce7, + 0x05140d9b, 0x9fc117d1, 0x0f3c16ad, 0x0e38152a, 0x9ec51456, + 0x0c301224, 0x9ccd1358, 0x9dc910df, 0x0d3411a3, 0x08201c38, + 0x98dd1d44, 0x99d91ec3, 0x09241fbf, 0x9bd119cd, 0x0b2c18b1, + 0x0a281b36, 0x9ad51a4a, 0x8f812fa1, 0x1f7c2edd, 0x1e782d5a, + 0x8e852c26, 0x1c702a54, 0x8c8d2b28, 0x8d8928af, 0x1d7429d3, + 0x18602448, 0x889d2534, 0x899926b3, 0x196427cf, 0x8b9121bd, + 0x1b6c20c1, 0x1a682346, 0x8a95223a, 0x10403870, 0x80bd390c, + 0x81b93a8b, 0x11443bf7, 0x83b13d85, 0x134c3cf9, 0x12483f7e, + 0x82b53e02, 0x87a13399, 0x175c32e5, 0x16583162, 0x86a5301e, + 0x1450366c, 0x84ad3710, 0x85a93497, 0x155435eb, 0xaf015f41, + 0x3ffc5e3d, 0x3ef85dba, 0xae055cc6, 0x3cf05ab4, 0xac0d5bc8, + 0xad09584f, 0x3df45933, 0x38e054a8, 0xa81d55d4, 0xa9195653, + 0x39e4572f, 0xab11515d, 0x3bec5021, 0x3ae853a6, 0xaa1552da, + 0x30c04890, 0xa03d49ec, 0xa1394a6b, 0x31c44b17, 0xa3314d65, + 0x33cc4c19, 0x32c84f9e, 0xa2354ee2, 0xa7214379, 0x37dc4205, + 0x36d84182, 0xa62540fe, 0x34d0468c, 0xa42d47f0, 0xa5294477, + 0x35d4450b, 0x208070e0, 0xb07d719c, 0xb179721b, 0x21847367, + 0xb3717515, 0x238c7469, 0x228877ee, 0xb2757692, 0xb7617b09, + 0x279c7a75, 0x269879f2, 0xb665788e, 0x24907efc, 0xb46d7f80, + 0xb5697c07, 0x25947d7b, 0xbf416731, 0x2fbc664d, 0x2eb865ca, + 0xbe4564b6, 0x2cb062c4, 0xbc4d63b8, 0xbd49603f, 0x2db46143, + 0x28a06cd8, 0xb85d6da4, 0xb9596e23, 0x29a46f5f, 0xbb51692d, + 0x2bac6851, 0x2aa86bd6, 0xba556aaa, 0xee01be81, 0x7efcbffd, + 0x7ff8bc7a, 0xef05bd06, 0x7df0bb74, 0xed0dba08, 0xec09b98f, + 0x7cf4b8f3, 0x79e0b568, 0xe91db414, 0xe819b793, 0x78e4b6ef, + 0xea11b09d, 0x7aecb1e1, 0x7be8b266, 0xeb15b31a, 0x71c0a950, + 0xe13da82c, 0xe039abab, 0x70c4aad7, 0xe231aca5, 0x72ccadd9, + 0x73c8ae5e, 0xe335af22, 0xe621a2b9, 0x76dca3c5, 0x77d8a042, + 0xe725a13e, 0x75d0a74c, 0xe52da630, 0xe429a5b7, 0x74d4a4cb, + 0x61809120, 0xf17d905c, 0xf07993db, 0x608492a7, 0xf27194d5, + 0x628c95a9, 0x6388962e, 0xf3759752, 0xf6619ac9, 0x669c9bb5, + 0x67989832, 0xf765994e, 0x65909f3c, 0xf56d9e40, 0xf4699dc7, + 0x64949cbb, 0xfe4186f1, 0x6ebc878d, 0x6fb8840a, 0xff458576, + 0x6db08304, 0xfd4d8278, 0xfc4981ff, 0x6cb48083, 0x69a08d18, + 0xf95d8c64, 0xf8598fe3, 0x68a48e9f, 0xfa5188ed, 0x6aac8991, + 0x6ba88a16, 0xfb558b6a, 0x4100e1c0, 0xd1fde0bc, 0xd0f9e33b, + 0x4004e247, 0xd2f1e435, 0x420ce549, 0x4308e6ce, 0xd3f5e7b2, + 0xd6e1ea29, 0x461ceb55, 0x4718e8d2, 0xd7e5e9ae, 0x4510efdc, + 0xd5edeea0, 0xd4e9ed27, 0x4414ec5b, 0xdec1f611, 0x4e3cf76d, + 0x4f38f4ea, 0xdfc5f596, 0x4d30f3e4, 0xddcdf298, 0xdcc9f11f, + 0x4c34f063, 0x4920fdf8, 0xd9ddfc84, 0xd8d9ff03, 0x4824fe7f, + 0xdad1f80d, 0x4a2cf971, 0x4b28faf6, 0xdbd5fb8a, 0xce81ce61, + 0x5e7ccf1d, 0x5f78cc9a, 0xcf85cde6, 0x5d70cb94, 0xcd8dcae8, + 0xcc89c96f, 0x5c74c813, 0x5960c588, 0xc99dc4f4, 0xc899c773, + 0x5864c60f, 0xca91c07d, 0x5a6cc101, 0x5b68c286, 0xcb95c3fa, + 0x5140d9b0, 0xc1bdd8cc, 0xc0b9db4b, 0x5044da37, 0xc2b1dc45, + 0x524cdd39, 0x5348debe, 0xc3b5dfc2, 0xc6a1d259, 0x565cd325, + 0x5758d0a2, 0xc7a5d1de, 0x5550d7ac, 0xc5add6d0, 0xc4a9d557, + 0x5454d42b}, + {0x00000000, 0x6c007d01, 0xd800fa02, 0xb4008703, 0x0002f407, + 0x6c028906, 0xd8020e05, 0xb4027304, 0x0005e80e, 0x6c05950f, + 0xd805120c, 0xb4056f0d, 0x00071c09, 0x6c076108, 0xd807e60b, + 0xb4079b0a, 0x000bd01c, 0x6c0bad1d, 0xd80b2a1e, 0xb40b571f, + 0x0009241b, 0x6c09591a, 0xd809de19, 0xb409a318, 0x000e3812, + 0x6c0e4513, 0xd80ec210, 0xb40ebf11, 0x000ccc15, 0x6c0cb114, + 0xd80c3617, 0xb40c4b16, 0x0017a038, 0x6c17dd39, 0xd8175a3a, + 0xb417273b, 0x0015543f, 0x6c15293e, 0xd815ae3d, 0xb415d33c, + 0x00124836, 0x6c123537, 0xd812b234, 0xb412cf35, 0x0010bc31, + 0x6c10c130, 0xd8104633, 0xb4103b32, 0x001c7024, 0x6c1c0d25, + 0xd81c8a26, 0xb41cf727, 0x001e8423, 0x6c1ef922, 0xd81e7e21, + 0xb41e0320, 0x0019982a, 0x6c19e52b, 0xd8196228, 0xb4191f29, + 0x001b6c2d, 0x6c1b112c, 0xd81b962f, 0xb41beb2e, 0x002f4070, + 0x6c2f3d71, 0xd82fba72, 0xb42fc773, 0x002db477, 0x6c2dc976, + 0xd82d4e75, 0xb42d3374, 0x002aa87e, 0x6c2ad57f, 0xd82a527c, + 0xb42a2f7d, 0x00285c79, 0x6c282178, 0xd828a67b, 0xb428db7a, + 0x0024906c, 0x6c24ed6d, 0xd8246a6e, 0xb424176f, 0x0026646b, + 0x6c26196a, 0xd8269e69, 0xb426e368, 0x00217862, 0x6c210563, + 0xd8218260, 0xb421ff61, 0x00238c65, 0x6c23f164, 0xd8237667, + 0xb4230b66, 0x0038e048, 0x6c389d49, 0xd8381a4a, 0xb438674b, + 0x003a144f, 0x6c3a694e, 0xd83aee4d, 0xb43a934c, 0x003d0846, + 0x6c3d7547, 0xd83df244, 0xb43d8f45, 0x003ffc41, 0x6c3f8140, + 0xd83f0643, 0xb43f7b42, 0x00333054, 0x6c334d55, 0xd833ca56, + 0xb433b757, 0x0031c453, 0x6c31b952, 0xd8313e51, 0xb4314350, + 0x0036d85a, 0x6c36a55b, 0xd8362258, 0xb4365f59, 0x00342c5d, + 0x6c34515c, 0xd834d65f, 0xb434ab5e, 0x005e80e0, 0x6c5efde1, + 0xd85e7ae2, 0xb45e07e3, 0x005c74e7, 0x6c5c09e6, 0xd85c8ee5, + 0xb45cf3e4, 0x005b68ee, 0x6c5b15ef, 0xd85b92ec, 0xb45befed, + 0x00599ce9, 0x6c59e1e8, 0xd85966eb, 0xb4591bea, 0x005550fc, + 0x6c552dfd, 0xd855aafe, 0xb455d7ff, 0x0057a4fb, 0x6c57d9fa, + 0xd8575ef9, 0xb45723f8, 0x0050b8f2, 0x6c50c5f3, 0xd85042f0, + 0xb4503ff1, 0x00524cf5, 0x6c5231f4, 0xd852b6f7, 0xb452cbf6, + 0x004920d8, 0x6c495dd9, 0xd849dada, 0xb449a7db, 0x004bd4df, + 0x6c4ba9de, 0xd84b2edd, 0xb44b53dc, 0x004cc8d6, 0x6c4cb5d7, + 0xd84c32d4, 0xb44c4fd5, 0x004e3cd1, 0x6c4e41d0, 0xd84ec6d3, + 0xb44ebbd2, 0x0042f0c4, 0x6c428dc5, 0xd8420ac6, 0xb44277c7, + 0x004004c3, 0x6c4079c2, 0xd840fec1, 0xb44083c0, 0x004718ca, + 0x6c4765cb, 0xd847e2c8, 0xb4479fc9, 0x0045eccd, 0x6c4591cc, + 0xd84516cf, 0xb4456bce, 0x0071c090, 0x6c71bd91, 0xd8713a92, + 0xb4714793, 0x00733497, 0x6c734996, 0xd873ce95, 0xb473b394, + 0x0074289e, 0x6c74559f, 0xd874d29c, 0xb474af9d, 0x0076dc99, + 0x6c76a198, 0xd876269b, 0xb4765b9a, 0x007a108c, 0x6c7a6d8d, + 0xd87aea8e, 0xb47a978f, 0x0078e48b, 0x6c78998a, 0xd8781e89, + 0xb4786388, 0x007ff882, 0x6c7f8583, 0xd87f0280, 0xb47f7f81, + 0x007d0c85, 0x6c7d7184, 0xd87df687, 0xb47d8b86, 0x006660a8, + 0x6c661da9, 0xd8669aaa, 0xb466e7ab, 0x006494af, 0x6c64e9ae, + 0xd8646ead, 0xb46413ac, 0x006388a6, 0x6c63f5a7, 0xd86372a4, + 0xb4630fa5, 0x00617ca1, 0x6c6101a0, 0xd86186a3, 0xb461fba2, + 0x006db0b4, 0x6c6dcdb5, 0xd86d4ab6, 0xb46d37b7, 0x006f44b3, + 0x6c6f39b2, 0xd86fbeb1, 0xb46fc3b0, 0x006858ba, 0x6c6825bb, + 0xd868a2b8, 0xb468dfb9, 0x006aacbd, 0x6c6ad1bc, 0xd86a56bf, + 0xb46a2bbe}, + {0x00000000, 0x00bd01c0, 0x017a0380, 0x01c70240, 0x02f40700, + 0x024906c0, 0x038e0480, 0x03330540, 0x05e80e00, 0x05550fc0, + 0x04920d80, 0x042f0c40, 0x071c0900, 0x07a108c0, 0x06660a80, + 0x06db0b40, 0x0bd01c00, 0x0b6d1dc0, 0x0aaa1f80, 0x0a171e40, + 0x09241b00, 0x09991ac0, 0x085e1880, 0x08e31940, 0x0e381200, + 0x0e8513c0, 0x0f421180, 0x0fff1040, 0x0ccc1500, 0x0c7114c0, + 0x0db61680, 0x0d0b1740, 0x17a03800, 0x171d39c0, 0x16da3b80, + 0x16673a40, 0x15543f00, 0x15e93ec0, 0x142e3c80, 0x14933d40, + 0x12483600, 0x12f537c0, 0x13323580, 0x138f3440, 0x10bc3100, + 0x100130c0, 0x11c63280, 0x117b3340, 0x1c702400, 0x1ccd25c0, + 0x1d0a2780, 0x1db72640, 0x1e842300, 0x1e3922c0, 0x1ffe2080, + 0x1f432140, 0x19982a00, 0x19252bc0, 0x18e22980, 0x185f2840, + 0x1b6c2d00, 0x1bd12cc0, 0x1a162e80, 0x1aab2f40, 0x2f407000, + 0x2ffd71c0, 0x2e3a7380, 0x2e877240, 0x2db47700, 0x2d0976c0, + 0x2cce7480, 0x2c737540, 0x2aa87e00, 0x2a157fc0, 0x2bd27d80, + 0x2b6f7c40, 0x285c7900, 0x28e178c0, 0x29267a80, 0x299b7b40, + 0x24906c00, 0x242d6dc0, 0x25ea6f80, 0x25576e40, 0x26646b00, + 0x26d96ac0, 0x271e6880, 0x27a36940, 0x21786200, 0x21c563c0, + 0x20026180, 0x20bf6040, 0x238c6500, 0x233164c0, 0x22f66680, + 0x224b6740, 0x38e04800, 0x385d49c0, 0x399a4b80, 0x39274a40, + 0x3a144f00, 0x3aa94ec0, 0x3b6e4c80, 0x3bd34d40, 0x3d084600, + 0x3db547c0, 0x3c724580, 0x3ccf4440, 0x3ffc4100, 0x3f4140c0, + 0x3e864280, 0x3e3b4340, 0x33305400, 0x338d55c0, 0x324a5780, + 0x32f75640, 0x31c45300, 0x317952c0, 0x30be5080, 0x30035140, + 0x36d85a00, 0x36655bc0, 0x37a25980, 0x371f5840, 0x342c5d00, + 0x34915cc0, 0x35565e80, 0x35eb5f40, 0x5e80e000, 0x5e3de1c0, + 0x5ffae380, 0x5f47e240, 0x5c74e700, 0x5cc9e6c0, 0x5d0ee480, + 0x5db3e540, 0x5b68ee00, 0x5bd5efc0, 0x5a12ed80, 0x5aafec40, + 0x599ce900, 0x5921e8c0, 0x58e6ea80, 0x585beb40, 0x5550fc00, + 0x55edfdc0, 0x542aff80, 0x5497fe40, 0x57a4fb00, 0x5719fac0, + 0x56def880, 0x5663f940, 0x50b8f200, 0x5005f3c0, 0x51c2f180, + 0x517ff040, 0x524cf500, 0x52f1f4c0, 0x5336f680, 0x538bf740, + 0x4920d800, 0x499dd9c0, 0x485adb80, 0x48e7da40, 0x4bd4df00, + 0x4b69dec0, 0x4aaedc80, 0x4a13dd40, 0x4cc8d600, 0x4c75d7c0, + 0x4db2d580, 0x4d0fd440, 0x4e3cd100, 0x4e81d0c0, 0x4f46d280, + 0x4ffbd340, 0x42f0c400, 0x424dc5c0, 0x438ac780, 0x4337c640, + 0x4004c300, 0x40b9c2c0, 0x417ec080, 0x41c3c140, 0x4718ca00, + 0x47a5cbc0, 0x4662c980, 0x46dfc840, 0x45eccd00, 0x4551ccc0, + 0x4496ce80, 0x442bcf40, 0x71c09000, 0x717d91c0, 0x70ba9380, + 0x70079240, 0x73349700, 0x738996c0, 0x724e9480, 0x72f39540, + 0x74289e00, 0x74959fc0, 0x75529d80, 0x75ef9c40, 0x76dc9900, + 0x766198c0, 0x77a69a80, 0x771b9b40, 0x7a108c00, 0x7aad8dc0, + 0x7b6a8f80, 0x7bd78e40, 0x78e48b00, 0x78598ac0, 0x799e8880, + 0x79238940, 0x7ff88200, 0x7f4583c0, 0x7e828180, 0x7e3f8040, + 0x7d0c8500, 0x7db184c0, 0x7c768680, 0x7ccb8740, 0x6660a800, + 0x66dda9c0, 0x671aab80, 0x67a7aa40, 0x6494af00, 0x6429aec0, + 0x65eeac80, 0x6553ad40, 0x6388a600, 0x6335a7c0, 0x62f2a580, + 0x624fa440, 0x617ca100, 0x61c1a0c0, 0x6006a280, 0x60bba340, + 0x6db0b400, 0x6d0db5c0, 0x6ccab780, 0x6c77b640, 0x6f44b300, + 0x6ff9b2c0, 0x6e3eb080, 0x6e83b140, 0x6858ba00, 0x68e5bbc0, + 0x6922b980, 0x699fb840, 0x6aacbd00, 0x6a11bcc0, 0x6bd6be80, + 0x6b6bbf40}}; + +static const word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0xc001bd0000000000, 0x80037a0100000000, + 0x4002c70100000000, 0x0007f40200000000, 0xc006490200000000, + 0x80048e0300000000, 0x4005330300000000, 0x000ee80500000000, + 0xc00f550500000000, 0x800d920400000000, 0x400c2f0400000000, + 0x00091c0700000000, 0xc008a10700000000, 0x800a660600000000, + 0x400bdb0600000000, 0x001cd00b00000000, 0xc01d6d0b00000000, + 0x801faa0a00000000, 0x401e170a00000000, 0x001b240900000000, + 0xc01a990900000000, 0x80185e0800000000, 0x4019e30800000000, + 0x0012380e00000000, 0xc013850e00000000, 0x8011420f00000000, + 0x4010ff0f00000000, 0x0015cc0c00000000, 0xc014710c00000000, + 0x8016b60d00000000, 0x40170b0d00000000, 0x0038a01700000000, + 0xc0391d1700000000, 0x803bda1600000000, 0x403a671600000000, + 0x003f541500000000, 0xc03ee91500000000, 0x803c2e1400000000, + 0x403d931400000000, 0x0036481200000000, 0xc037f51200000000, + 0x8035321300000000, 0x40348f1300000000, 0x0031bc1000000000, + 0xc030011000000000, 0x8032c61100000000, 0x40337b1100000000, + 0x0024701c00000000, 0xc025cd1c00000000, 0x80270a1d00000000, + 0x4026b71d00000000, 0x0023841e00000000, 0xc022391e00000000, + 0x8020fe1f00000000, 0x4021431f00000000, 0x002a981900000000, + 0xc02b251900000000, 0x8029e21800000000, 0x40285f1800000000, + 0x002d6c1b00000000, 0xc02cd11b00000000, 0x802e161a00000000, + 0x402fab1a00000000, 0x0070402f00000000, 0xc071fd2f00000000, + 0x80733a2e00000000, 0x4072872e00000000, 0x0077b42d00000000, + 0xc076092d00000000, 0x8074ce2c00000000, 0x4075732c00000000, + 0x007ea82a00000000, 0xc07f152a00000000, 0x807dd22b00000000, + 0x407c6f2b00000000, 0x00795c2800000000, 0xc078e12800000000, + 0x807a262900000000, 0x407b9b2900000000, 0x006c902400000000, + 0xc06d2d2400000000, 0x806fea2500000000, 0x406e572500000000, + 0x006b642600000000, 0xc06ad92600000000, 0x80681e2700000000, + 0x4069a32700000000, 0x0062782100000000, 0xc063c52100000000, + 0x8061022000000000, 0x4060bf2000000000, 0x00658c2300000000, + 0xc064312300000000, 0x8066f62200000000, 0x40674b2200000000, + 0x0048e03800000000, 0xc0495d3800000000, 0x804b9a3900000000, + 0x404a273900000000, 0x004f143a00000000, 0xc04ea93a00000000, + 0x804c6e3b00000000, 0x404dd33b00000000, 0x0046083d00000000, + 0xc047b53d00000000, 0x8045723c00000000, 0x4044cf3c00000000, + 0x0041fc3f00000000, 0xc040413f00000000, 0x8042863e00000000, + 0x40433b3e00000000, 0x0054303300000000, 0xc0558d3300000000, + 0x80574a3200000000, 0x4056f73200000000, 0x0053c43100000000, + 0xc052793100000000, 0x8050be3000000000, 0x4051033000000000, + 0x005ad83600000000, 0xc05b653600000000, 0x8059a23700000000, + 0x40581f3700000000, 0x005d2c3400000000, 0xc05c913400000000, + 0x805e563500000000, 0x405feb3500000000, 0x00e0805e00000000, + 0xc0e13d5e00000000, 0x80e3fa5f00000000, 0x40e2475f00000000, + 0x00e7745c00000000, 0xc0e6c95c00000000, 0x80e40e5d00000000, + 0x40e5b35d00000000, 0x00ee685b00000000, 0xc0efd55b00000000, + 0x80ed125a00000000, 0x40ecaf5a00000000, 0x00e99c5900000000, + 0xc0e8215900000000, 0x80eae65800000000, 0x40eb5b5800000000, + 0x00fc505500000000, 0xc0fded5500000000, 0x80ff2a5400000000, + 0x40fe975400000000, 0x00fba45700000000, 0xc0fa195700000000, + 0x80f8de5600000000, 0x40f9635600000000, 0x00f2b85000000000, + 0xc0f3055000000000, 0x80f1c25100000000, 0x40f07f5100000000, + 0x00f54c5200000000, 0xc0f4f15200000000, 0x80f6365300000000, + 0x40f78b5300000000, 0x00d8204900000000, 0xc0d99d4900000000, + 0x80db5a4800000000, 0x40dae74800000000, 0x00dfd44b00000000, + 0xc0de694b00000000, 0x80dcae4a00000000, 0x40dd134a00000000, + 0x00d6c84c00000000, 0xc0d7754c00000000, 0x80d5b24d00000000, + 0x40d40f4d00000000, 0x00d13c4e00000000, 0xc0d0814e00000000, + 0x80d2464f00000000, 0x40d3fb4f00000000, 0x00c4f04200000000, + 0xc0c54d4200000000, 0x80c78a4300000000, 0x40c6374300000000, + 0x00c3044000000000, 0xc0c2b94000000000, 0x80c07e4100000000, + 0x40c1c34100000000, 0x00ca184700000000, 0xc0cba54700000000, + 0x80c9624600000000, 0x40c8df4600000000, 0x00cdec4500000000, + 0xc0cc514500000000, 0x80ce964400000000, 0x40cf2b4400000000, + 0x0090c07100000000, 0xc0917d7100000000, 0x8093ba7000000000, + 0x4092077000000000, 0x0097347300000000, 0xc096897300000000, + 0x80944e7200000000, 0x4095f37200000000, 0x009e287400000000, + 0xc09f957400000000, 0x809d527500000000, 0x409cef7500000000, + 0x0099dc7600000000, 0xc098617600000000, 0x809aa67700000000, + 0x409b1b7700000000, 0x008c107a00000000, 0xc08dad7a00000000, + 0x808f6a7b00000000, 0x408ed77b00000000, 0x008be47800000000, + 0xc08a597800000000, 0x80889e7900000000, 0x4089237900000000, + 0x0082f87f00000000, 0xc083457f00000000, 0x8081827e00000000, + 0x40803f7e00000000, 0x00850c7d00000000, 0xc084b17d00000000, + 0x8086767c00000000, 0x4087cb7c00000000, 0x00a8606600000000, + 0xc0a9dd6600000000, 0x80ab1a6700000000, 0x40aaa76700000000, + 0x00af946400000000, 0xc0ae296400000000, 0x80acee6500000000, + 0x40ad536500000000, 0x00a6886300000000, 0xc0a7356300000000, + 0x80a5f26200000000, 0x40a44f6200000000, 0x00a17c6100000000, + 0xc0a0c16100000000, 0x80a2066000000000, 0x40a3bb6000000000, + 0x00b4b06d00000000, 0xc0b50d6d00000000, 0x80b7ca6c00000000, + 0x40b6776c00000000, 0x00b3446f00000000, 0xc0b2f96f00000000, + 0x80b03e6e00000000, 0x40b1836e00000000, 0x00ba586800000000, + 0xc0bbe56800000000, 0x80b9226900000000, 0x40b89f6900000000, + 0x00bdac6a00000000, 0xc0bc116a00000000, 0x80bed66b00000000, + 0x40bf6b6b00000000}, + {0x0000000000000000, 0x017d006c00000000, 0x02fa00d800000000, + 0x038700b400000000, 0x07f4020000000000, 0x0689026c00000000, + 0x050e02d800000000, 0x047302b400000000, 0x0ee8050000000000, + 0x0f95056c00000000, 0x0c1205d800000000, 0x0d6f05b400000000, + 0x091c070000000000, 0x0861076c00000000, 0x0be607d800000000, + 0x0a9b07b400000000, 0x1cd00b0000000000, 0x1dad0b6c00000000, + 0x1e2a0bd800000000, 0x1f570bb400000000, 0x1b24090000000000, + 0x1a59096c00000000, 0x19de09d800000000, 0x18a309b400000000, + 0x12380e0000000000, 0x13450e6c00000000, 0x10c20ed800000000, + 0x11bf0eb400000000, 0x15cc0c0000000000, 0x14b10c6c00000000, + 0x17360cd800000000, 0x164b0cb400000000, 0x38a0170000000000, + 0x39dd176c00000000, 0x3a5a17d800000000, 0x3b2717b400000000, + 0x3f54150000000000, 0x3e29156c00000000, 0x3dae15d800000000, + 0x3cd315b400000000, 0x3648120000000000, 0x3735126c00000000, + 0x34b212d800000000, 0x35cf12b400000000, 0x31bc100000000000, + 0x30c1106c00000000, 0x334610d800000000, 0x323b10b400000000, + 0x24701c0000000000, 0x250d1c6c00000000, 0x268a1cd800000000, + 0x27f71cb400000000, 0x23841e0000000000, 0x22f91e6c00000000, + 0x217e1ed800000000, 0x20031eb400000000, 0x2a98190000000000, + 0x2be5196c00000000, 0x286219d800000000, 0x291f19b400000000, + 0x2d6c1b0000000000, 0x2c111b6c00000000, 0x2f961bd800000000, + 0x2eeb1bb400000000, 0x70402f0000000000, 0x713d2f6c00000000, + 0x72ba2fd800000000, 0x73c72fb400000000, 0x77b42d0000000000, + 0x76c92d6c00000000, 0x754e2dd800000000, 0x74332db400000000, + 0x7ea82a0000000000, 0x7fd52a6c00000000, 0x7c522ad800000000, + 0x7d2f2ab400000000, 0x795c280000000000, 0x7821286c00000000, + 0x7ba628d800000000, 0x7adb28b400000000, 0x6c90240000000000, + 0x6ded246c00000000, 0x6e6a24d800000000, 0x6f1724b400000000, + 0x6b64260000000000, 0x6a19266c00000000, 0x699e26d800000000, + 0x68e326b400000000, 0x6278210000000000, 0x6305216c00000000, + 0x608221d800000000, 0x61ff21b400000000, 0x658c230000000000, + 0x64f1236c00000000, 0x677623d800000000, 0x660b23b400000000, + 0x48e0380000000000, 0x499d386c00000000, 0x4a1a38d800000000, + 0x4b6738b400000000, 0x4f143a0000000000, 0x4e693a6c00000000, + 0x4dee3ad800000000, 0x4c933ab400000000, 0x46083d0000000000, + 0x47753d6c00000000, 0x44f23dd800000000, 0x458f3db400000000, + 0x41fc3f0000000000, 0x40813f6c00000000, 0x43063fd800000000, + 0x427b3fb400000000, 0x5430330000000000, 0x554d336c00000000, + 0x56ca33d800000000, 0x57b733b400000000, 0x53c4310000000000, + 0x52b9316c00000000, 0x513e31d800000000, 0x504331b400000000, + 0x5ad8360000000000, 0x5ba5366c00000000, 0x582236d800000000, + 0x595f36b400000000, 0x5d2c340000000000, 0x5c51346c00000000, + 0x5fd634d800000000, 0x5eab34b400000000, 0xe0805e0000000000, + 0xe1fd5e6c00000000, 0xe27a5ed800000000, 0xe3075eb400000000, + 0xe7745c0000000000, 0xe6095c6c00000000, 0xe58e5cd800000000, + 0xe4f35cb400000000, 0xee685b0000000000, 0xef155b6c00000000, + 0xec925bd800000000, 0xedef5bb400000000, 0xe99c590000000000, + 0xe8e1596c00000000, 0xeb6659d800000000, 0xea1b59b400000000, + 0xfc50550000000000, 0xfd2d556c00000000, 0xfeaa55d800000000, + 0xffd755b400000000, 0xfba4570000000000, 0xfad9576c00000000, + 0xf95e57d800000000, 0xf82357b400000000, 0xf2b8500000000000, + 0xf3c5506c00000000, 0xf04250d800000000, 0xf13f50b400000000, + 0xf54c520000000000, 0xf431526c00000000, 0xf7b652d800000000, + 0xf6cb52b400000000, 0xd820490000000000, 0xd95d496c00000000, + 0xdada49d800000000, 0xdba749b400000000, 0xdfd44b0000000000, + 0xdea94b6c00000000, 0xdd2e4bd800000000, 0xdc534bb400000000, + 0xd6c84c0000000000, 0xd7b54c6c00000000, 0xd4324cd800000000, + 0xd54f4cb400000000, 0xd13c4e0000000000, 0xd0414e6c00000000, + 0xd3c64ed800000000, 0xd2bb4eb400000000, 0xc4f0420000000000, + 0xc58d426c00000000, 0xc60a42d800000000, 0xc77742b400000000, + 0xc304400000000000, 0xc279406c00000000, 0xc1fe40d800000000, + 0xc08340b400000000, 0xca18470000000000, 0xcb65476c00000000, + 0xc8e247d800000000, 0xc99f47b400000000, 0xcdec450000000000, + 0xcc91456c00000000, 0xcf1645d800000000, 0xce6b45b400000000, + 0x90c0710000000000, 0x91bd716c00000000, 0x923a71d800000000, + 0x934771b400000000, 0x9734730000000000, 0x9649736c00000000, + 0x95ce73d800000000, 0x94b373b400000000, 0x9e28740000000000, + 0x9f55746c00000000, 0x9cd274d800000000, 0x9daf74b400000000, + 0x99dc760000000000, 0x98a1766c00000000, 0x9b2676d800000000, + 0x9a5b76b400000000, 0x8c107a0000000000, 0x8d6d7a6c00000000, + 0x8eea7ad800000000, 0x8f977ab400000000, 0x8be4780000000000, + 0x8a99786c00000000, 0x891e78d800000000, 0x886378b400000000, + 0x82f87f0000000000, 0x83857f6c00000000, 0x80027fd800000000, + 0x817f7fb400000000, 0x850c7d0000000000, 0x84717d6c00000000, + 0x87f67dd800000000, 0x868b7db400000000, 0xa860660000000000, + 0xa91d666c00000000, 0xaa9a66d800000000, 0xabe766b400000000, + 0xaf94640000000000, 0xaee9646c00000000, 0xad6e64d800000000, + 0xac1364b400000000, 0xa688630000000000, 0xa7f5636c00000000, + 0xa47263d800000000, 0xa50f63b400000000, 0xa17c610000000000, + 0xa001616c00000000, 0xa38661d800000000, 0xa2fb61b400000000, + 0xb4b06d0000000000, 0xb5cd6d6c00000000, 0xb64a6dd800000000, + 0xb7376db400000000, 0xb3446f0000000000, 0xb2396f6c00000000, + 0xb1be6fd800000000, 0xb0c36fb400000000, 0xba58680000000000, + 0xbb25686c00000000, 0xb8a268d800000000, 0xb9df68b400000000, + 0xbdac6a0000000000, 0xbcd16a6c00000000, 0xbf566ad800000000, + 0xbe2b6ab400000000}, + {0x0000000000000000, 0x7c01fd9000000000, 0xfb02f99100000000, + 0x8703040100000000, 0xf505f19300000000, 0x89040c0300000000, + 0x0e07080200000000, 0x7206f59200000000, 0xe90be19700000000, + 0x950a1c0700000000, 0x1209180600000000, 0x6e08e59600000000, + 0x1c0e100400000000, 0x600fed9400000000, 0xe70ce99500000000, + 0x9b0d140500000000, 0xd117c19f00000000, 0xad163c0f00000000, + 0x2a15380e00000000, 0x5614c59e00000000, 0x2412300c00000000, + 0x5813cd9c00000000, 0xdf10c99d00000000, 0xa311340d00000000, + 0x381c200800000000, 0x441ddd9800000000, 0xc31ed99900000000, + 0xbf1f240900000000, 0xcd19d19b00000000, 0xb1182c0b00000000, + 0x361b280a00000000, 0x4a1ad59a00000000, 0xa12f818f00000000, + 0xdd2e7c1f00000000, 0x5a2d781e00000000, 0x262c858e00000000, + 0x542a701c00000000, 0x282b8d8c00000000, 0xaf28898d00000000, + 0xd329741d00000000, 0x4824601800000000, 0x34259d8800000000, + 0xb326998900000000, 0xcf27641900000000, 0xbd21918b00000000, + 0xc1206c1b00000000, 0x4623681a00000000, 0x3a22958a00000000, + 0x7038401000000000, 0x0c39bd8000000000, 0x8b3ab98100000000, + 0xf73b441100000000, 0x853db18300000000, 0xf93c4c1300000000, + 0x7e3f481200000000, 0x023eb58200000000, 0x9933a18700000000, + 0xe5325c1700000000, 0x6231581600000000, 0x1e30a58600000000, + 0x6c36501400000000, 0x1037ad8400000000, 0x9734a98500000000, + 0xeb35541500000000, 0x415f01af00000000, 0x3d5efc3f00000000, + 0xba5df83e00000000, 0xc65c05ae00000000, 0xb45af03c00000000, + 0xc85b0dac00000000, 0x4f5809ad00000000, 0x3359f43d00000000, + 0xa854e03800000000, 0xd4551da800000000, 0x535619a900000000, + 0x2f57e43900000000, 0x5d5111ab00000000, 0x2150ec3b00000000, + 0xa653e83a00000000, 0xda5215aa00000000, 0x9048c03000000000, + 0xec493da000000000, 0x6b4a39a100000000, 0x174bc43100000000, + 0x654d31a300000000, 0x194ccc3300000000, 0x9e4fc83200000000, + 0xe24e35a200000000, 0x794321a700000000, 0x0542dc3700000000, + 0x8241d83600000000, 0xfe4025a600000000, 0x8c46d03400000000, + 0xf0472da400000000, 0x774429a500000000, 0x0b45d43500000000, + 0xe070802000000000, 0x9c717db000000000, 0x1b7279b100000000, + 0x6773842100000000, 0x157571b300000000, 0x69748c2300000000, + 0xee77882200000000, 0x927675b200000000, 0x097b61b700000000, + 0x757a9c2700000000, 0xf279982600000000, 0x8e7865b600000000, + 0xfc7e902400000000, 0x807f6db400000000, 0x077c69b500000000, + 0x7b7d942500000000, 0x316741bf00000000, 0x4d66bc2f00000000, + 0xca65b82e00000000, 0xb66445be00000000, 0xc462b02c00000000, + 0xb8634dbc00000000, 0x3f6049bd00000000, 0x4361b42d00000000, + 0xd86ca02800000000, 0xa46d5db800000000, 0x236e59b900000000, + 0x5f6fa42900000000, 0x2d6951bb00000000, 0x5168ac2b00000000, + 0xd66ba82a00000000, 0xaa6a55ba00000000, 0x81be01ee00000000, + 0xfdbffc7e00000000, 0x7abcf87f00000000, 0x06bd05ef00000000, + 0x74bbf07d00000000, 0x08ba0ded00000000, 0x8fb909ec00000000, + 0xf3b8f47c00000000, 0x68b5e07900000000, 0x14b41de900000000, + 0x93b719e800000000, 0xefb6e47800000000, 0x9db011ea00000000, + 0xe1b1ec7a00000000, 0x66b2e87b00000000, 0x1ab315eb00000000, + 0x50a9c07100000000, 0x2ca83de100000000, 0xabab39e000000000, + 0xd7aac47000000000, 0xa5ac31e200000000, 0xd9adcc7200000000, + 0x5eaec87300000000, 0x22af35e300000000, 0xb9a221e600000000, + 0xc5a3dc7600000000, 0x42a0d87700000000, 0x3ea125e700000000, + 0x4ca7d07500000000, 0x30a62de500000000, 0xb7a529e400000000, + 0xcba4d47400000000, 0x2091806100000000, 0x5c907df100000000, + 0xdb9379f000000000, 0xa792846000000000, 0xd59471f200000000, + 0xa9958c6200000000, 0x2e96886300000000, 0x529775f300000000, + 0xc99a61f600000000, 0xb59b9c6600000000, 0x3298986700000000, + 0x4e9965f700000000, 0x3c9f906500000000, 0x409e6df500000000, + 0xc79d69f400000000, 0xbb9c946400000000, 0xf18641fe00000000, + 0x8d87bc6e00000000, 0x0a84b86f00000000, 0x768545ff00000000, + 0x0483b06d00000000, 0x78824dfd00000000, 0xff8149fc00000000, + 0x8380b46c00000000, 0x188da06900000000, 0x648c5df900000000, + 0xe38f59f800000000, 0x9f8ea46800000000, 0xed8851fa00000000, + 0x9189ac6a00000000, 0x168aa86b00000000, 0x6a8b55fb00000000, + 0xc0e1004100000000, 0xbce0fdd100000000, 0x3be3f9d000000000, + 0x47e2044000000000, 0x35e4f1d200000000, 0x49e50c4200000000, + 0xcee6084300000000, 0xb2e7f5d300000000, 0x29eae1d600000000, + 0x55eb1c4600000000, 0xd2e8184700000000, 0xaee9e5d700000000, + 0xdcef104500000000, 0xa0eeedd500000000, 0x27ede9d400000000, + 0x5bec144400000000, 0x11f6c1de00000000, 0x6df73c4e00000000, + 0xeaf4384f00000000, 0x96f5c5df00000000, 0xe4f3304d00000000, + 0x98f2cddd00000000, 0x1ff1c9dc00000000, 0x63f0344c00000000, + 0xf8fd204900000000, 0x84fcddd900000000, 0x03ffd9d800000000, + 0x7ffe244800000000, 0x0df8d1da00000000, 0x71f92c4a00000000, + 0xf6fa284b00000000, 0x8afbd5db00000000, 0x61ce81ce00000000, + 0x1dcf7c5e00000000, 0x9acc785f00000000, 0xe6cd85cf00000000, + 0x94cb705d00000000, 0xe8ca8dcd00000000, 0x6fc989cc00000000, + 0x13c8745c00000000, 0x88c5605900000000, 0xf4c49dc900000000, + 0x73c799c800000000, 0x0fc6645800000000, 0x7dc091ca00000000, + 0x01c16c5a00000000, 0x86c2685b00000000, 0xfac395cb00000000, + 0xb0d9405100000000, 0xccd8bdc100000000, 0x4bdbb9c000000000, + 0x37da445000000000, 0x45dcb1c200000000, 0x39dd4c5200000000, + 0xbede485300000000, 0xc2dfb5c300000000, 0x59d2a1c600000000, + 0x25d35c5600000000, 0xa2d0585700000000, 0xded1a5c700000000, + 0xacd7505500000000, 0xd0d6adc500000000, 0x57d5a9c400000000, + 0x2bd4545400000000}, + {0x0000000000000000, 0x008151a900000000, 0x0302a0e200000000, + 0x0383f14b00000000, 0x0504437500000000, 0x058512dc00000000, + 0x0606e39700000000, 0x0687b23e00000000, 0x0a0886ea00000000, + 0x0a89d74300000000, 0x090a260800000000, 0x098b77a100000000, + 0x0f0cc59f00000000, 0x0f8d943600000000, 0x0c0e657d00000000, + 0x0c8f34d400000000, 0x17100f6500000000, 0x17915ecc00000000, + 0x1412af8700000000, 0x1493fe2e00000000, 0x12144c1000000000, + 0x12951db900000000, 0x1116ecf200000000, 0x1197bd5b00000000, + 0x1d18898f00000000, 0x1d99d82600000000, 0x1e1a296d00000000, + 0x1e9b78c400000000, 0x181ccafa00000000, 0x189d9b5300000000, + 0x1b1e6a1800000000, 0x1b9f3bb100000000, 0x2e201eca00000000, + 0x2ea14f6300000000, 0x2d22be2800000000, 0x2da3ef8100000000, + 0x2b245dbf00000000, 0x2ba50c1600000000, 0x2826fd5d00000000, + 0x28a7acf400000000, 0x2428982000000000, 0x24a9c98900000000, + 0x272a38c200000000, 0x27ab696b00000000, 0x212cdb5500000000, + 0x21ad8afc00000000, 0x222e7bb700000000, 0x22af2a1e00000000, + 0x393011af00000000, 0x39b1400600000000, 0x3a32b14d00000000, + 0x3ab3e0e400000000, 0x3c3452da00000000, 0x3cb5037300000000, + 0x3f36f23800000000, 0x3fb7a39100000000, 0x3338974500000000, + 0x33b9c6ec00000000, 0x303a37a700000000, 0x30bb660e00000000, + 0x363cd43000000000, 0x36bd859900000000, 0x353e74d200000000, + 0x35bf257b00000000, 0x5f403f2400000000, 0x5fc16e8d00000000, + 0x5c429fc600000000, 0x5cc3ce6f00000000, 0x5a447c5100000000, + 0x5ac52df800000000, 0x5946dcb300000000, 0x59c78d1a00000000, + 0x5548b9ce00000000, 0x55c9e86700000000, 0x564a192c00000000, + 0x56cb488500000000, 0x504cfabb00000000, 0x50cdab1200000000, + 0x534e5a5900000000, 0x53cf0bf000000000, 0x4850304100000000, + 0x48d161e800000000, 0x4b5290a300000000, 0x4bd3c10a00000000, + 0x4d54733400000000, 0x4dd5229d00000000, 0x4e56d3d600000000, + 0x4ed7827f00000000, 0x4258b6ab00000000, 0x42d9e70200000000, + 0x415a164900000000, 0x41db47e000000000, 0x475cf5de00000000, + 0x47dda47700000000, 0x445e553c00000000, 0x44df049500000000, + 0x716021ee00000000, 0x71e1704700000000, 0x7262810c00000000, + 0x72e3d0a500000000, 0x7464629b00000000, 0x74e5333200000000, + 0x7766c27900000000, 0x77e793d000000000, 0x7b68a70400000000, + 0x7be9f6ad00000000, 0x786a07e600000000, 0x78eb564f00000000, + 0x7e6ce47100000000, 0x7eedb5d800000000, 0x7d6e449300000000, + 0x7def153a00000000, 0x66702e8b00000000, 0x66f17f2200000000, + 0x65728e6900000000, 0x65f3dfc000000000, 0x63746dfe00000000, + 0x63f53c5700000000, 0x6076cd1c00000000, 0x60f79cb500000000, + 0x6c78a86100000000, 0x6cf9f9c800000000, 0x6f7a088300000000, + 0x6ffb592a00000000, 0x697ceb1400000000, 0x69fdbabd00000000, + 0x6a7e4bf600000000, 0x6aff1a5f00000000, 0xbe807e4800000000, + 0xbe012fe100000000, 0xbd82deaa00000000, 0xbd038f0300000000, + 0xbb843d3d00000000, 0xbb056c9400000000, 0xb8869ddf00000000, + 0xb807cc7600000000, 0xb488f8a200000000, 0xb409a90b00000000, + 0xb78a584000000000, 0xb70b09e900000000, 0xb18cbbd700000000, + 0xb10dea7e00000000, 0xb28e1b3500000000, 0xb20f4a9c00000000, + 0xa990712d00000000, 0xa911208400000000, 0xaa92d1cf00000000, + 0xaa13806600000000, 0xac94325800000000, 0xac1563f100000000, + 0xaf9692ba00000000, 0xaf17c31300000000, 0xa398f7c700000000, + 0xa319a66e00000000, 0xa09a572500000000, 0xa01b068c00000000, + 0xa69cb4b200000000, 0xa61de51b00000000, 0xa59e145000000000, + 0xa51f45f900000000, 0x90a0608200000000, 0x9021312b00000000, + 0x93a2c06000000000, 0x932391c900000000, 0x95a423f700000000, + 0x9525725e00000000, 0x96a6831500000000, 0x9627d2bc00000000, + 0x9aa8e66800000000, 0x9a29b7c100000000, 0x99aa468a00000000, + 0x992b172300000000, 0x9faca51d00000000, 0x9f2df4b400000000, + 0x9cae05ff00000000, 0x9c2f545600000000, 0x87b06fe700000000, + 0x87313e4e00000000, 0x84b2cf0500000000, 0x84339eac00000000, + 0x82b42c9200000000, 0x82357d3b00000000, 0x81b68c7000000000, + 0x8137ddd900000000, 0x8db8e90d00000000, 0x8d39b8a400000000, + 0x8eba49ef00000000, 0x8e3b184600000000, 0x88bcaa7800000000, + 0x883dfbd100000000, 0x8bbe0a9a00000000, 0x8b3f5b3300000000, + 0xe1c0416c00000000, 0xe14110c500000000, 0xe2c2e18e00000000, + 0xe243b02700000000, 0xe4c4021900000000, 0xe44553b000000000, + 0xe7c6a2fb00000000, 0xe747f35200000000, 0xebc8c78600000000, + 0xeb49962f00000000, 0xe8ca676400000000, 0xe84b36cd00000000, + 0xeecc84f300000000, 0xee4dd55a00000000, 0xedce241100000000, + 0xed4f75b800000000, 0xf6d04e0900000000, 0xf6511fa000000000, + 0xf5d2eeeb00000000, 0xf553bf4200000000, 0xf3d40d7c00000000, + 0xf3555cd500000000, 0xf0d6ad9e00000000, 0xf057fc3700000000, + 0xfcd8c8e300000000, 0xfc59994a00000000, 0xffda680100000000, + 0xff5b39a800000000, 0xf9dc8b9600000000, 0xf95dda3f00000000, + 0xfade2b7400000000, 0xfa5f7add00000000, 0xcfe05fa600000000, + 0xcf610e0f00000000, 0xcce2ff4400000000, 0xcc63aeed00000000, + 0xcae41cd300000000, 0xca654d7a00000000, 0xc9e6bc3100000000, + 0xc967ed9800000000, 0xc5e8d94c00000000, 0xc56988e500000000, + 0xc6ea79ae00000000, 0xc66b280700000000, 0xc0ec9a3900000000, + 0xc06dcb9000000000, 0xc3ee3adb00000000, 0xc36f6b7200000000, + 0xd8f050c300000000, 0xd871016a00000000, 0xdbf2f02100000000, + 0xdb73a18800000000, 0xddf413b600000000, 0xdd75421f00000000, + 0xdef6b35400000000, 0xde77e2fd00000000, 0xd2f8d62900000000, + 0xd279878000000000, 0xd1fa76cb00000000, 0xd17b276200000000, + 0xd7fc955c00000000, 0xd77dc4f500000000, 0xd4fe35be00000000, + 0xd47f641700000000}, + {0x0000000000000000, 0x8151a90000000000, 0x02a3520100000000, + 0x83f2fb0100000000, 0x0446a50200000000, 0x85170c0200000000, + 0x06e5f70300000000, 0x87b45e0300000000, 0x088c4a0500000000, + 0x89dde30500000000, 0x0a2f180400000000, 0x8b7eb10400000000, + 0x0ccaef0700000000, 0x8d9b460700000000, 0x0e69bd0600000000, + 0x8f38140600000000, 0x1018950a00000000, 0x91493c0a00000000, + 0x12bbc70b00000000, 0x93ea6e0b00000000, 0x145e300800000000, + 0x950f990800000000, 0x16fd620900000000, 0x97accb0900000000, + 0x1894df0f00000000, 0x99c5760f00000000, 0x1a378d0e00000000, + 0x9b66240e00000000, 0x1cd27a0d00000000, 0x9d83d30d00000000, + 0x1e71280c00000000, 0x9f20810c00000000, 0x20302a1500000000, + 0xa161831500000000, 0x2293781400000000, 0xa3c2d11400000000, + 0x24768f1700000000, 0xa527261700000000, 0x26d5dd1600000000, + 0xa784741600000000, 0x28bc601000000000, 0xa9edc91000000000, + 0x2a1f321100000000, 0xab4e9b1100000000, 0x2cfac51200000000, + 0xadab6c1200000000, 0x2e59971300000000, 0xaf083e1300000000, + 0x3028bf1f00000000, 0xb179161f00000000, 0x328bed1e00000000, + 0xb3da441e00000000, 0x346e1a1d00000000, 0xb53fb31d00000000, + 0x36cd481c00000000, 0xb79ce11c00000000, 0x38a4f51a00000000, + 0xb9f55c1a00000000, 0x3a07a71b00000000, 0xbb560e1b00000000, + 0x3ce2501800000000, 0xbdb3f91800000000, 0x3e41021900000000, + 0xbf10ab1900000000, 0x4060542a00000000, 0xc131fd2a00000000, + 0x42c3062b00000000, 0xc392af2b00000000, 0x4426f12800000000, + 0xc577582800000000, 0x4685a32900000000, 0xc7d40a2900000000, + 0x48ec1e2f00000000, 0xc9bdb72f00000000, 0x4a4f4c2e00000000, + 0xcb1ee52e00000000, 0x4caabb2d00000000, 0xcdfb122d00000000, + 0x4e09e92c00000000, 0xcf58402c00000000, 0x5078c12000000000, + 0xd129682000000000, 0x52db932100000000, 0xd38a3a2100000000, + 0x543e642200000000, 0xd56fcd2200000000, 0x569d362300000000, + 0xd7cc9f2300000000, 0x58f48b2500000000, 0xd9a5222500000000, + 0x5a57d92400000000, 0xdb06702400000000, 0x5cb22e2700000000, + 0xdde3872700000000, 0x5e117c2600000000, 0xdf40d52600000000, + 0x60507e3f00000000, 0xe101d73f00000000, 0x62f32c3e00000000, + 0xe3a2853e00000000, 0x6416db3d00000000, 0xe547723d00000000, + 0x66b5893c00000000, 0xe7e4203c00000000, 0x68dc343a00000000, + 0xe98d9d3a00000000, 0x6a7f663b00000000, 0xeb2ecf3b00000000, + 0x6c9a913800000000, 0xedcb383800000000, 0x6e39c33900000000, + 0xef686a3900000000, 0x7048eb3500000000, 0xf119423500000000, + 0x72ebb93400000000, 0xf3ba103400000000, 0x740e4e3700000000, + 0xf55fe73700000000, 0x76ad1c3600000000, 0xf7fcb53600000000, + 0x78c4a13000000000, 0xf995083000000000, 0x7a67f33100000000, + 0xfb365a3100000000, 0x7c82043200000000, 0xfdd3ad3200000000, + 0x7e21563300000000, 0xff70ff3300000000, 0x80c0a85400000000, + 0x0191015400000000, 0x8263fa5500000000, 0x0332535500000000, + 0x84860d5600000000, 0x05d7a45600000000, 0x86255f5700000000, + 0x0774f65700000000, 0x884ce25100000000, 0x091d4b5100000000, + 0x8aefb05000000000, 0x0bbe195000000000, 0x8c0a475300000000, + 0x0d5bee5300000000, 0x8ea9155200000000, 0x0ff8bc5200000000, + 0x90d83d5e00000000, 0x1189945e00000000, 0x927b6f5f00000000, + 0x132ac65f00000000, 0x949e985c00000000, 0x15cf315c00000000, + 0x963dca5d00000000, 0x176c635d00000000, 0x9854775b00000000, + 0x1905de5b00000000, 0x9af7255a00000000, 0x1ba68c5a00000000, + 0x9c12d25900000000, 0x1d437b5900000000, 0x9eb1805800000000, + 0x1fe0295800000000, 0xa0f0824100000000, 0x21a12b4100000000, + 0xa253d04000000000, 0x2302794000000000, 0xa4b6274300000000, + 0x25e78e4300000000, 0xa615754200000000, 0x2744dc4200000000, + 0xa87cc84400000000, 0x292d614400000000, 0xaadf9a4500000000, + 0x2b8e334500000000, 0xac3a6d4600000000, 0x2d6bc44600000000, + 0xae993f4700000000, 0x2fc8964700000000, 0xb0e8174b00000000, + 0x31b9be4b00000000, 0xb24b454a00000000, 0x331aec4a00000000, + 0xb4aeb24900000000, 0x35ff1b4900000000, 0xb60de04800000000, + 0x375c494800000000, 0xb8645d4e00000000, 0x3935f44e00000000, + 0xbac70f4f00000000, 0x3b96a64f00000000, 0xbc22f84c00000000, + 0x3d73514c00000000, 0xbe81aa4d00000000, 0x3fd0034d00000000, + 0xc0a0fc7e00000000, 0x41f1557e00000000, 0xc203ae7f00000000, + 0x4352077f00000000, 0xc4e6597c00000000, 0x45b7f07c00000000, + 0xc6450b7d00000000, 0x4714a27d00000000, 0xc82cb67b00000000, + 0x497d1f7b00000000, 0xca8fe47a00000000, 0x4bde4d7a00000000, + 0xcc6a137900000000, 0x4d3bba7900000000, 0xcec9417800000000, + 0x4f98e87800000000, 0xd0b8697400000000, 0x51e9c07400000000, + 0xd21b3b7500000000, 0x534a927500000000, 0xd4fecc7600000000, + 0x55af657600000000, 0xd65d9e7700000000, 0x570c377700000000, + 0xd834237100000000, 0x59658a7100000000, 0xda97717000000000, + 0x5bc6d87000000000, 0xdc72867300000000, 0x5d232f7300000000, + 0xded1d47200000000, 0x5f807d7200000000, 0xe090d66b00000000, + 0x61c17f6b00000000, 0xe233846a00000000, 0x63622d6a00000000, + 0xe4d6736900000000, 0x6587da6900000000, 0xe675216800000000, + 0x6724886800000000, 0xe81c9c6e00000000, 0x694d356e00000000, + 0xeabfce6f00000000, 0x6bee676f00000000, 0xec5a396c00000000, + 0x6d0b906c00000000, 0xeef96b6d00000000, 0x6fa8c26d00000000, + 0xf088436100000000, 0x71d9ea6100000000, 0xf22b116000000000, + 0x737ab86000000000, 0xf4cee66300000000, 0x759f4f6300000000, + 0xf66db46200000000, 0x773c1d6200000000, 0xf804096400000000, + 0x7955a06400000000, 0xfaa75b6500000000, 0x7bf6f26500000000, + 0xfc42ac6600000000, 0x7d13056600000000, 0xfee1fe6700000000, + 0x7fb0576700000000}, + {0x0000000000000000, 0x5128904800000000, 0xa250209100000000, + 0xf378b0d900000000, 0x47a1439200000000, 0x1689d3da00000000, + 0xe5f1630300000000, 0xb4d9f34b00000000, 0x8d42849400000000, + 0xdc6a14dc00000000, 0x2f12a40500000000, 0x7e3a344d00000000, + 0xcae3c70600000000, 0x9bcb574e00000000, 0x68b3e79700000000, + 0x399b77df00000000, 0x19850b9900000000, 0x48ad9bd100000000, + 0xbbd52b0800000000, 0xeafdbb4000000000, 0x5e24480b00000000, + 0x0f0cd84300000000, 0xfc74689a00000000, 0xad5cf8d200000000, + 0x94c78f0d00000000, 0xc5ef1f4500000000, 0x3697af9c00000000, + 0x67bf3fd400000000, 0xd366cc9f00000000, 0x824e5cd700000000, + 0x7136ec0e00000000, 0x201e7c4600000000, 0x310a148200000000, + 0x602284ca00000000, 0x935a341300000000, 0xc272a45b00000000, + 0x76ab571000000000, 0x2783c75800000000, 0xd4fb778100000000, + 0x85d3e7c900000000, 0xbc48901600000000, 0xed60005e00000000, + 0x1e18b08700000000, 0x4f3020cf00000000, 0xfbe9d38400000000, + 0xaac143cc00000000, 0x59b9f31500000000, 0x0891635d00000000, + 0x288f1f1b00000000, 0x79a78f5300000000, 0x8adf3f8a00000000, + 0xdbf7afc200000000, 0x6f2e5c8900000000, 0x3e06ccc100000000, + 0xcd7e7c1800000000, 0x9c56ec5000000000, 0xa5cd9b8f00000000, + 0xf4e50bc700000000, 0x079dbb1e00000000, 0x56b52b5600000000, + 0xe26cd81d00000000, 0xb344485500000000, 0x403cf88c00000000, + 0x111468c400000000, 0x61142bb400000000, 0x303cbbfc00000000, + 0xc3440b2500000000, 0x926c9b6d00000000, 0x26b5682600000000, + 0x779df86e00000000, 0x84e548b700000000, 0xd5cdd8ff00000000, + 0xec56af2000000000, 0xbd7e3f6800000000, 0x4e068fb100000000, + 0x1f2e1ff900000000, 0xabf7ecb200000000, 0xfadf7cfa00000000, + 0x09a7cc2300000000, 0x588f5c6b00000000, 0x7891202d00000000, + 0x29b9b06500000000, 0xdac100bc00000000, 0x8be990f400000000, + 0x3f3063bf00000000, 0x6e18f3f700000000, 0x9d60432e00000000, + 0xcc48d36600000000, 0xf5d3a4b900000000, 0xa4fb34f100000000, + 0x5783842800000000, 0x06ab146000000000, 0xb272e72b00000000, + 0xe35a776300000000, 0x1022c7ba00000000, 0x410a57f200000000, + 0x501e3f3600000000, 0x0136af7e00000000, 0xf24e1fa700000000, + 0xa3668fef00000000, 0x17bf7ca400000000, 0x4697ecec00000000, + 0xb5ef5c3500000000, 0xe4c7cc7d00000000, 0xdd5cbba200000000, + 0x8c742bea00000000, 0x7f0c9b3300000000, 0x2e240b7b00000000, + 0x9afdf83000000000, 0xcbd5687800000000, 0x38add8a100000000, + 0x698548e900000000, 0x499b34af00000000, 0x18b3a4e700000000, + 0xebcb143e00000000, 0xbae3847600000000, 0x0e3a773d00000000, + 0x5f12e77500000000, 0xac6a57ac00000000, 0xfd42c7e400000000, + 0xc4d9b03b00000000, 0x95f1207300000000, 0x668990aa00000000, + 0x37a100e200000000, 0x8378f3a900000000, 0xd25063e100000000, + 0x2128d33800000000, 0x7000437000000000, 0xc12855d800000000, + 0x9000c59000000000, 0x6378754900000000, 0x3250e50100000000, + 0x8689164a00000000, 0xd7a1860200000000, 0x24d936db00000000, + 0x75f1a69300000000, 0x4c6ad14c00000000, 0x1d42410400000000, + 0xee3af1dd00000000, 0xbf12619500000000, 0x0bcb92de00000000, + 0x5ae3029600000000, 0xa99bb24f00000000, 0xf8b3220700000000, + 0xd8ad5e4100000000, 0x8985ce0900000000, 0x7afd7ed000000000, + 0x2bd5ee9800000000, 0x9f0c1dd300000000, 0xce248d9b00000000, + 0x3d5c3d4200000000, 0x6c74ad0a00000000, 0x55efdad500000000, + 0x04c74a9d00000000, 0xf7bffa4400000000, 0xa6976a0c00000000, + 0x124e994700000000, 0x4366090f00000000, 0xb01eb9d600000000, + 0xe136299e00000000, 0xf022415a00000000, 0xa10ad11200000000, + 0x527261cb00000000, 0x035af18300000000, 0xb78302c800000000, + 0xe6ab928000000000, 0x15d3225900000000, 0x44fbb21100000000, + 0x7d60c5ce00000000, 0x2c48558600000000, 0xdf30e55f00000000, + 0x8e18751700000000, 0x3ac1865c00000000, 0x6be9161400000000, + 0x9891a6cd00000000, 0xc9b9368500000000, 0xe9a74ac300000000, + 0xb88fda8b00000000, 0x4bf76a5200000000, 0x1adffa1a00000000, + 0xae06095100000000, 0xff2e991900000000, 0x0c5629c000000000, + 0x5d7eb98800000000, 0x64e5ce5700000000, 0x35cd5e1f00000000, + 0xc6b5eec600000000, 0x979d7e8e00000000, 0x23448dc500000000, + 0x726c1d8d00000000, 0x8114ad5400000000, 0xd03c3d1c00000000, + 0xa03c7e6c00000000, 0xf114ee2400000000, 0x026c5efd00000000, + 0x5344ceb500000000, 0xe79d3dfe00000000, 0xb6b5adb600000000, + 0x45cd1d6f00000000, 0x14e58d2700000000, 0x2d7efaf800000000, + 0x7c566ab000000000, 0x8f2eda6900000000, 0xde064a2100000000, + 0x6adfb96a00000000, 0x3bf7292200000000, 0xc88f99fb00000000, + 0x99a709b300000000, 0xb9b975f500000000, 0xe891e5bd00000000, + 0x1be9556400000000, 0x4ac1c52c00000000, 0xfe18366700000000, + 0xaf30a62f00000000, 0x5c4816f600000000, 0x0d6086be00000000, + 0x34fbf16100000000, 0x65d3612900000000, 0x96abd1f000000000, + 0xc78341b800000000, 0x735ab2f300000000, 0x227222bb00000000, + 0xd10a926200000000, 0x8022022a00000000, 0x91366aee00000000, + 0xc01efaa600000000, 0x33664a7f00000000, 0x624eda3700000000, + 0xd697297c00000000, 0x87bfb93400000000, 0x74c709ed00000000, + 0x25ef99a500000000, 0x1c74ee7a00000000, 0x4d5c7e3200000000, + 0xbe24ceeb00000000, 0xef0c5ea300000000, 0x5bd5ade800000000, + 0x0afd3da000000000, 0xf9858d7900000000, 0xa8ad1d3100000000, + 0x88b3617700000000, 0xd99bf13f00000000, 0x2ae341e600000000, + 0x7bcbd1ae00000000, 0xcf1222e500000000, 0x9e3ab2ad00000000, + 0x6d42027400000000, 0x3c6a923c00000000, 0x05f1e5e300000000, + 0x54d975ab00000000, 0xa7a1c57200000000, 0xf689553a00000000, + 0x4250a67100000000, 0x1378363900000000, 0xe00086e000000000, + 0xb12816a800000000}, + {0x0000000000000000, 0x29c1d9bd00000000, 0x5182b0cb00000000, + 0x7843697600000000, 0xa104622700000000, 0x88c5bb9a00000000, + 0xf086d2ec00000000, 0xd9470b5100000000, 0x4209c44e00000000, + 0x6bc81df300000000, 0x138b748500000000, 0x3a4aad3800000000, + 0xe30da66900000000, 0xcacc7fd400000000, 0xb28f16a200000000, + 0x9b4ecf1f00000000, 0x8412889d00000000, 0xadd3512000000000, + 0xd590385600000000, 0xfc51e1eb00000000, 0x2516eaba00000000, + 0x0cd7330700000000, 0x74945a7100000000, 0x5d5583cc00000000, + 0xc61b4cd300000000, 0xefda956e00000000, 0x9799fc1800000000, + 0xbe5825a500000000, 0x671f2ef400000000, 0x4edef74900000000, + 0x369d9e3f00000000, 0x1f5c478200000000, 0x0b25138b00000000, + 0x22e4ca3600000000, 0x5aa7a34000000000, 0x73667afd00000000, + 0xaa2171ac00000000, 0x83e0a81100000000, 0xfba3c16700000000, + 0xd26218da00000000, 0x492cd7c500000000, 0x60ed0e7800000000, + 0x18ae670e00000000, 0x316fbeb300000000, 0xe828b5e200000000, + 0xc1e96c5f00000000, 0xb9aa052900000000, 0x906bdc9400000000, + 0x8f379b1600000000, 0xa6f642ab00000000, 0xdeb52bdd00000000, + 0xf774f26000000000, 0x2e33f93100000000, 0x07f2208c00000000, + 0x7fb149fa00000000, 0x5670904700000000, 0xcd3e5f5800000000, + 0xe4ff86e500000000, 0x9cbcef9300000000, 0xb57d362e00000000, + 0x6c3a3d7f00000000, 0x45fbe4c200000000, 0x3db88db400000000, + 0x1479540900000000, 0x154a25a600000000, 0x3c8bfc1b00000000, + 0x44c8956d00000000, 0x6d094cd000000000, 0xb44e478100000000, + 0x9d8f9e3c00000000, 0xe5ccf74a00000000, 0xcc0d2ef700000000, + 0x5743e1e800000000, 0x7e82385500000000, 0x06c1512300000000, + 0x2f00889e00000000, 0xf64783cf00000000, 0xdf865a7200000000, + 0xa7c5330400000000, 0x8e04eab900000000, 0x9158ad3b00000000, + 0xb899748600000000, 0xc0da1df000000000, 0xe91bc44d00000000, + 0x305ccf1c00000000, 0x199d16a100000000, 0x61de7fd700000000, + 0x481fa66a00000000, 0xd351697500000000, 0xfa90b0c800000000, + 0x82d3d9be00000000, 0xab12000300000000, 0x72550b5200000000, + 0x5b94d2ef00000000, 0x23d7bb9900000000, 0x0a16622400000000, + 0x1e6f362d00000000, 0x37aeef9000000000, 0x4fed86e600000000, + 0x662c5f5b00000000, 0xbf6b540a00000000, 0x96aa8db700000000, + 0xeee9e4c100000000, 0xc7283d7c00000000, 0x5c66f26300000000, + 0x75a72bde00000000, 0x0de442a800000000, 0x24259b1500000000, + 0xfd62904400000000, 0xd4a349f900000000, 0xace0208f00000000, + 0x8521f93200000000, 0x9a7dbeb000000000, 0xb3bc670d00000000, + 0xcbff0e7b00000000, 0xe23ed7c600000000, 0x3b79dc9700000000, + 0x12b8052a00000000, 0x6afb6c5c00000000, 0x433ab5e100000000, + 0xd8747afe00000000, 0xf1b5a34300000000, 0x89f6ca3500000000, + 0xa037138800000000, 0x797018d900000000, 0x50b1c16400000000, + 0x28f2a81200000000, 0x013371af00000000, 0x299449fc00000000, + 0x0055904100000000, 0x7816f93700000000, 0x51d7208a00000000, + 0x88902bdb00000000, 0xa151f26600000000, 0xd9129b1000000000, + 0xf0d342ad00000000, 0x6b9d8db200000000, 0x425c540f00000000, + 0x3a1f3d7900000000, 0x13dee4c400000000, 0xca99ef9500000000, + 0xe358362800000000, 0x9b1b5f5e00000000, 0xb2da86e300000000, + 0xad86c16100000000, 0x844718dc00000000, 0xfc0471aa00000000, + 0xd5c5a81700000000, 0x0c82a34600000000, 0x25437afb00000000, + 0x5d00138d00000000, 0x74c1ca3000000000, 0xef8f052f00000000, + 0xc64edc9200000000, 0xbe0db5e400000000, 0x97cc6c5900000000, + 0x4e8b670800000000, 0x674abeb500000000, 0x1f09d7c300000000, + 0x36c80e7e00000000, 0x22b15a7700000000, 0x0b7083ca00000000, + 0x7333eabc00000000, 0x5af2330100000000, 0x83b5385000000000, + 0xaa74e1ed00000000, 0xd237889b00000000, 0xfbf6512600000000, + 0x60b89e3900000000, 0x4979478400000000, 0x313a2ef200000000, + 0x18fbf74f00000000, 0xc1bcfc1e00000000, 0xe87d25a300000000, + 0x903e4cd500000000, 0xb9ff956800000000, 0xa6a3d2ea00000000, + 0x8f620b5700000000, 0xf721622100000000, 0xdee0bb9c00000000, + 0x07a7b0cd00000000, 0x2e66697000000000, 0x5625000600000000, + 0x7fe4d9bb00000000, 0xe4aa16a400000000, 0xcd6bcf1900000000, + 0xb528a66f00000000, 0x9ce97fd200000000, 0x45ae748300000000, + 0x6c6fad3e00000000, 0x142cc44800000000, 0x3ded1df500000000, + 0x3cde6c5a00000000, 0x151fb5e700000000, 0x6d5cdc9100000000, + 0x449d052c00000000, 0x9dda0e7d00000000, 0xb41bd7c000000000, + 0xcc58beb600000000, 0xe599670b00000000, 0x7ed7a81400000000, + 0x571671a900000000, 0x2f5518df00000000, 0x0694c16200000000, + 0xdfd3ca3300000000, 0xf612138e00000000, 0x8e517af800000000, + 0xa790a34500000000, 0xb8cce4c700000000, 0x910d3d7a00000000, + 0xe94e540c00000000, 0xc08f8db100000000, 0x19c886e000000000, + 0x30095f5d00000000, 0x484a362b00000000, 0x618bef9600000000, + 0xfac5208900000000, 0xd304f93400000000, 0xab47904200000000, + 0x828649ff00000000, 0x5bc142ae00000000, 0x72009b1300000000, + 0x0a43f26500000000, 0x23822bd800000000, 0x37fb7fd100000000, + 0x1e3aa66c00000000, 0x6679cf1a00000000, 0x4fb816a700000000, + 0x96ff1df600000000, 0xbf3ec44b00000000, 0xc77dad3d00000000, + 0xeebc748000000000, 0x75f2bb9f00000000, 0x5c33622200000000, + 0x24700b5400000000, 0x0db1d2e900000000, 0xd4f6d9b800000000, + 0xfd37000500000000, 0x8574697300000000, 0xacb5b0ce00000000, + 0xb3e9f74c00000000, 0x9a282ef100000000, 0xe26b478700000000, + 0xcbaa9e3a00000000, 0x12ed956b00000000, 0x3b2c4cd600000000, + 0x436f25a000000000, 0x6aaefc1d00000000, 0xf1e0330200000000, + 0xd821eabf00000000, 0xa06283c900000000, 0x89a35a7400000000, + 0x50e4512500000000, 0x7925889800000000, 0x0166e1ee00000000, + 0x28a7385300000000}, + {0x0000000000000000, 0xc0f0ac8600000000, 0x83e15abd00000000, + 0x4311f63b00000000, 0x05c3b6ca00000000, 0xc5331a4c00000000, + 0x8622ec7700000000, 0x46d240f100000000, 0x09866e2500000000, + 0xc976c2a300000000, 0x8a67349800000000, 0x4a97981e00000000, + 0x0c45d8ef00000000, 0xccb5746900000000, 0x8fa4825200000000, + 0x4f542ed400000000, 0x120cdd4a00000000, 0xd2fc71cc00000000, + 0x91ed87f700000000, 0x511d2b7100000000, 0x17cf6b8000000000, + 0xd73fc70600000000, 0x942e313d00000000, 0x54de9dbb00000000, + 0x1b8ab36f00000000, 0xdb7a1fe900000000, 0x986be9d200000000, + 0x589b455400000000, 0x1e4905a500000000, 0xdeb9a92300000000, + 0x9da85f1800000000, 0x5d58f39e00000000, 0x2418ba9500000000, + 0xe4e8161300000000, 0xa7f9e02800000000, 0x67094cae00000000, + 0x21db0c5f00000000, 0xe12ba0d900000000, 0xa23a56e200000000, + 0x62cafa6400000000, 0x2d9ed4b000000000, 0xed6e783600000000, + 0xae7f8e0d00000000, 0x6e8f228b00000000, 0x285d627a00000000, + 0xe8adcefc00000000, 0xabbc38c700000000, 0x6b4c944100000000, + 0x361467df00000000, 0xf6e4cb5900000000, 0xb5f53d6200000000, + 0x750591e400000000, 0x33d7d11500000000, 0xf3277d9300000000, + 0xb0368ba800000000, 0x70c6272e00000000, 0x3f9209fa00000000, + 0xff62a57c00000000, 0xbc73534700000000, 0x7c83ffc100000000, + 0x3a51bf3000000000, 0xfaa113b600000000, 0xb9b0e58d00000000, + 0x7940490b00000000, 0x4b30779b00000000, 0x8bc0db1d00000000, + 0xc8d12d2600000000, 0x082181a000000000, 0x4ef3c15100000000, + 0x8e036dd700000000, 0xcd129bec00000000, 0x0de2376a00000000, + 0x42b619be00000000, 0x8246b53800000000, 0xc157430300000000, + 0x01a7ef8500000000, 0x4775af7400000000, 0x878503f200000000, + 0xc494f5c900000000, 0x0464594f00000000, 0x593caad100000000, + 0x99cc065700000000, 0xdaddf06c00000000, 0x1a2d5cea00000000, + 0x5cff1c1b00000000, 0x9c0fb09d00000000, 0xdf1e46a600000000, + 0x1feeea2000000000, 0x50bac4f400000000, 0x904a687200000000, + 0xd35b9e4900000000, 0x13ab32cf00000000, 0x5579723e00000000, + 0x9589deb800000000, 0xd698288300000000, 0x1668840500000000, + 0x6f28cd0e00000000, 0xafd8618800000000, 0xecc997b300000000, + 0x2c393b3500000000, 0x6aeb7bc400000000, 0xaa1bd74200000000, + 0xe90a217900000000, 0x29fa8dff00000000, 0x66aea32b00000000, + 0xa65e0fad00000000, 0xe54ff99600000000, 0x25bf551000000000, + 0x636d15e100000000, 0xa39db96700000000, 0xe08c4f5c00000000, + 0x207ce3da00000000, 0x7d24104400000000, 0xbdd4bcc200000000, + 0xfec54af900000000, 0x3e35e67f00000000, 0x78e7a68e00000000, + 0xb8170a0800000000, 0xfb06fc3300000000, 0x3bf650b500000000, + 0x74a27e6100000000, 0xb452d2e700000000, 0xf74324dc00000000, + 0x37b3885a00000000, 0x7161c8ab00000000, 0xb191642d00000000, + 0xf280921600000000, 0x32703e9000000000, 0x9560ed8600000000, + 0x5590410000000000, 0x1681b73b00000000, 0xd6711bbd00000000, + 0x90a35b4c00000000, 0x5053f7ca00000000, 0x134201f100000000, + 0xd3b2ad7700000000, 0x9ce683a300000000, 0x5c162f2500000000, + 0x1f07d91e00000000, 0xdff7759800000000, 0x9925356900000000, + 0x59d599ef00000000, 0x1ac46fd400000000, 0xda34c35200000000, + 0x876c30cc00000000, 0x479c9c4a00000000, 0x048d6a7100000000, + 0xc47dc6f700000000, 0x82af860600000000, 0x425f2a8000000000, + 0x014edcbb00000000, 0xc1be703d00000000, 0x8eea5ee900000000, + 0x4e1af26f00000000, 0x0d0b045400000000, 0xcdfba8d200000000, + 0x8b29e82300000000, 0x4bd944a500000000, 0x08c8b29e00000000, + 0xc8381e1800000000, 0xb178571300000000, 0x7188fb9500000000, + 0x32990dae00000000, 0xf269a12800000000, 0xb4bbe1d900000000, + 0x744b4d5f00000000, 0x375abb6400000000, 0xf7aa17e200000000, + 0xb8fe393600000000, 0x780e95b000000000, 0x3b1f638b00000000, + 0xfbefcf0d00000000, 0xbd3d8ffc00000000, 0x7dcd237a00000000, + 0x3edcd54100000000, 0xfe2c79c700000000, 0xa3748a5900000000, + 0x638426df00000000, 0x2095d0e400000000, 0xe0657c6200000000, + 0xa6b73c9300000000, 0x6647901500000000, 0x2556662e00000000, + 0xe5a6caa800000000, 0xaaf2e47c00000000, 0x6a0248fa00000000, + 0x2913bec100000000, 0xe9e3124700000000, 0xaf3152b600000000, + 0x6fc1fe3000000000, 0x2cd0080b00000000, 0xec20a48d00000000, + 0xde509a1d00000000, 0x1ea0369b00000000, 0x5db1c0a000000000, + 0x9d416c2600000000, 0xdb932cd700000000, 0x1b63805100000000, + 0x5872766a00000000, 0x9882daec00000000, 0xd7d6f43800000000, + 0x172658be00000000, 0x5437ae8500000000, 0x94c7020300000000, + 0xd21542f200000000, 0x12e5ee7400000000, 0x51f4184f00000000, + 0x9104b4c900000000, 0xcc5c475700000000, 0x0cacebd100000000, + 0x4fbd1dea00000000, 0x8f4db16c00000000, 0xc99ff19d00000000, + 0x096f5d1b00000000, 0x4a7eab2000000000, 0x8a8e07a600000000, + 0xc5da297200000000, 0x052a85f400000000, 0x463b73cf00000000, + 0x86cbdf4900000000, 0xc0199fb800000000, 0x00e9333e00000000, + 0x43f8c50500000000, 0x8308698300000000, 0xfa48208800000000, + 0x3ab88c0e00000000, 0x79a97a3500000000, 0xb959d6b300000000, + 0xff8b964200000000, 0x3f7b3ac400000000, 0x7c6accff00000000, + 0xbc9a607900000000, 0xf3ce4ead00000000, 0x333ee22b00000000, + 0x702f141000000000, 0xb0dfb89600000000, 0xf60df86700000000, + 0x36fd54e100000000, 0x75eca2da00000000, 0xb51c0e5c00000000, + 0xe844fdc200000000, 0x28b4514400000000, 0x6ba5a77f00000000, + 0xab550bf900000000, 0xed874b0800000000, 0x2d77e78e00000000, + 0x6e6611b500000000, 0xae96bd3300000000, 0xe1c293e700000000, + 0x21323f6100000000, 0x6223c95a00000000, 0xa2d365dc00000000, + 0xe401252d00000000, 0x24f189ab00000000, 0x67e07f9000000000, + 0xa710d31600000000}}; + +#else /* W == 4 */ + +static const crc_t crc_braid_table[][256] = { + {0x00000000, 0x5c11c100, 0xb8238200, 0xe4324300, 0xc0440403, + 0x9c55c503, 0x78678603, 0x24764703, 0x308b0805, 0x6c9ac905, + 0x88a88a05, 0xd4b94b05, 0xf0cf0c06, 0xacdecd06, 0x48ec8e06, + 0x14fd4f06, 0x6116100a, 0x3d07d10a, 0xd935920a, 0x8524530a, + 0xa1521409, 0xfd43d509, 0x19719609, 0x45605709, 0x519d180f, + 0x0d8cd90f, 0xe9be9a0f, 0xb5af5b0f, 0x91d91c0c, 0xcdc8dd0c, + 0x29fa9e0c, 0x75eb5f0c, 0xc22c2014, 0x9e3de114, 0x7a0fa214, + 0x261e6314, 0x02682417, 0x5e79e517, 0xba4ba617, 0xe65a6717, + 0xf2a72811, 0xaeb6e911, 0x4a84aa11, 0x16956b11, 0x32e32c12, + 0x6ef2ed12, 0x8ac0ae12, 0xd6d16f12, 0xa33a301e, 0xff2bf11e, + 0x1b19b21e, 0x4708731e, 0x637e341d, 0x3f6ff51d, 0xdb5db61d, + 0x874c771d, 0x93b1381b, 0xcfa0f91b, 0x2b92ba1b, 0x77837b1b, + 0x53f53c18, 0x0fe4fd18, 0xebd6be18, 0xb7c77f18, 0x345b402b, + 0x684a812b, 0x8c78c22b, 0xd069032b, 0xf41f4428, 0xa80e8528, + 0x4c3cc628, 0x102d0728, 0x04d0482e, 0x58c1892e, 0xbcf3ca2e, + 0xe0e20b2e, 0xc4944c2d, 0x98858d2d, 0x7cb7ce2d, 0x20a60f2d, + 0x554d5021, 0x095c9121, 0xed6ed221, 0xb17f1321, 0x95095422, + 0xc9189522, 0x2d2ad622, 0x713b1722, 0x65c65824, 0x39d79924, + 0xdde5da24, 0x81f41b24, 0xa5825c27, 0xf9939d27, 0x1da1de27, + 0x41b01f27, 0xf677603f, 0xaa66a13f, 0x4e54e23f, 0x1245233f, + 0x3633643c, 0x6a22a53c, 0x8e10e63c, 0xd201273c, 0xc6fc683a, + 0x9aeda93a, 0x7edfea3a, 0x22ce2b3a, 0x06b86c39, 0x5aa9ad39, + 0xbe9bee39, 0xe28a2f39, 0x97617035, 0xcb70b135, 0x2f42f235, + 0x73533335, 0x57257436, 0x0b34b536, 0xef06f636, 0xb3173736, + 0xa7ea7830, 0xfbfbb930, 0x1fc9fa30, 0x43d83b30, 0x67ae7c33, + 0x3bbfbd33, 0xdf8dfe33, 0x839c3f33, 0x68b68056, 0x34a74156, + 0xd0950256, 0x8c84c356, 0xa8f28455, 0xf4e34555, 0x10d10655, + 0x4cc0c755, 0x583d8853, 0x042c4953, 0xe01e0a53, 0xbc0fcb53, + 0x98798c50, 0xc4684d50, 0x205a0e50, 0x7c4bcf50, 0x09a0905c, + 0x55b1515c, 0xb183125c, 0xed92d35c, 0xc9e4945f, 0x95f5555f, + 0x71c7165f, 0x2dd6d75f, 0x392b9859, 0x653a5959, 0x81081a59, + 0xdd19db59, 0xf96f9c5a, 0xa57e5d5a, 0x414c1e5a, 0x1d5ddf5a, + 0xaa9aa042, 0xf68b6142, 0x12b92242, 0x4ea8e342, 0x6adea441, + 0x36cf6541, 0xd2fd2641, 0x8eece741, 0x9a11a847, 0xc6006947, + 0x22322a47, 0x7e23eb47, 0x5a55ac44, 0x06446d44, 0xe2762e44, + 0xbe67ef44, 0xcb8cb048, 0x979d7148, 0x73af3248, 0x2fbef348, + 0x0bc8b44b, 0x57d9754b, 0xb3eb364b, 0xeffaf74b, 0xfb07b84d, + 0xa716794d, 0x43243a4d, 0x1f35fb4d, 0x3b43bc4e, 0x67527d4e, + 0x83603e4e, 0xdf71ff4e, 0x5cedc07d, 0x00fc017d, 0xe4ce427d, + 0xb8df837d, 0x9ca9c47e, 0xc0b8057e, 0x248a467e, 0x789b877e, + 0x6c66c878, 0x30770978, 0xd4454a78, 0x88548b78, 0xac22cc7b, + 0xf0330d7b, 0x14014e7b, 0x48108f7b, 0x3dfbd077, 0x61ea1177, + 0x85d85277, 0xd9c99377, 0xfdbfd474, 0xa1ae1574, 0x459c5674, + 0x198d9774, 0x0d70d872, 0x51611972, 0xb5535a72, 0xe9429b72, + 0xcd34dc71, 0x91251d71, 0x75175e71, 0x29069f71, 0x9ec1e069, + 0xc2d02169, 0x26e26269, 0x7af3a369, 0x5e85e46a, 0x0294256a, + 0xe6a6666a, 0xbab7a76a, 0xae4ae86c, 0xf25b296c, 0x16696a6c, + 0x4a78ab6c, 0x6e0eec6f, 0x321f2d6f, 0xd62d6e6f, 0x8a3caf6f, + 0xffd7f063, 0xa3c63163, 0x47f47263, 0x1be5b363, 0x3f93f460, + 0x63823560, 0x87b07660, 0xdba1b760, 0xcf5cf866, 0x934d3966, + 0x777f7a66, 0x2b6ebb66, 0x0f18fc65, 0x53093d65, 0xb73b7e65, + 0xeb2abf65}, + {0x00000000, 0xd16d00ac, 0x12d9015b, 0xc3b401f7, 0x25b202b6, + 0xf4df021a, 0x376b03ed, 0xe6060341, 0x4b64056c, 0x9a0905c0, + 0x59bd0437, 0x88d0049b, 0x6ed607da, 0xbfbb0776, 0x7c0f0681, + 0xad62062d, 0x96c80ad8, 0x47a50a74, 0x84110b83, 0x557c0b2f, + 0xb37a086e, 0x621708c2, 0xa1a30935, 0x70ce0999, 0xddac0fb4, + 0x0cc10f18, 0xcf750eef, 0x1e180e43, 0xf81e0d02, 0x29730dae, + 0xeac70c59, 0x3baa0cf5, 0x9d9315b3, 0x4cfe151f, 0x8f4a14e8, + 0x5e271444, 0xb8211705, 0x694c17a9, 0xaaf8165e, 0x7b9516f2, + 0xd6f710df, 0x079a1073, 0xc42e1184, 0x15431128, 0xf3451269, + 0x222812c5, 0xe19c1332, 0x30f1139e, 0x0b5b1f6b, 0xda361fc7, + 0x19821e30, 0xc8ef1e9c, 0x2ee91ddd, 0xff841d71, 0x3c301c86, + 0xed5d1c2a, 0x403f1a07, 0x91521aab, 0x52e61b5c, 0x838b1bf0, + 0x658d18b1, 0xb4e0181d, 0x775419ea, 0xa6391946, 0x8b252b65, + 0x5a482bc9, 0x99fc2a3e, 0x48912a92, 0xae9729d3, 0x7ffa297f, + 0xbc4e2888, 0x6d232824, 0xc0412e09, 0x112c2ea5, 0xd2982f52, + 0x03f52ffe, 0xe5f32cbf, 0x349e2c13, 0xf72a2de4, 0x26472d48, + 0x1ded21bd, 0xcc802111, 0x0f3420e6, 0xde59204a, 0x385f230b, + 0xe93223a7, 0x2a862250, 0xfbeb22fc, 0x568924d1, 0x87e4247d, + 0x4450258a, 0x953d2526, 0x733b2667, 0xa25626cb, 0x61e2273c, + 0xb08f2790, 0x16b63ed6, 0xc7db3e7a, 0x046f3f8d, 0xd5023f21, + 0x33043c60, 0xe2693ccc, 0x21dd3d3b, 0xf0b03d97, 0x5dd23bba, + 0x8cbf3b16, 0x4f0b3ae1, 0x9e663a4d, 0x7860390c, 0xa90d39a0, + 0x6ab93857, 0xbbd438fb, 0x807e340e, 0x511334a2, 0x92a73555, + 0x43ca35f9, 0xa5cc36b8, 0x74a13614, 0xb71537e3, 0x6678374f, + 0xcb1a3162, 0x1a7731ce, 0xd9c33039, 0x08ae3095, 0xeea833d4, + 0x3fc53378, 0xfc71328f, 0x2d1c3223, 0xa64956c9, 0x77245665, + 0xb4905792, 0x65fd573e, 0x83fb547f, 0x529654d3, 0x91225524, + 0x404f5588, 0xed2d53a5, 0x3c405309, 0xfff452fe, 0x2e995252, + 0xc89f5113, 0x19f251bf, 0xda465048, 0x0b2b50e4, 0x30815c11, + 0xe1ec5cbd, 0x22585d4a, 0xf3355de6, 0x15335ea7, 0xc45e5e0b, + 0x07ea5ffc, 0xd6875f50, 0x7be5597d, 0xaa8859d1, 0x693c5826, + 0xb851588a, 0x5e575bcb, 0x8f3a5b67, 0x4c8e5a90, 0x9de35a3c, + 0x3bda437a, 0xeab743d6, 0x29034221, 0xf86e428d, 0x1e6841cc, + 0xcf054160, 0x0cb14097, 0xdddc403b, 0x70be4616, 0xa1d346ba, + 0x6267474d, 0xb30a47e1, 0x550c44a0, 0x8461440c, 0x47d545fb, + 0x96b84557, 0xad1249a2, 0x7c7f490e, 0xbfcb48f9, 0x6ea64855, + 0x88a04b14, 0x59cd4bb8, 0x9a794a4f, 0x4b144ae3, 0xe6764cce, + 0x371b4c62, 0xf4af4d95, 0x25c24d39, 0xc3c44e78, 0x12a94ed4, + 0xd11d4f23, 0x00704f8f, 0x2d6c7dac, 0xfc017d00, 0x3fb57cf7, + 0xeed87c5b, 0x08de7f1a, 0xd9b37fb6, 0x1a077e41, 0xcb6a7eed, + 0x660878c0, 0xb765786c, 0x74d1799b, 0xa5bc7937, 0x43ba7a76, + 0x92d77ada, 0x51637b2d, 0x800e7b81, 0xbba47774, 0x6ac977d8, + 0xa97d762f, 0x78107683, 0x9e1675c2, 0x4f7b756e, 0x8ccf7499, + 0x5da27435, 0xf0c07218, 0x21ad72b4, 0xe2197343, 0x337473ef, + 0xd57270ae, 0x041f7002, 0xc7ab71f5, 0x16c67159, 0xb0ff681f, + 0x619268b3, 0xa2266944, 0x734b69e8, 0x954d6aa9, 0x44206a05, + 0x87946bf2, 0x56f96b5e, 0xfb9b6d73, 0x2af66ddf, 0xe9426c28, + 0x382f6c84, 0xde296fc5, 0x0f446f69, 0xccf06e9e, 0x1d9d6e32, + 0x263762c7, 0xf75a626b, 0x34ee639c, 0xe5836330, 0x03856071, + 0xd2e860dd, 0x115c612a, 0xc0316186, 0x6d5367ab, 0xbc3e6707, + 0x7f8a66f0, 0xaee7665c, 0x48e1651d, 0x998c65b1, 0x5a386446, + 0x8b5564ea}, + {0x00000000, 0xfc91ad91, 0x49205b21, 0xb5b1f6b0, 0x9240b642, + 0x6ed11bd3, 0xdb60ed63, 0x27f140f2, 0x94826c87, 0x6813c116, + 0xdda237a6, 0x21339a37, 0x06c2dac5, 0xfa537754, 0x4fe281e4, + 0xb3732c75, 0x9907d90d, 0x6596749c, 0xd027822c, 0x2cb62fbd, + 0x0b476f4f, 0xf7d6c2de, 0x4267346e, 0xbef699ff, 0x0d85b58a, + 0xf114181b, 0x44a5eeab, 0xb834433a, 0x9fc503c8, 0x6354ae59, + 0xd6e558e9, 0x2a74f578, 0x820cb219, 0x7e9d1f88, 0xcb2ce938, + 0x37bd44a9, 0x104c045b, 0xecdda9ca, 0x596c5f7a, 0xa5fdf2eb, + 0x168ede9e, 0xea1f730f, 0x5fae85bf, 0xa33f282e, 0x84ce68dc, + 0x785fc54d, 0xcdee33fd, 0x317f9e6c, 0x1b0b6b14, 0xe79ac685, + 0x522b3035, 0xaeba9da4, 0x894bdd56, 0x75da70c7, 0xc06b8677, + 0x3cfa2be6, 0x8f890793, 0x7318aa02, 0xc6a95cb2, 0x3a38f123, + 0x1dc9b1d1, 0xe1581c40, 0x54e9eaf0, 0xa8784761, 0xb41a6431, + 0x488bc9a0, 0xfd3a3f10, 0x01ab9281, 0x265ad273, 0xdacb7fe2, + 0x6f7a8952, 0x93eb24c3, 0x209808b6, 0xdc09a527, 0x69b85397, + 0x9529fe06, 0xb2d8bef4, 0x4e491365, 0xfbf8e5d5, 0x07694844, + 0x2d1dbd3c, 0xd18c10ad, 0x643de61d, 0x98ac4b8c, 0xbf5d0b7e, + 0x43cca6ef, 0xf67d505f, 0x0aecfdce, 0xb99fd1bb, 0x450e7c2a, + 0xf0bf8a9a, 0x0c2e270b, 0x2bdf67f9, 0xd74eca68, 0x62ff3cd8, + 0x9e6e9149, 0x3616d628, 0xca877bb9, 0x7f368d09, 0x83a72098, + 0xa456606a, 0x58c7cdfb, 0xed763b4b, 0x11e796da, 0xa294baaf, + 0x5e05173e, 0xebb4e18e, 0x17254c1f, 0x30d40ced, 0xcc45a17c, + 0x79f457cc, 0x8565fa5d, 0xaf110f25, 0x5380a2b4, 0xe6315404, + 0x1aa0f995, 0x3d51b967, 0xc1c014f6, 0x7471e246, 0x88e04fd7, + 0x3b9363a2, 0xc702ce33, 0x72b33883, 0x8e229512, 0xa9d3d5e0, + 0x55427871, 0xe0f38ec1, 0x1c622350, 0xd837c861, 0x24a665f0, + 0x91179340, 0x6d863ed1, 0x4a777e23, 0xb6e6d3b2, 0x03572502, + 0xffc68893, 0x4cb5a4e6, 0xb0240977, 0x0595ffc7, 0xf9045256, + 0xdef512a4, 0x2264bf35, 0x97d54985, 0x6b44e414, 0x4130116c, + 0xbda1bcfd, 0x08104a4d, 0xf481e7dc, 0xd370a72e, 0x2fe10abf, + 0x9a50fc0f, 0x66c1519e, 0xd5b27deb, 0x2923d07a, 0x9c9226ca, + 0x60038b5b, 0x47f2cba9, 0xbb636638, 0x0ed29088, 0xf2433d19, + 0x5a3b7a78, 0xa6aad7e9, 0x131b2159, 0xef8a8cc8, 0xc87bcc3a, + 0x34ea61ab, 0x815b971b, 0x7dca3a8a, 0xceb916ff, 0x3228bb6e, + 0x87994dde, 0x7b08e04f, 0x5cf9a0bd, 0xa0680d2c, 0x15d9fb9c, + 0xe948560d, 0xc33ca375, 0x3fad0ee4, 0x8a1cf854, 0x768d55c5, + 0x517c1537, 0xadedb8a6, 0x185c4e16, 0xe4cde387, 0x57becff2, + 0xab2f6263, 0x1e9e94d3, 0xe20f3942, 0xc5fe79b0, 0x396fd421, + 0x8cde2291, 0x704f8f00, 0x6c2dac50, 0x90bc01c1, 0x250df771, + 0xd99c5ae0, 0xfe6d1a12, 0x02fcb783, 0xb74d4133, 0x4bdceca2, + 0xf8afc0d7, 0x043e6d46, 0xb18f9bf6, 0x4d1e3667, 0x6aef7695, + 0x967edb04, 0x23cf2db4, 0xdf5e8025, 0xf52a755d, 0x09bbd8cc, + 0xbc0a2e7c, 0x409b83ed, 0x676ac31f, 0x9bfb6e8e, 0x2e4a983e, + 0xd2db35af, 0x61a819da, 0x9d39b44b, 0x288842fb, 0xd419ef6a, + 0xf3e8af98, 0x0f790209, 0xbac8f4b9, 0x46595928, 0xee211e49, + 0x12b0b3d8, 0xa7014568, 0x5b90e8f9, 0x7c61a80b, 0x80f0059a, + 0x3541f32a, 0xc9d05ebb, 0x7aa372ce, 0x8632df5f, 0x338329ef, + 0xcf12847e, 0xe8e3c48c, 0x1472691d, 0xa1c39fad, 0x5d52323c, + 0x7726c744, 0x8bb76ad5, 0x3e069c65, 0xc29731f4, 0xe5667106, + 0x19f7dc97, 0xac462a27, 0x50d787b6, 0xe3a4abc3, 0x1f350652, + 0xaa84f0e2, 0x56155d73, 0x71e41d81, 0x8d75b010, 0x38c446a0, + 0xc455eb31}, + {0x00000000, 0x006c90c1, 0x00d92182, 0x00b5b143, 0x01b24304, + 0x01ded3c5, 0x016b6286, 0x0107f247, 0x03648608, 0x030816c9, + 0x03bda78a, 0x03d1374b, 0x02d6c50c, 0x02ba55cd, 0x020fe48e, + 0x0263744f, 0x06c90c10, 0x06a59cd1, 0x06102d92, 0x067cbd53, + 0x077b4f14, 0x0717dfd5, 0x07a26e96, 0x07cefe57, 0x05ad8a18, + 0x05c11ad9, 0x0574ab9a, 0x05183b5b, 0x041fc91c, 0x047359dd, + 0x04c6e89e, 0x04aa785f, 0x0d921820, 0x0dfe88e1, 0x0d4b39a2, + 0x0d27a963, 0x0c205b24, 0x0c4ccbe5, 0x0cf97aa6, 0x0c95ea67, + 0x0ef69e28, 0x0e9a0ee9, 0x0e2fbfaa, 0x0e432f6b, 0x0f44dd2c, + 0x0f284ded, 0x0f9dfcae, 0x0ff16c6f, 0x0b5b1430, 0x0b3784f1, + 0x0b8235b2, 0x0beea573, 0x0ae95734, 0x0a85c7f5, 0x0a3076b6, + 0x0a5ce677, 0x083f9238, 0x085302f9, 0x08e6b3ba, 0x088a237b, + 0x098dd13c, 0x09e141fd, 0x0954f0be, 0x0938607f, 0x1b243040, + 0x1b48a081, 0x1bfd11c2, 0x1b918103, 0x1a967344, 0x1afae385, + 0x1a4f52c6, 0x1a23c207, 0x1840b648, 0x182c2689, 0x189997ca, + 0x18f5070b, 0x19f2f54c, 0x199e658d, 0x192bd4ce, 0x1947440f, + 0x1ded3c50, 0x1d81ac91, 0x1d341dd2, 0x1d588d13, 0x1c5f7f54, + 0x1c33ef95, 0x1c865ed6, 0x1ceace17, 0x1e89ba58, 0x1ee52a99, + 0x1e509bda, 0x1e3c0b1b, 0x1f3bf95c, 0x1f57699d, 0x1fe2d8de, + 0x1f8e481f, 0x16b62860, 0x16dab8a1, 0x166f09e2, 0x16039923, + 0x17046b64, 0x1768fba5, 0x17dd4ae6, 0x17b1da27, 0x15d2ae68, + 0x15be3ea9, 0x150b8fea, 0x15671f2b, 0x1460ed6c, 0x140c7dad, + 0x14b9ccee, 0x14d55c2f, 0x107f2470, 0x1013b4b1, 0x10a605f2, + 0x10ca9533, 0x11cd6774, 0x11a1f7b5, 0x111446f6, 0x1178d637, + 0x131ba278, 0x137732b9, 0x13c283fa, 0x13ae133b, 0x12a9e17c, + 0x12c571bd, 0x1270c0fe, 0x121c503f, 0x36486080, 0x3624f041, + 0x36914102, 0x36fdd1c3, 0x37fa2384, 0x3796b345, 0x37230206, + 0x374f92c7, 0x352ce688, 0x35407649, 0x35f5c70a, 0x359957cb, + 0x349ea58c, 0x34f2354d, 0x3447840e, 0x342b14cf, 0x30816c90, + 0x30edfc51, 0x30584d12, 0x3034ddd3, 0x31332f94, 0x315fbf55, + 0x31ea0e16, 0x31869ed7, 0x33e5ea98, 0x33897a59, 0x333ccb1a, + 0x33505bdb, 0x3257a99c, 0x323b395d, 0x328e881e, 0x32e218df, + 0x3bda78a0, 0x3bb6e861, 0x3b035922, 0x3b6fc9e3, 0x3a683ba4, + 0x3a04ab65, 0x3ab11a26, 0x3add8ae7, 0x38befea8, 0x38d26e69, + 0x3867df2a, 0x380b4feb, 0x390cbdac, 0x39602d6d, 0x39d59c2e, + 0x39b90cef, 0x3d1374b0, 0x3d7fe471, 0x3dca5532, 0x3da6c5f3, + 0x3ca137b4, 0x3ccda775, 0x3c781636, 0x3c1486f7, 0x3e77f2b8, + 0x3e1b6279, 0x3eaed33a, 0x3ec243fb, 0x3fc5b1bc, 0x3fa9217d, + 0x3f1c903e, 0x3f7000ff, 0x2d6c50c0, 0x2d00c001, 0x2db57142, + 0x2dd9e183, 0x2cde13c4, 0x2cb28305, 0x2c073246, 0x2c6ba287, + 0x2e08d6c8, 0x2e644609, 0x2ed1f74a, 0x2ebd678b, 0x2fba95cc, + 0x2fd6050d, 0x2f63b44e, 0x2f0f248f, 0x2ba55cd0, 0x2bc9cc11, + 0x2b7c7d52, 0x2b10ed93, 0x2a171fd4, 0x2a7b8f15, 0x2ace3e56, + 0x2aa2ae97, 0x28c1dad8, 0x28ad4a19, 0x2818fb5a, 0x28746b9b, + 0x297399dc, 0x291f091d, 0x29aab85e, 0x29c6289f, 0x20fe48e0, + 0x2092d821, 0x20276962, 0x204bf9a3, 0x214c0be4, 0x21209b25, + 0x21952a66, 0x21f9baa7, 0x239acee8, 0x23f65e29, 0x2343ef6a, + 0x232f7fab, 0x22288dec, 0x22441d2d, 0x22f1ac6e, 0x229d3caf, + 0x263744f0, 0x265bd431, 0x26ee6572, 0x2682f5b3, 0x278507f4, + 0x27e99735, 0x275c2676, 0x2730b6b7, 0x2553c2f8, 0x253f5239, + 0x258ae37a, 0x25e673bb, 0x24e181fc, 0x248d113d, 0x2438a07e, + 0x245430bf}}; + +static const word_t crc_braid_big_table[][256] = { + {0x00000000, 0xc1906c00, 0x8221d900, 0x43b1b500, 0x0443b201, + 0xc5d3de01, 0x86626b01, 0x47f20701, 0x08866403, 0xc9160803, + 0x8aa7bd03, 0x4b37d103, 0x0cc5d602, 0xcd55ba02, 0x8ee40f02, + 0x4f746302, 0x100cc906, 0xd19ca506, 0x922d1006, 0x53bd7c06, + 0x144f7b07, 0xd5df1707, 0x966ea207, 0x57fece07, 0x188aad05, + 0xd91ac105, 0x9aab7405, 0x5b3b1805, 0x1cc91f04, 0xdd597304, + 0x9ee8c604, 0x5f78aa04, 0x2018920d, 0xe188fe0d, 0xa2394b0d, + 0x63a9270d, 0x245b200c, 0xe5cb4c0c, 0xa67af90c, 0x67ea950c, + 0x289ef60e, 0xe90e9a0e, 0xaabf2f0e, 0x6b2f430e, 0x2cdd440f, + 0xed4d280f, 0xaefc9d0f, 0x6f6cf10f, 0x30145b0b, 0xf184370b, + 0xb235820b, 0x73a5ee0b, 0x3457e90a, 0xf5c7850a, 0xb676300a, + 0x77e65c0a, 0x38923f08, 0xf9025308, 0xbab3e608, 0x7b238a08, + 0x3cd18d09, 0xfd41e109, 0xbef05409, 0x7f603809, 0x4030241b, + 0x81a0481b, 0xc211fd1b, 0x0381911b, 0x4473961a, 0x85e3fa1a, + 0xc6524f1a, 0x07c2231a, 0x48b64018, 0x89262c18, 0xca979918, + 0x0b07f518, 0x4cf5f219, 0x8d659e19, 0xced42b19, 0x0f444719, + 0x503ced1d, 0x91ac811d, 0xd21d341d, 0x138d581d, 0x547f5f1c, + 0x95ef331c, 0xd65e861c, 0x17ceea1c, 0x58ba891e, 0x992ae51e, + 0xda9b501e, 0x1b0b3c1e, 0x5cf93b1f, 0x9d69571f, 0xded8e21f, + 0x1f488e1f, 0x6028b616, 0xa1b8da16, 0xe2096f16, 0x23990316, + 0x646b0417, 0xa5fb6817, 0xe64add17, 0x27dab117, 0x68aed215, + 0xa93ebe15, 0xea8f0b15, 0x2b1f6715, 0x6ced6014, 0xad7d0c14, + 0xeeccb914, 0x2f5cd514, 0x70247f10, 0xb1b41310, 0xf205a610, + 0x3395ca10, 0x7467cd11, 0xb5f7a111, 0xf6461411, 0x37d67811, + 0x78a21b13, 0xb9327713, 0xfa83c213, 0x3b13ae13, 0x7ce1a912, + 0xbd71c512, 0xfec07012, 0x3f501c12, 0x80604836, 0x41f02436, + 0x02419136, 0xc3d1fd36, 0x8423fa37, 0x45b39637, 0x06022337, + 0xc7924f37, 0x88e62c35, 0x49764035, 0x0ac7f535, 0xcb579935, + 0x8ca59e34, 0x4d35f234, 0x0e844734, 0xcf142b34, 0x906c8130, + 0x51fced30, 0x124d5830, 0xd3dd3430, 0x942f3331, 0x55bf5f31, + 0x160eea31, 0xd79e8631, 0x98eae533, 0x597a8933, 0x1acb3c33, + 0xdb5b5033, 0x9ca95732, 0x5d393b32, 0x1e888e32, 0xdf18e232, + 0xa078da3b, 0x61e8b63b, 0x2259033b, 0xe3c96f3b, 0xa43b683a, + 0x65ab043a, 0x261ab13a, 0xe78add3a, 0xa8febe38, 0x696ed238, + 0x2adf6738, 0xeb4f0b38, 0xacbd0c39, 0x6d2d6039, 0x2e9cd539, + 0xef0cb939, 0xb074133d, 0x71e47f3d, 0x3255ca3d, 0xf3c5a63d, + 0xb437a13c, 0x75a7cd3c, 0x3616783c, 0xf786143c, 0xb8f2773e, + 0x79621b3e, 0x3ad3ae3e, 0xfb43c23e, 0xbcb1c53f, 0x7d21a93f, + 0x3e901c3f, 0xff00703f, 0xc0506c2d, 0x01c0002d, 0x4271b52d, + 0x83e1d92d, 0xc413de2c, 0x0583b22c, 0x4632072c, 0x87a26b2c, + 0xc8d6082e, 0x0946642e, 0x4af7d12e, 0x8b67bd2e, 0xcc95ba2f, + 0x0d05d62f, 0x4eb4632f, 0x8f240f2f, 0xd05ca52b, 0x11ccc92b, + 0x527d7c2b, 0x93ed102b, 0xd41f172a, 0x158f7b2a, 0x563ece2a, + 0x97aea22a, 0xd8dac128, 0x194aad28, 0x5afb1828, 0x9b6b7428, + 0xdc997329, 0x1d091f29, 0x5eb8aa29, 0x9f28c629, 0xe048fe20, + 0x21d89220, 0x62692720, 0xa3f94b20, 0xe40b4c21, 0x259b2021, + 0x662a9521, 0xa7baf921, 0xe8ce9a23, 0x295ef623, 0x6aef4323, + 0xab7f2f23, 0xec8d2822, 0x2d1d4422, 0x6eacf122, 0xaf3c9d22, + 0xf0443726, 0x31d45b26, 0x7265ee26, 0xb3f58226, 0xf4078527, + 0x3597e927, 0x76265c27, 0xb7b63027, 0xf8c25325, 0x39523f25, + 0x7ae38a25, 0xbb73e625, 0xfc81e124, 0x3d118d24, 0x7ea03824, + 0xbf305424}, + {0x00000000, 0x91ad91fc, 0x215b2049, 0xb0f6b1b5, 0x42b64092, + 0xd31bd16e, 0x63ed60db, 0xf240f127, 0x876c8294, 0x16c11368, + 0xa637a2dd, 0x379a3321, 0xc5dac206, 0x547753fa, 0xe481e24f, + 0x752c73b3, 0x0dd90799, 0x9c749665, 0x2c8227d0, 0xbd2fb62c, + 0x4f6f470b, 0xdec2d6f7, 0x6e346742, 0xff99f6be, 0x8ab5850d, + 0x1b1814f1, 0xabeea544, 0x3a4334b8, 0xc803c59f, 0x59ae5463, + 0xe958e5d6, 0x78f5742a, 0x19b20c82, 0x881f9d7e, 0x38e92ccb, + 0xa944bd37, 0x5b044c10, 0xcaa9ddec, 0x7a5f6c59, 0xebf2fda5, + 0x9ede8e16, 0x0f731fea, 0xbf85ae5f, 0x2e283fa3, 0xdc68ce84, + 0x4dc55f78, 0xfd33eecd, 0x6c9e7f31, 0x146b0b1b, 0x85c69ae7, + 0x35302b52, 0xa49dbaae, 0x56dd4b89, 0xc770da75, 0x77866bc0, + 0xe62bfa3c, 0x9307898f, 0x02aa1873, 0xb25ca9c6, 0x23f1383a, + 0xd1b1c91d, 0x401c58e1, 0xf0eae954, 0x614778a8, 0x31641ab4, + 0xa0c98b48, 0x103f3afd, 0x8192ab01, 0x73d25a26, 0xe27fcbda, + 0x52897a6f, 0xc324eb93, 0xb6089820, 0x27a509dc, 0x9753b869, + 0x06fe2995, 0xf4bed8b2, 0x6513494e, 0xd5e5f8fb, 0x44486907, + 0x3cbd1d2d, 0xad108cd1, 0x1de63d64, 0x8c4bac98, 0x7e0b5dbf, + 0xefa6cc43, 0x5f507df6, 0xcefdec0a, 0xbbd19fb9, 0x2a7c0e45, + 0x9a8abff0, 0x0b272e0c, 0xf967df2b, 0x68ca4ed7, 0xd83cff62, + 0x49916e9e, 0x28d61636, 0xb97b87ca, 0x098d367f, 0x9820a783, + 0x6a6056a4, 0xfbcdc758, 0x4b3b76ed, 0xda96e711, 0xafba94a2, + 0x3e17055e, 0x8ee1b4eb, 0x1f4c2517, 0xed0cd430, 0x7ca145cc, + 0xcc57f479, 0x5dfa6585, 0x250f11af, 0xb4a28053, 0x045431e6, + 0x95f9a01a, 0x67b9513d, 0xf614c0c1, 0x46e27174, 0xd74fe088, + 0xa263933b, 0x33ce02c7, 0x8338b372, 0x1295228e, 0xe0d5d3a9, + 0x71784255, 0xc18ef3e0, 0x5023621c, 0x61c837d8, 0xf065a624, + 0x40931791, 0xd13e866d, 0x237e774a, 0xb2d3e6b6, 0x02255703, + 0x9388c6ff, 0xe6a4b54c, 0x770924b0, 0xc7ff9505, 0x565204f9, + 0xa412f5de, 0x35bf6422, 0x8549d597, 0x14e4446b, 0x6c113041, + 0xfdbca1bd, 0x4d4a1008, 0xdce781f4, 0x2ea770d3, 0xbf0ae12f, + 0x0ffc509a, 0x9e51c166, 0xeb7db2d5, 0x7ad02329, 0xca26929c, + 0x5b8b0360, 0xa9cbf247, 0x386663bb, 0x8890d20e, 0x193d43f2, + 0x787a3b5a, 0xe9d7aaa6, 0x59211b13, 0xc88c8aef, 0x3acc7bc8, + 0xab61ea34, 0x1b975b81, 0x8a3aca7d, 0xff16b9ce, 0x6ebb2832, + 0xde4d9987, 0x4fe0087b, 0xbda0f95c, 0x2c0d68a0, 0x9cfbd915, + 0x0d5648e9, 0x75a33cc3, 0xe40ead3f, 0x54f81c8a, 0xc5558d76, + 0x37157c51, 0xa6b8edad, 0x164e5c18, 0x87e3cde4, 0xf2cfbe57, + 0x63622fab, 0xd3949e1e, 0x42390fe2, 0xb079fec5, 0x21d46f39, + 0x9122de8c, 0x008f4f70, 0x50ac2d6c, 0xc101bc90, 0x71f70d25, + 0xe05a9cd9, 0x121a6dfe, 0x83b7fc02, 0x33414db7, 0xa2ecdc4b, + 0xd7c0aff8, 0x466d3e04, 0xf69b8fb1, 0x67361e4d, 0x9576ef6a, + 0x04db7e96, 0xb42dcf23, 0x25805edf, 0x5d752af5, 0xccd8bb09, + 0x7c2e0abc, 0xed839b40, 0x1fc36a67, 0x8e6efb9b, 0x3e984a2e, + 0xaf35dbd2, 0xda19a861, 0x4bb4399d, 0xfb428828, 0x6aef19d4, + 0x98afe8f3, 0x0902790f, 0xb9f4c8ba, 0x28595946, 0x491e21ee, + 0xd8b3b012, 0x684501a7, 0xf9e8905b, 0x0ba8617c, 0x9a05f080, + 0x2af34135, 0xbb5ed0c9, 0xce72a37a, 0x5fdf3286, 0xef298333, + 0x7e8412cf, 0x8cc4e3e8, 0x1d697214, 0xad9fc3a1, 0x3c32525d, + 0x44c72677, 0xd56ab78b, 0x659c063e, 0xf43197c2, 0x067166e5, + 0x97dcf719, 0x272a46ac, 0xb687d750, 0xc3aba4e3, 0x5206351f, + 0xe2f084aa, 0x735d1556, 0x811de471, 0x10b0758d, 0xa046c438, + 0x31eb55c4}, + {0x00000000, 0xac006dd1, 0x5b01d912, 0xf701b4c3, 0xb602b225, + 0x1a02dff4, 0xed036b37, 0x410306e6, 0x6c05644b, 0xc005099a, + 0x3704bd59, 0x9b04d088, 0xda07d66e, 0x7607bbbf, 0x81060f7c, + 0x2d0662ad, 0xd80ac896, 0x740aa547, 0x830b1184, 0x2f0b7c55, + 0x6e087ab3, 0xc2081762, 0x3509a3a1, 0x9909ce70, 0xb40facdd, + 0x180fc10c, 0xef0e75cf, 0x430e181e, 0x020d1ef8, 0xae0d7329, + 0x590cc7ea, 0xf50caa3b, 0xb315939d, 0x1f15fe4c, 0xe8144a8f, + 0x4414275e, 0x051721b8, 0xa9174c69, 0x5e16f8aa, 0xf216957b, + 0xdf10f7d6, 0x73109a07, 0x84112ec4, 0x28114315, 0x691245f3, + 0xc5122822, 0x32139ce1, 0x9e13f130, 0x6b1f5b0b, 0xc71f36da, + 0x301e8219, 0x9c1eefc8, 0xdd1de92e, 0x711d84ff, 0x861c303c, + 0x2a1c5ded, 0x071a3f40, 0xab1a5291, 0x5c1be652, 0xf01b8b83, + 0xb1188d65, 0x1d18e0b4, 0xea195477, 0x461939a6, 0x652b258b, + 0xc92b485a, 0x3e2afc99, 0x922a9148, 0xd32997ae, 0x7f29fa7f, + 0x88284ebc, 0x2428236d, 0x092e41c0, 0xa52e2c11, 0x522f98d2, + 0xfe2ff503, 0xbf2cf3e5, 0x132c9e34, 0xe42d2af7, 0x482d4726, + 0xbd21ed1d, 0x112180cc, 0xe620340f, 0x4a2059de, 0x0b235f38, + 0xa72332e9, 0x5022862a, 0xfc22ebfb, 0xd1248956, 0x7d24e487, + 0x8a255044, 0x26253d95, 0x67263b73, 0xcb2656a2, 0x3c27e261, + 0x90278fb0, 0xd63eb616, 0x7a3edbc7, 0x8d3f6f04, 0x213f02d5, + 0x603c0433, 0xcc3c69e2, 0x3b3ddd21, 0x973db0f0, 0xba3bd25d, + 0x163bbf8c, 0xe13a0b4f, 0x4d3a669e, 0x0c396078, 0xa0390da9, + 0x5738b96a, 0xfb38d4bb, 0x0e347e80, 0xa2341351, 0x5535a792, + 0xf935ca43, 0xb836cca5, 0x1436a174, 0xe33715b7, 0x4f377866, + 0x62311acb, 0xce31771a, 0x3930c3d9, 0x9530ae08, 0xd433a8ee, + 0x7833c53f, 0x8f3271fc, 0x23321c2d, 0xc95649a6, 0x65562477, + 0x925790b4, 0x3e57fd65, 0x7f54fb83, 0xd3549652, 0x24552291, + 0x88554f40, 0xa5532ded, 0x0953403c, 0xfe52f4ff, 0x5252992e, + 0x13519fc8, 0xbf51f219, 0x485046da, 0xe4502b0b, 0x115c8130, + 0xbd5cece1, 0x4a5d5822, 0xe65d35f3, 0xa75e3315, 0x0b5e5ec4, + 0xfc5fea07, 0x505f87d6, 0x7d59e57b, 0xd15988aa, 0x26583c69, + 0x8a5851b8, 0xcb5b575e, 0x675b3a8f, 0x905a8e4c, 0x3c5ae39d, + 0x7a43da3b, 0xd643b7ea, 0x21420329, 0x8d426ef8, 0xcc41681e, + 0x604105cf, 0x9740b10c, 0x3b40dcdd, 0x1646be70, 0xba46d3a1, + 0x4d476762, 0xe1470ab3, 0xa0440c55, 0x0c446184, 0xfb45d547, + 0x5745b896, 0xa24912ad, 0x0e497f7c, 0xf948cbbf, 0x5548a66e, + 0x144ba088, 0xb84bcd59, 0x4f4a799a, 0xe34a144b, 0xce4c76e6, + 0x624c1b37, 0x954daff4, 0x394dc225, 0x784ec4c3, 0xd44ea912, + 0x234f1dd1, 0x8f4f7000, 0xac7d6c2d, 0x007d01fc, 0xf77cb53f, + 0x5b7cd8ee, 0x1a7fde08, 0xb67fb3d9, 0x417e071a, 0xed7e6acb, + 0xc0780866, 0x6c7865b7, 0x9b79d174, 0x3779bca5, 0x767aba43, + 0xda7ad792, 0x2d7b6351, 0x817b0e80, 0x7477a4bb, 0xd877c96a, + 0x2f767da9, 0x83761078, 0xc275169e, 0x6e757b4f, 0x9974cf8c, + 0x3574a25d, 0x1872c0f0, 0xb472ad21, 0x437319e2, 0xef737433, + 0xae7072d5, 0x02701f04, 0xf571abc7, 0x5971c616, 0x1f68ffb0, + 0xb3689261, 0x446926a2, 0xe8694b73, 0xa96a4d95, 0x056a2044, + 0xf26b9487, 0x5e6bf956, 0x736d9bfb, 0xdf6df62a, 0x286c42e9, + 0x846c2f38, 0xc56f29de, 0x696f440f, 0x9e6ef0cc, 0x326e9d1d, + 0xc7623726, 0x6b625af7, 0x9c63ee34, 0x306383e5, 0x71608503, + 0xdd60e8d2, 0x2a615c11, 0x866131c0, 0xab67536d, 0x07673ebc, + 0xf0668a7f, 0x5c66e7ae, 0x1d65e148, 0xb1658c99, 0x4664385a, + 0xea64558b}, + {0x00000000, 0x00c1115c, 0x008223b8, 0x004332e4, 0x030444c0, + 0x03c5559c, 0x03866778, 0x03477624, 0x05088b30, 0x05c99a6c, + 0x058aa888, 0x054bb9d4, 0x060ccff0, 0x06cddeac, 0x068eec48, + 0x064ffd14, 0x0a101661, 0x0ad1073d, 0x0a9235d9, 0x0a532485, + 0x091452a1, 0x09d543fd, 0x09967119, 0x09576045, 0x0f189d51, + 0x0fd98c0d, 0x0f9abee9, 0x0f5bafb5, 0x0c1cd991, 0x0cddc8cd, + 0x0c9efa29, 0x0c5feb75, 0x14202cc2, 0x14e13d9e, 0x14a20f7a, + 0x14631e26, 0x17246802, 0x17e5795e, 0x17a64bba, 0x17675ae6, + 0x1128a7f2, 0x11e9b6ae, 0x11aa844a, 0x116b9516, 0x122ce332, + 0x12edf26e, 0x12aec08a, 0x126fd1d6, 0x1e303aa3, 0x1ef12bff, + 0x1eb2191b, 0x1e730847, 0x1d347e63, 0x1df56f3f, 0x1db65ddb, + 0x1d774c87, 0x1b38b193, 0x1bf9a0cf, 0x1bba922b, 0x1b7b8377, + 0x183cf553, 0x18fde40f, 0x18bed6eb, 0x187fc7b7, 0x2b405b34, + 0x2b814a68, 0x2bc2788c, 0x2b0369d0, 0x28441ff4, 0x28850ea8, + 0x28c63c4c, 0x28072d10, 0x2e48d004, 0x2e89c158, 0x2ecaf3bc, + 0x2e0be2e0, 0x2d4c94c4, 0x2d8d8598, 0x2dceb77c, 0x2d0fa620, + 0x21504d55, 0x21915c09, 0x21d26eed, 0x21137fb1, 0x22540995, + 0x229518c9, 0x22d62a2d, 0x22173b71, 0x2458c665, 0x2499d739, + 0x24dae5dd, 0x241bf481, 0x275c82a5, 0x279d93f9, 0x27dea11d, + 0x271fb041, 0x3f6077f6, 0x3fa166aa, 0x3fe2544e, 0x3f234512, + 0x3c643336, 0x3ca5226a, 0x3ce6108e, 0x3c2701d2, 0x3a68fcc6, + 0x3aa9ed9a, 0x3aeadf7e, 0x3a2bce22, 0x396cb806, 0x39ada95a, + 0x39ee9bbe, 0x392f8ae2, 0x35706197, 0x35b170cb, 0x35f2422f, + 0x35335373, 0x36742557, 0x36b5340b, 0x36f606ef, 0x363717b3, + 0x3078eaa7, 0x30b9fbfb, 0x30fac91f, 0x303bd843, 0x337cae67, + 0x33bdbf3b, 0x33fe8ddf, 0x333f9c83, 0x5680b668, 0x5641a734, + 0x560295d0, 0x56c3848c, 0x5584f2a8, 0x5545e3f4, 0x5506d110, + 0x55c7c04c, 0x53883d58, 0x53492c04, 0x530a1ee0, 0x53cb0fbc, + 0x508c7998, 0x504d68c4, 0x500e5a20, 0x50cf4b7c, 0x5c90a009, + 0x5c51b155, 0x5c1283b1, 0x5cd392ed, 0x5f94e4c9, 0x5f55f595, + 0x5f16c771, 0x5fd7d62d, 0x59982b39, 0x59593a65, 0x591a0881, + 0x59db19dd, 0x5a9c6ff9, 0x5a5d7ea5, 0x5a1e4c41, 0x5adf5d1d, + 0x42a09aaa, 0x42618bf6, 0x4222b912, 0x42e3a84e, 0x41a4de6a, + 0x4165cf36, 0x4126fdd2, 0x41e7ec8e, 0x47a8119a, 0x476900c6, + 0x472a3222, 0x47eb237e, 0x44ac555a, 0x446d4406, 0x442e76e2, + 0x44ef67be, 0x48b08ccb, 0x48719d97, 0x4832af73, 0x48f3be2f, + 0x4bb4c80b, 0x4b75d957, 0x4b36ebb3, 0x4bf7faef, 0x4db807fb, + 0x4d7916a7, 0x4d3a2443, 0x4dfb351f, 0x4ebc433b, 0x4e7d5267, + 0x4e3e6083, 0x4eff71df, 0x7dc0ed5c, 0x7d01fc00, 0x7d42cee4, + 0x7d83dfb8, 0x7ec4a99c, 0x7e05b8c0, 0x7e468a24, 0x7e879b78, + 0x78c8666c, 0x78097730, 0x784a45d4, 0x788b5488, 0x7bcc22ac, + 0x7b0d33f0, 0x7b4e0114, 0x7b8f1048, 0x77d0fb3d, 0x7711ea61, + 0x7752d885, 0x7793c9d9, 0x74d4bffd, 0x7415aea1, 0x74569c45, + 0x74978d19, 0x72d8700d, 0x72196151, 0x725a53b5, 0x729b42e9, + 0x71dc34cd, 0x711d2591, 0x715e1775, 0x719f0629, 0x69e0c19e, + 0x6921d0c2, 0x6962e226, 0x69a3f37a, 0x6ae4855e, 0x6a259402, + 0x6a66a6e6, 0x6aa7b7ba, 0x6ce84aae, 0x6c295bf2, 0x6c6a6916, + 0x6cab784a, 0x6fec0e6e, 0x6f2d1f32, 0x6f6e2dd6, 0x6faf3c8a, + 0x63f0d7ff, 0x6331c6a3, 0x6372f447, 0x63b3e51b, 0x60f4933f, + 0x60358263, 0x6076b087, 0x60b7a1db, 0x66f85ccf, 0x66394d93, + 0x667a7f77, 0x66bb6e2b, 0x65fc180f, 0x653d0953, 0x657e3bb7, + 0x65bf2aeb}}; + +#endif + +#endif + +#if N == 6 + +#if W == 8 + +static const crc_t crc_braid_table[][256] = { + {0x00000000, 0xe17c91c1, 0x72fa2381, 0x9386b240, 0xe5f44702, + 0x0488d6c3, 0x970e6483, 0x7672f542, 0x7beb8e07, 0x9a971fc6, + 0x0911ad86, 0xe86d3c47, 0x9e1fc905, 0x7f6358c4, 0xece5ea84, + 0x0d997b45, 0xf7d71c0e, 0x16ab8dcf, 0x852d3f8f, 0x6451ae4e, + 0x12235b0c, 0xf35fcacd, 0x60d9788d, 0x81a5e94c, 0x8c3c9209, + 0x6d4003c8, 0xfec6b188, 0x1fba2049, 0x69c8d50b, 0x88b444ca, + 0x1b32f68a, 0xfa4e674b, 0x5fad381f, 0xbed1a9de, 0x2d571b9e, + 0xcc2b8a5f, 0xba597f1d, 0x5b25eedc, 0xc8a35c9c, 0x29dfcd5d, + 0x2446b618, 0xc53a27d9, 0x56bc9599, 0xb7c00458, 0xc1b2f11a, + 0x20ce60db, 0xb348d29b, 0x5234435a, 0xa87a2411, 0x4906b5d0, + 0xda800790, 0x3bfc9651, 0x4d8e6313, 0xacf2f2d2, 0x3f744092, + 0xde08d153, 0xd391aa16, 0x32ed3bd7, 0xa16b8997, 0x40171856, + 0x3665ed14, 0xd7197cd5, 0x449fce95, 0xa5e35f54, 0xbf5a703e, + 0x5e26e1ff, 0xcda053bf, 0x2cdcc27e, 0x5aae373c, 0xbbd2a6fd, + 0x285414bd, 0xc928857c, 0xc4b1fe39, 0x25cd6ff8, 0xb64bddb8, + 0x57374c79, 0x2145b93b, 0xc03928fa, 0x53bf9aba, 0xb2c30b7b, + 0x488d6c30, 0xa9f1fdf1, 0x3a774fb1, 0xdb0bde70, 0xad792b32, + 0x4c05baf3, 0xdf8308b3, 0x3eff9972, 0x3366e237, 0xd21a73f6, + 0x419cc1b6, 0xa0e05077, 0xd692a535, 0x37ee34f4, 0xa46886b4, + 0x45141775, 0xe0f74821, 0x018bd9e0, 0x920d6ba0, 0x7371fa61, + 0x05030f23, 0xe47f9ee2, 0x77f92ca2, 0x9685bd63, 0x9b1cc626, + 0x7a6057e7, 0xe9e6e5a7, 0x089a7466, 0x7ee88124, 0x9f9410e5, + 0x0c12a2a5, 0xed6e3364, 0x1720542f, 0xf65cc5ee, 0x65da77ae, + 0x84a6e66f, 0xf2d4132d, 0x13a882ec, 0x802e30ac, 0x6152a16d, + 0x6ccbda28, 0x8db74be9, 0x1e31f9a9, 0xff4d6868, 0x893f9d2a, + 0x68430ceb, 0xfbc5beab, 0x1ab92f6a, 0xceb7e07f, 0x2fcb71be, + 0xbc4dc3fe, 0x5d31523f, 0x2b43a77d, 0xca3f36bc, 0x59b984fc, + 0xb8c5153d, 0xb55c6e78, 0x5420ffb9, 0xc7a64df9, 0x26dadc38, + 0x50a8297a, 0xb1d4b8bb, 0x22520afb, 0xc32e9b3a, 0x3960fc71, + 0xd81c6db0, 0x4b9adff0, 0xaae64e31, 0xdc94bb73, 0x3de82ab2, + 0xae6e98f2, 0x4f120933, 0x428b7276, 0xa3f7e3b7, 0x307151f7, + 0xd10dc036, 0xa77f3574, 0x4603a4b5, 0xd58516f5, 0x34f98734, + 0x911ad860, 0x706649a1, 0xe3e0fbe1, 0x029c6a20, 0x74ee9f62, + 0x95920ea3, 0x0614bce3, 0xe7682d22, 0xeaf15667, 0x0b8dc7a6, + 0x980b75e6, 0x7977e427, 0x0f051165, 0xee7980a4, 0x7dff32e4, + 0x9c83a325, 0x66cdc46e, 0x87b155af, 0x1437e7ef, 0xf54b762e, + 0x8339836c, 0x624512ad, 0xf1c3a0ed, 0x10bf312c, 0x1d264a69, + 0xfc5adba8, 0x6fdc69e8, 0x8ea0f829, 0xf8d20d6b, 0x19ae9caa, + 0x8a282eea, 0x6b54bf2b, 0x71ed9041, 0x90910180, 0x0317b3c0, + 0xe26b2201, 0x9419d743, 0x75654682, 0xe6e3f4c2, 0x079f6503, + 0x0a061e46, 0xeb7a8f87, 0x78fc3dc7, 0x9980ac06, 0xeff25944, + 0x0e8ec885, 0x9d087ac5, 0x7c74eb04, 0x863a8c4f, 0x67461d8e, + 0xf4c0afce, 0x15bc3e0f, 0x63cecb4d, 0x82b25a8c, 0x1134e8cc, + 0xf048790d, 0xfdd10248, 0x1cad9389, 0x8f2b21c9, 0x6e57b008, + 0x1825454a, 0xf959d48b, 0x6adf66cb, 0x8ba3f70a, 0x2e40a85e, + 0xcf3c399f, 0x5cba8bdf, 0xbdc61a1e, 0xcbb4ef5c, 0x2ac87e9d, + 0xb94eccdd, 0x58325d1c, 0x55ab2659, 0xb4d7b798, 0x275105d8, + 0xc62d9419, 0xb05f615b, 0x5123f09a, 0xc2a542da, 0x23d9d31b, + 0xd997b450, 0x38eb2591, 0xab6d97d1, 0x4a110610, 0x3c63f352, + 0xdd1f6293, 0x4e99d0d3, 0xafe54112, 0xa27c3a57, 0x4300ab96, + 0xd08619d6, 0x31fa8817, 0x47887d55, 0xa6f4ec94, 0x35725ed4, + 0xd40ecf15}, + {0x00000000, 0x2d6cc0fd, 0x5ad981fa, 0x77b54107, 0xb5b303f4, + 0x98dfc309, 0xef6a820e, 0xc20642f3, 0xdb6507eb, 0xf609c716, + 0x81bc8611, 0xacd046ec, 0x6ed6041f, 0x43bac4e2, 0x340f85e5, + 0x19634518, 0x06c90fd5, 0x2ba5cf28, 0x5c108e2f, 0x717c4ed2, + 0xb37a0c21, 0x9e16ccdc, 0xe9a38ddb, 0xc4cf4d26, 0xddac083e, + 0xf0c0c8c3, 0x877589c4, 0xaa194939, 0x681f0bca, 0x4573cb37, + 0x32c68a30, 0x1faa4acd, 0x0d921faa, 0x20fedf57, 0x574b9e50, + 0x7a275ead, 0xb8211c5e, 0x954ddca3, 0xe2f89da4, 0xcf945d59, + 0xd6f71841, 0xfb9bd8bc, 0x8c2e99bb, 0xa1425946, 0x63441bb5, + 0x4e28db48, 0x399d9a4f, 0x14f15ab2, 0x0b5b107f, 0x2637d082, + 0x51829185, 0x7cee5178, 0xbee8138b, 0x9384d376, 0xe4319271, + 0xc95d528c, 0xd03e1794, 0xfd52d769, 0x8ae7966e, 0xa78b5693, + 0x658d1460, 0x48e1d49d, 0x3f54959a, 0x12385567, 0x1b243f54, + 0x3648ffa9, 0x41fdbeae, 0x6c917e53, 0xae973ca0, 0x83fbfc5d, + 0xf44ebd5a, 0xd9227da7, 0xc04138bf, 0xed2df842, 0x9a98b945, + 0xb7f479b8, 0x75f23b4b, 0x589efbb6, 0x2f2bbab1, 0x02477a4c, + 0x1ded3081, 0x3081f07c, 0x4734b17b, 0x6a587186, 0xa85e3375, + 0x8532f388, 0xf287b28f, 0xdfeb7272, 0xc688376a, 0xebe4f797, + 0x9c51b690, 0xb13d766d, 0x733b349e, 0x5e57f463, 0x29e2b564, + 0x048e7599, 0x16b620fe, 0x3bdae003, 0x4c6fa104, 0x610361f9, + 0xa305230a, 0x8e69e3f7, 0xf9dca2f0, 0xd4b0620d, 0xcdd32715, + 0xe0bfe7e8, 0x970aa6ef, 0xba666612, 0x786024e1, 0x550ce41c, + 0x22b9a51b, 0x0fd565e6, 0x107f2f2b, 0x3d13efd6, 0x4aa6aed1, + 0x67ca6e2c, 0xa5cc2cdf, 0x88a0ec22, 0xff15ad25, 0xd2796dd8, + 0xcb1a28c0, 0xe676e83d, 0x91c3a93a, 0xbcaf69c7, 0x7ea92b34, + 0x53c5ebc9, 0x2470aace, 0x091c6a33, 0x36487ea8, 0x1b24be55, + 0x6c91ff52, 0x41fd3faf, 0x83fb7d5c, 0xae97bda1, 0xd922fca6, + 0xf44e3c5b, 0xed2d7943, 0xc041b9be, 0xb7f4f8b9, 0x9a983844, + 0x589e7ab7, 0x75f2ba4a, 0x0247fb4d, 0x2f2b3bb0, 0x3081717d, + 0x1dedb180, 0x6a58f087, 0x4734307a, 0x85327289, 0xa85eb274, + 0xdfebf373, 0xf287338e, 0xebe47696, 0xc688b66b, 0xb13df76c, + 0x9c513791, 0x5e577562, 0x733bb59f, 0x048ef498, 0x29e23465, + 0x3bda6102, 0x16b6a1ff, 0x6103e0f8, 0x4c6f2005, 0x8e6962f6, + 0xa305a20b, 0xd4b0e30c, 0xf9dc23f1, 0xe0bf66e9, 0xcdd3a614, + 0xba66e713, 0x970a27ee, 0x550c651d, 0x7860a5e0, 0x0fd5e4e7, + 0x22b9241a, 0x3d136ed7, 0x107fae2a, 0x67caef2d, 0x4aa62fd0, + 0x88a06d23, 0xa5ccadde, 0xd279ecd9, 0xff152c24, 0xe676693c, + 0xcb1aa9c1, 0xbcafe8c6, 0x91c3283b, 0x53c56ac8, 0x7ea9aa35, + 0x091ceb32, 0x24702bcf, 0x2d6c41fc, 0x00008101, 0x77b5c006, + 0x5ad900fb, 0x98df4208, 0xb5b382f5, 0xc206c3f2, 0xef6a030f, + 0xf6094617, 0xdb6586ea, 0xacd0c7ed, 0x81bc0710, 0x43ba45e3, + 0x6ed6851e, 0x1963c419, 0x340f04e4, 0x2ba54e29, 0x06c98ed4, + 0x717ccfd3, 0x5c100f2e, 0x9e164ddd, 0xb37a8d20, 0xc4cfcc27, + 0xe9a30cda, 0xf0c049c2, 0xddac893f, 0xaa19c838, 0x877508c5, + 0x45734a36, 0x681f8acb, 0x1faacbcc, 0x32c60b31, 0x20fe5e56, + 0x0d929eab, 0x7a27dfac, 0x574b1f51, 0x954d5da2, 0xb8219d5f, + 0xcf94dc58, 0xe2f81ca5, 0xfb9b59bd, 0xd6f79940, 0xa142d847, + 0x8c2e18ba, 0x4e285a49, 0x63449ab4, 0x14f1dbb3, 0x399d1b4e, + 0x26375183, 0x0b5b917e, 0x7ceed079, 0x51821084, 0x93845277, + 0xbee8928a, 0xc95dd38d, 0xe4311370, 0xfd525668, 0xd03e9695, + 0xa78bd792, 0x8ae7176f, 0x48e1559c, 0x658d9561, 0x1238d466, + 0x3f54149b}, + {0x00000000, 0x6c90fd50, 0xd921faa0, 0xb5b107f0, 0x0240f543, + 0x6ed00813, 0xdb610fe3, 0xb7f1f2b3, 0x0481ea86, 0x681117d6, + 0xdda01026, 0xb130ed76, 0x06c11fc5, 0x6a51e295, 0xdfe0e565, + 0xb3701835, 0x0903d50c, 0x6593285c, 0xd0222fac, 0xbcb2d2fc, + 0x0b43204f, 0x67d3dd1f, 0xd262daef, 0xbef227bf, 0x0d823f8a, + 0x6112c2da, 0xd4a3c52a, 0xb833387a, 0x0fc2cac9, 0x63523799, + 0xd6e33069, 0xba73cd39, 0x1207aa18, 0x7e975748, 0xcb2650b8, + 0xa7b6ade8, 0x10475f5b, 0x7cd7a20b, 0xc966a5fb, 0xa5f658ab, + 0x1686409e, 0x7a16bdce, 0xcfa7ba3e, 0xa337476e, 0x14c6b5dd, + 0x7856488d, 0xcde74f7d, 0xa177b22d, 0x1b047f14, 0x77948244, + 0xc22585b4, 0xaeb578e4, 0x19448a57, 0x75d47707, 0xc06570f7, + 0xacf58da7, 0x1f859592, 0x731568c2, 0xc6a46f32, 0xaa349262, + 0x1dc560d1, 0x71559d81, 0xc4e49a71, 0xa8746721, 0x240f5430, + 0x489fa960, 0xfd2eae90, 0x91be53c0, 0x264fa173, 0x4adf5c23, + 0xff6e5bd3, 0x93fea683, 0x208ebeb6, 0x4c1e43e6, 0xf9af4416, + 0x953fb946, 0x22ce4bf5, 0x4e5eb6a5, 0xfbefb155, 0x977f4c05, + 0x2d0c813c, 0x419c7c6c, 0xf42d7b9c, 0x98bd86cc, 0x2f4c747f, + 0x43dc892f, 0xf66d8edf, 0x9afd738f, 0x298d6bba, 0x451d96ea, + 0xf0ac911a, 0x9c3c6c4a, 0x2bcd9ef9, 0x475d63a9, 0xf2ec6459, + 0x9e7c9909, 0x3608fe28, 0x5a980378, 0xef290488, 0x83b9f9d8, + 0x34480b6b, 0x58d8f63b, 0xed69f1cb, 0x81f90c9b, 0x328914ae, + 0x5e19e9fe, 0xeba8ee0e, 0x8738135e, 0x30c9e1ed, 0x5c591cbd, + 0xe9e81b4d, 0x8578e61d, 0x3f0b2b24, 0x539bd674, 0xe62ad184, + 0x8aba2cd4, 0x3d4bde67, 0x51db2337, 0xe46a24c7, 0x88fad997, + 0x3b8ac1a2, 0x571a3cf2, 0xe2ab3b02, 0x8e3bc652, 0x39ca34e1, + 0x555ac9b1, 0xe0ebce41, 0x8c7b3311, 0x481ea860, 0x248e5530, + 0x913f52c0, 0xfdafaf90, 0x4a5e5d23, 0x26cea073, 0x937fa783, + 0xffef5ad3, 0x4c9f42e6, 0x200fbfb6, 0x95beb846, 0xf92e4516, + 0x4edfb7a5, 0x224f4af5, 0x97fe4d05, 0xfb6eb055, 0x411d7d6c, + 0x2d8d803c, 0x983c87cc, 0xf4ac7a9c, 0x435d882f, 0x2fcd757f, + 0x9a7c728f, 0xf6ec8fdf, 0x459c97ea, 0x290c6aba, 0x9cbd6d4a, + 0xf02d901a, 0x47dc62a9, 0x2b4c9ff9, 0x9efd9809, 0xf26d6559, + 0x5a190278, 0x3689ff28, 0x8338f8d8, 0xefa80588, 0x5859f73b, + 0x34c90a6b, 0x81780d9b, 0xede8f0cb, 0x5e98e8fe, 0x320815ae, + 0x87b9125e, 0xeb29ef0e, 0x5cd81dbd, 0x3048e0ed, 0x85f9e71d, + 0xe9691a4d, 0x531ad774, 0x3f8a2a24, 0x8a3b2dd4, 0xe6abd084, + 0x515a2237, 0x3dcadf67, 0x887bd897, 0xe4eb25c7, 0x579b3df2, + 0x3b0bc0a2, 0x8ebac752, 0xe22a3a02, 0x55dbc8b1, 0x394b35e1, + 0x8cfa3211, 0xe06acf41, 0x6c11fc50, 0x00810100, 0xb53006f0, + 0xd9a0fba0, 0x6e510913, 0x02c1f443, 0xb770f3b3, 0xdbe00ee3, + 0x689016d6, 0x0400eb86, 0xb1b1ec76, 0xdd211126, 0x6ad0e395, + 0x06401ec5, 0xb3f11935, 0xdf61e465, 0x6512295c, 0x0982d40c, + 0xbc33d3fc, 0xd0a32eac, 0x6752dc1f, 0x0bc2214f, 0xbe7326bf, + 0xd2e3dbef, 0x6193c3da, 0x0d033e8a, 0xb8b2397a, 0xd422c42a, + 0x63d33699, 0x0f43cbc9, 0xbaf2cc39, 0xd6623169, 0x7e165648, + 0x1286ab18, 0xa737ace8, 0xcba751b8, 0x7c56a30b, 0x10c65e5b, + 0xa57759ab, 0xc9e7a4fb, 0x7a97bcce, 0x1607419e, 0xa3b6466e, + 0xcf26bb3e, 0x78d7498d, 0x1447b4dd, 0xa1f6b32d, 0xcd664e7d, + 0x77158344, 0x1b857e14, 0xae3479e4, 0xc2a484b4, 0x75557607, + 0x19c58b57, 0xac748ca7, 0xc0e471f7, 0x739469c2, 0x1f049492, + 0xaab59362, 0xc6256e32, 0x71d49c81, 0x1d4461d1, 0xa8f56621, + 0xc4659b71}, + {0x00000000, 0x903d50c0, 0x9079a183, 0x0044f143, 0x90f04305, + 0x00cd13c5, 0x0089e286, 0x90b4b246, 0x91e38609, 0x01ded6c9, + 0x019a278a, 0x91a7774a, 0x0113c50c, 0x912e95cc, 0x916a648f, + 0x0157344f, 0x93c40c11, 0x03f95cd1, 0x03bdad92, 0x9380fd52, + 0x03344f14, 0x93091fd4, 0x934dee97, 0x0370be57, 0x02278a18, + 0x921adad8, 0x925e2b9b, 0x02637b5b, 0x92d7c91d, 0x02ea99dd, + 0x02ae689e, 0x9293385e, 0x978b1821, 0x07b648e1, 0x07f2b9a2, + 0x97cfe962, 0x077b5b24, 0x97460be4, 0x9702faa7, 0x073faa67, + 0x06689e28, 0x9655cee8, 0x96113fab, 0x062c6f6b, 0x9698dd2d, + 0x06a58ded, 0x06e17cae, 0x96dc2c6e, 0x044f1430, 0x947244f0, + 0x9436b5b3, 0x040be573, 0x94bf5735, 0x048207f5, 0x04c6f6b6, + 0x94fba676, 0x95ac9239, 0x0591c2f9, 0x05d533ba, 0x95e8637a, + 0x055cd13c, 0x956181fc, 0x952570bf, 0x0518207f, 0x9f153041, + 0x0f286081, 0x0f6c91c2, 0x9f51c102, 0x0fe57344, 0x9fd82384, + 0x9f9cd2c7, 0x0fa18207, 0x0ef6b648, 0x9ecbe688, 0x9e8f17cb, + 0x0eb2470b, 0x9e06f54d, 0x0e3ba58d, 0x0e7f54ce, 0x9e42040e, + 0x0cd13c50, 0x9cec6c90, 0x9ca89dd3, 0x0c95cd13, 0x9c217f55, + 0x0c1c2f95, 0x0c58ded6, 0x9c658e16, 0x9d32ba59, 0x0d0fea99, + 0x0d4b1bda, 0x9d764b1a, 0x0dc2f95c, 0x9dffa99c, 0x9dbb58df, + 0x0d86081f, 0x089e2860, 0x98a378a0, 0x98e789e3, 0x08dad923, + 0x986e6b65, 0x08533ba5, 0x0817cae6, 0x982a9a26, 0x997dae69, + 0x0940fea9, 0x09040fea, 0x99395f2a, 0x098ded6c, 0x99b0bdac, + 0x99f44cef, 0x09c91c2f, 0x9b5a2471, 0x0b6774b1, 0x0b2385f2, + 0x9b1ed532, 0x0baa6774, 0x9b9737b4, 0x9bd3c6f7, 0x0bee9637, + 0x0ab9a278, 0x9a84f2b8, 0x9ac003fb, 0x0afd533b, 0x9a49e17d, + 0x0a74b1bd, 0x0a3040fe, 0x9a0d103e, 0x8e296081, 0x1e143041, + 0x1e50c102, 0x8e6d91c2, 0x1ed92384, 0x8ee47344, 0x8ea08207, + 0x1e9dd2c7, 0x1fcae688, 0x8ff7b648, 0x8fb3470b, 0x1f8e17cb, + 0x8f3aa58d, 0x1f07f54d, 0x1f43040e, 0x8f7e54ce, 0x1ded6c90, + 0x8dd03c50, 0x8d94cd13, 0x1da99dd3, 0x8d1d2f95, 0x1d207f55, + 0x1d648e16, 0x8d59ded6, 0x8c0eea99, 0x1c33ba59, 0x1c774b1a, + 0x8c4a1bda, 0x1cfea99c, 0x8cc3f95c, 0x8c87081f, 0x1cba58df, + 0x19a278a0, 0x899f2860, 0x89dbd923, 0x19e689e3, 0x89523ba5, + 0x196f6b65, 0x192b9a26, 0x8916cae6, 0x8841fea9, 0x187cae69, + 0x18385f2a, 0x88050fea, 0x18b1bdac, 0x888ced6c, 0x88c81c2f, + 0x18f54cef, 0x8a6674b1, 0x1a5b2471, 0x1a1fd532, 0x8a2285f2, + 0x1a9637b4, 0x8aab6774, 0x8aef9637, 0x1ad2c6f7, 0x1b85f2b8, + 0x8bb8a278, 0x8bfc533b, 0x1bc103fb, 0x8b75b1bd, 0x1b48e17d, + 0x1b0c103e, 0x8b3140fe, 0x113c50c0, 0x81010000, 0x8145f143, + 0x1178a183, 0x81cc13c5, 0x11f14305, 0x11b5b246, 0x8188e286, + 0x80dfd6c9, 0x10e28609, 0x10a6774a, 0x809b278a, 0x102f95cc, + 0x8012c50c, 0x8056344f, 0x106b648f, 0x82f85cd1, 0x12c50c11, + 0x1281fd52, 0x82bcad92, 0x12081fd4, 0x82354f14, 0x8271be57, + 0x124cee97, 0x131bdad8, 0x83268a18, 0x83627b5b, 0x135f2b9b, + 0x83eb99dd, 0x13d6c91d, 0x1392385e, 0x83af689e, 0x86b748e1, + 0x168a1821, 0x16cee962, 0x86f3b9a2, 0x16470be4, 0x867a5b24, + 0x863eaa67, 0x1603faa7, 0x1754cee8, 0x87699e28, 0x872d6f6b, + 0x17103fab, 0x87a48ded, 0x1799dd2d, 0x17dd2c6e, 0x87e07cae, + 0x157344f0, 0x854e1430, 0x850ae573, 0x1537b5b3, 0x858307f5, + 0x15be5735, 0x15faa676, 0x85c7f6b6, 0x8490c2f9, 0x14ad9239, + 0x14e9637a, 0x84d433ba, 0x146081fc, 0x845dd13c, 0x8419207f, + 0x142470bf}, + {0x00000000, 0xac51c101, 0xe8a08201, 0x44f14300, 0x61420401, + 0xcd13c500, 0x89e28600, 0x25b34701, 0xc2840802, 0x6ed5c903, + 0x2a248a03, 0x86754b02, 0xa3c60c03, 0x0f97cd02, 0x4b668e02, + 0xe7374f03, 0x350b1007, 0x995ad106, 0xddab9206, 0x71fa5307, + 0x54491406, 0xf818d507, 0xbce99607, 0x10b85706, 0xf78f1805, + 0x5bded904, 0x1f2f9a04, 0xb37e5b05, 0x96cd1c04, 0x3a9cdd05, + 0x7e6d9e05, 0xd23c5f04, 0x6a16200e, 0xc647e10f, 0x82b6a20f, + 0x2ee7630e, 0x0b54240f, 0xa705e50e, 0xe3f4a60e, 0x4fa5670f, + 0xa892280c, 0x04c3e90d, 0x4032aa0d, 0xec636b0c, 0xc9d02c0d, + 0x6581ed0c, 0x2170ae0c, 0x8d216f0d, 0x5f1d3009, 0xf34cf108, + 0xb7bdb208, 0x1bec7309, 0x3e5f3408, 0x920ef509, 0xd6ffb609, + 0x7aae7708, 0x9d99380b, 0x31c8f90a, 0x7539ba0a, 0xd9687b0b, + 0xfcdb3c0a, 0x508afd0b, 0x147bbe0b, 0xb82a7f0a, 0xd42c401c, + 0x787d811d, 0x3c8cc21d, 0x90dd031c, 0xb56e441d, 0x193f851c, + 0x5dcec61c, 0xf19f071d, 0x16a8481e, 0xbaf9891f, 0xfe08ca1f, + 0x52590b1e, 0x77ea4c1f, 0xdbbb8d1e, 0x9f4ace1e, 0x331b0f1f, + 0xe127501b, 0x4d76911a, 0x0987d21a, 0xa5d6131b, 0x8065541a, + 0x2c34951b, 0x68c5d61b, 0xc494171a, 0x23a35819, 0x8ff29918, + 0xcb03da18, 0x67521b19, 0x42e15c18, 0xeeb09d19, 0xaa41de19, + 0x06101f18, 0xbe3a6012, 0x126ba113, 0x569ae213, 0xfacb2312, + 0xdf786413, 0x7329a512, 0x37d8e612, 0x9b892713, 0x7cbe6810, + 0xd0efa911, 0x941eea11, 0x384f2b10, 0x1dfc6c11, 0xb1adad10, + 0xf55cee10, 0x590d2f11, 0x8b317015, 0x2760b114, 0x6391f214, + 0xcfc03315, 0xea737414, 0x4622b515, 0x02d3f615, 0xae823714, + 0x49b57817, 0xe5e4b916, 0xa115fa16, 0x0d443b17, 0x28f77c16, + 0x84a6bd17, 0xc057fe17, 0x6c063f16, 0x185b803b, 0xb40a413a, + 0xf0fb023a, 0x5caac33b, 0x7919843a, 0xd548453b, 0x91b9063b, + 0x3de8c73a, 0xdadf8839, 0x768e4938, 0x327f0a38, 0x9e2ecb39, + 0xbb9d8c38, 0x17cc4d39, 0x533d0e39, 0xff6ccf38, 0x2d50903c, + 0x8101513d, 0xc5f0123d, 0x69a1d33c, 0x4c12943d, 0xe043553c, + 0xa4b2163c, 0x08e3d73d, 0xefd4983e, 0x4385593f, 0x07741a3f, + 0xab25db3e, 0x8e969c3f, 0x22c75d3e, 0x66361e3e, 0xca67df3f, + 0x724da035, 0xde1c6134, 0x9aed2234, 0x36bce335, 0x130fa434, + 0xbf5e6535, 0xfbaf2635, 0x57fee734, 0xb0c9a837, 0x1c986936, + 0x58692a36, 0xf438eb37, 0xd18bac36, 0x7dda6d37, 0x392b2e37, + 0x957aef36, 0x4746b032, 0xeb177133, 0xafe63233, 0x03b7f332, + 0x2604b433, 0x8a557532, 0xcea43632, 0x62f5f733, 0x85c2b830, + 0x29937931, 0x6d623a31, 0xc133fb30, 0xe480bc31, 0x48d17d30, + 0x0c203e30, 0xa071ff31, 0xcc77c027, 0x60260126, 0x24d74226, + 0x88868327, 0xad35c426, 0x01640527, 0x45954627, 0xe9c48726, + 0x0ef3c825, 0xa2a20924, 0xe6534a24, 0x4a028b25, 0x6fb1cc24, + 0xc3e00d25, 0x87114e25, 0x2b408f24, 0xf97cd020, 0x552d1121, + 0x11dc5221, 0xbd8d9320, 0x983ed421, 0x346f1520, 0x709e5620, + 0xdccf9721, 0x3bf8d822, 0x97a91923, 0xd3585a23, 0x7f099b22, + 0x5abadc23, 0xf6eb1d22, 0xb21a5e22, 0x1e4b9f23, 0xa661e029, + 0x0a302128, 0x4ec16228, 0xe290a329, 0xc723e428, 0x6b722529, + 0x2f836629, 0x83d2a728, 0x64e5e82b, 0xc8b4292a, 0x8c456a2a, + 0x2014ab2b, 0x05a7ec2a, 0xa9f62d2b, 0xed076e2b, 0x4156af2a, + 0x936af02e, 0x3f3b312f, 0x7bca722f, 0xd79bb32e, 0xf228f42f, + 0x5e79352e, 0x1a88762e, 0xb6d9b72f, 0x51eef82c, 0xfdbf392d, + 0xb94e7a2d, 0x151fbb2c, 0x30acfc2d, 0x9cfd3d2c, 0xd80c7e2c, + 0x745dbf2d}, + {0x00000000, 0x30b70076, 0x616e00ec, 0x51d9009a, 0xc2dc01d8, + 0xf26b01ae, 0xa3b20134, 0x93050142, 0x35bb03b3, 0x050c03c5, + 0x54d5035f, 0x64620329, 0xf767026b, 0xc7d0021d, 0x96090287, + 0xa6be02f1, 0x6b760766, 0x5bc10710, 0x0a18078a, 0x3aaf07fc, + 0xa9aa06be, 0x991d06c8, 0xc8c40652, 0xf8730624, 0x5ecd04d5, + 0x6e7a04a3, 0x3fa30439, 0x0f14044f, 0x9c11050d, 0xaca6057b, + 0xfd7f05e1, 0xcdc80597, 0xd6ec0ecc, 0xe65b0eba, 0xb7820e20, + 0x87350e56, 0x14300f14, 0x24870f62, 0x755e0ff8, 0x45e90f8e, + 0xe3570d7f, 0xd3e00d09, 0x82390d93, 0xb28e0de5, 0x218b0ca7, + 0x113c0cd1, 0x40e50c4b, 0x70520c3d, 0xbd9a09aa, 0x8d2d09dc, + 0xdcf40946, 0xec430930, 0x7f460872, 0x4ff10804, 0x1e28089e, + 0x2e9f08e8, 0x88210a19, 0xb8960a6f, 0xe94f0af5, 0xd9f80a83, + 0x4afd0bc1, 0x7a4a0bb7, 0x2b930b2d, 0x1b240b5b, 0x1ddb1d9b, + 0x2d6c1ded, 0x7cb51d77, 0x4c021d01, 0xdf071c43, 0xefb01c35, + 0xbe691caf, 0x8ede1cd9, 0x28601e28, 0x18d71e5e, 0x490e1ec4, + 0x79b91eb2, 0xeabc1ff0, 0xda0b1f86, 0x8bd21f1c, 0xbb651f6a, + 0x76ad1afd, 0x461a1a8b, 0x17c31a11, 0x27741a67, 0xb4711b25, + 0x84c61b53, 0xd51f1bc9, 0xe5a81bbf, 0x4316194e, 0x73a11938, + 0x227819a2, 0x12cf19d4, 0x81ca1896, 0xb17d18e0, 0xe0a4187a, + 0xd013180c, 0xcb371357, 0xfb801321, 0xaa5913bb, 0x9aee13cd, + 0x09eb128f, 0x395c12f9, 0x68851263, 0x58321215, 0xfe8c10e4, + 0xce3b1092, 0x9fe21008, 0xaf55107e, 0x3c50113c, 0x0ce7114a, + 0x5d3e11d0, 0x6d8911a6, 0xa0411431, 0x90f61447, 0xc12f14dd, + 0xf19814ab, 0x629d15e9, 0x522a159f, 0x03f31505, 0x33441573, + 0x95fa1782, 0xa54d17f4, 0xf494176e, 0xc4231718, 0x5726165a, + 0x6791162c, 0x364816b6, 0x06ff16c0, 0x3bb63b36, 0x0b013b40, + 0x5ad83bda, 0x6a6f3bac, 0xf96a3aee, 0xc9dd3a98, 0x98043a02, + 0xa8b33a74, 0x0e0d3885, 0x3eba38f3, 0x6f633869, 0x5fd4381f, + 0xccd1395d, 0xfc66392b, 0xadbf39b1, 0x9d0839c7, 0x50c03c50, + 0x60773c26, 0x31ae3cbc, 0x01193cca, 0x921c3d88, 0xa2ab3dfe, + 0xf3723d64, 0xc3c53d12, 0x657b3fe3, 0x55cc3f95, 0x04153f0f, + 0x34a23f79, 0xa7a73e3b, 0x97103e4d, 0xc6c93ed7, 0xf67e3ea1, + 0xed5a35fa, 0xdded358c, 0x8c343516, 0xbc833560, 0x2f863422, + 0x1f313454, 0x4ee834ce, 0x7e5f34b8, 0xd8e13649, 0xe856363f, + 0xb98f36a5, 0x893836d3, 0x1a3d3791, 0x2a8a37e7, 0x7b53377d, + 0x4be4370b, 0x862c329c, 0xb69b32ea, 0xe7423270, 0xd7f53206, + 0x44f03344, 0x74473332, 0x259e33a8, 0x152933de, 0xb397312f, + 0x83203159, 0xd2f931c3, 0xe24e31b5, 0x714b30f7, 0x41fc3081, + 0x1025301b, 0x2092306d, 0x266d26ad, 0x16da26db, 0x47032641, + 0x77b42637, 0xe4b12775, 0xd4062703, 0x85df2799, 0xb56827ef, + 0x13d6251e, 0x23612568, 0x72b825f2, 0x420f2584, 0xd10a24c6, + 0xe1bd24b0, 0xb064242a, 0x80d3245c, 0x4d1b21cb, 0x7dac21bd, + 0x2c752127, 0x1cc22151, 0x8fc72013, 0xbf702065, 0xeea920ff, + 0xde1e2089, 0x78a02278, 0x4817220e, 0x19ce2294, 0x297922e2, + 0xba7c23a0, 0x8acb23d6, 0xdb12234c, 0xeba5233a, 0xf0812861, + 0xc0362817, 0x91ef288d, 0xa15828fb, 0x325d29b9, 0x02ea29cf, + 0x53332955, 0x63842923, 0xc53a2bd2, 0xf58d2ba4, 0xa4542b3e, + 0x94e32b48, 0x07e62a0a, 0x37512a7c, 0x66882ae6, 0x563f2a90, + 0x9bf72f07, 0xab402f71, 0xfa992feb, 0xca2e2f9d, 0x592b2edf, + 0x699c2ea9, 0x38452e33, 0x08f22e45, 0xae4c2cb4, 0x9efb2cc2, + 0xcf222c58, 0xff952c2e, 0x6c902d6c, 0x5c272d1a, 0x0dfe2d80, + 0x3d492df6}, + {0x00000000, 0x776c766c, 0xeed8ecd8, 0x99b49ab4, 0x6db2d9b3, + 0x1adeafdf, 0x836a356b, 0xf4064307, 0xdb65b366, 0xac09c50a, + 0x35bd5fbe, 0x42d129d2, 0xb6d76ad5, 0xc1bb1cb9, 0x580f860d, + 0x2f63f061, 0x06c866cf, 0x71a410a3, 0xe8108a17, 0x9f7cfc7b, + 0x6b7abf7c, 0x1c16c910, 0x85a253a4, 0xf2ce25c8, 0xddadd5a9, + 0xaac1a3c5, 0x33753971, 0x44194f1d, 0xb01f0c1a, 0xc7737a76, + 0x5ec7e0c2, 0x29ab96ae, 0x0d90cd9e, 0x7afcbbf2, 0xe3482146, + 0x9424572a, 0x6022142d, 0x174e6241, 0x8efaf8f5, 0xf9968e99, + 0xd6f57ef8, 0xa1990894, 0x382d9220, 0x4f41e44c, 0xbb47a74b, + 0xcc2bd127, 0x559f4b93, 0x22f33dff, 0x0b58ab51, 0x7c34dd3d, + 0xe5804789, 0x92ec31e5, 0x66ea72e2, 0x1186048e, 0x88329e3a, + 0xff5ee856, 0xd03d1837, 0xa7516e5b, 0x3ee5f4ef, 0x49898283, + 0xbd8fc184, 0xcae3b7e8, 0x53572d5c, 0x243b5b30, 0x1b219b3c, + 0x6c4ded50, 0xf5f977e4, 0x82950188, 0x7693428f, 0x01ff34e3, + 0x984bae57, 0xef27d83b, 0xc044285a, 0xb7285e36, 0x2e9cc482, + 0x59f0b2ee, 0xadf6f1e9, 0xda9a8785, 0x432e1d31, 0x34426b5d, + 0x1de9fdf3, 0x6a858b9f, 0xf331112b, 0x845d6747, 0x705b2440, + 0x0737522c, 0x9e83c898, 0xe9efbef4, 0xc68c4e95, 0xb1e038f9, + 0x2854a24d, 0x5f38d421, 0xab3e9726, 0xdc52e14a, 0x45e67bfe, + 0x328a0d92, 0x16b156a2, 0x61dd20ce, 0xf869ba7a, 0x8f05cc16, + 0x7b038f11, 0x0c6ff97d, 0x95db63c9, 0xe2b715a5, 0xcdd4e5c4, + 0xbab893a8, 0x230c091c, 0x54607f70, 0xa0663c77, 0xd70a4a1b, + 0x4ebed0af, 0x39d2a6c3, 0x1079306d, 0x67154601, 0xfea1dcb5, + 0x89cdaad9, 0x7dcbe9de, 0x0aa79fb2, 0x93130506, 0xe47f736a, + 0xcb1c830b, 0xbc70f567, 0x25c46fd3, 0x52a819bf, 0xa6ae5ab8, + 0xd1c22cd4, 0x4876b660, 0x3f1ac00c, 0x36433678, 0x412f4014, + 0xd89bdaa0, 0xaff7accc, 0x5bf1efcb, 0x2c9d99a7, 0xb5290313, + 0xc245757f, 0xed26851e, 0x9a4af372, 0x03fe69c6, 0x74921faa, + 0x80945cad, 0xf7f82ac1, 0x6e4cb075, 0x1920c619, 0x308b50b7, + 0x47e726db, 0xde53bc6f, 0xa93fca03, 0x5d398904, 0x2a55ff68, + 0xb3e165dc, 0xc48d13b0, 0xebeee3d1, 0x9c8295bd, 0x05360f09, + 0x725a7965, 0x865c3a62, 0xf1304c0e, 0x6884d6ba, 0x1fe8a0d6, + 0x3bd3fbe6, 0x4cbf8d8a, 0xd50b173e, 0xa2676152, 0x56612255, + 0x210d5439, 0xb8b9ce8d, 0xcfd5b8e1, 0xe0b64880, 0x97da3eec, + 0x0e6ea458, 0x7902d234, 0x8d049133, 0xfa68e75f, 0x63dc7deb, + 0x14b00b87, 0x3d1b9d29, 0x4a77eb45, 0xd3c371f1, 0xa4af079d, + 0x50a9449a, 0x27c532f6, 0xbe71a842, 0xc91dde2e, 0xe67e2e4f, + 0x91125823, 0x08a6c297, 0x7fcab4fb, 0x8bccf7fc, 0xfca08190, + 0x65141b24, 0x12786d48, 0x2d62ad44, 0x5a0edb28, 0xc3ba419c, + 0xb4d637f0, 0x40d074f7, 0x37bc029b, 0xae08982f, 0xd964ee43, + 0xf6071e22, 0x816b684e, 0x18dff2fa, 0x6fb38496, 0x9bb5c791, + 0xecd9b1fd, 0x756d2b49, 0x02015d25, 0x2baacb8b, 0x5cc6bde7, + 0xc5722753, 0xb21e513f, 0x46181238, 0x31746454, 0xa8c0fee0, + 0xdfac888c, 0xf0cf78ed, 0x87a30e81, 0x1e179435, 0x697be259, + 0x9d7da15e, 0xea11d732, 0x73a54d86, 0x04c93bea, 0x20f260da, + 0x579e16b6, 0xce2a8c02, 0xb946fa6e, 0x4d40b969, 0x3a2ccf05, + 0xa39855b1, 0xd4f423dd, 0xfb97d3bc, 0x8cfba5d0, 0x154f3f64, + 0x62234908, 0x96250a0f, 0xe1497c63, 0x78fde6d7, 0x0f9190bb, + 0x263a0615, 0x51567079, 0xc8e2eacd, 0xbf8e9ca1, 0x4b88dfa6, + 0x3ce4a9ca, 0xa550337e, 0xd23c4512, 0xfd5fb573, 0x8a33c31f, + 0x138759ab, 0x64eb2fc7, 0x90ed6cc0, 0xe7811aac, 0x7e358018, + 0x0959f674}, + {0x00000000, 0x6c866cf0, 0xd90cd9e0, 0xb58ab510, 0x021ab3c3, + 0x6e9cdf33, 0xdb166a23, 0xb79006d3, 0x04356786, 0x68b30b76, + 0xdd39be66, 0xb1bfd296, 0x062fd445, 0x6aa9b8b5, 0xdf230da5, + 0xb3a56155, 0x086acf0c, 0x64eca3fc, 0xd16616ec, 0xbde07a1c, + 0x0a707ccf, 0x66f6103f, 0xd37ca52f, 0xbffac9df, 0x0c5fa88a, + 0x60d9c47a, 0xd553716a, 0xb9d51d9a, 0x0e451b49, 0x62c377b9, + 0xd749c2a9, 0xbbcfae59, 0x10d59e18, 0x7c53f2e8, 0xc9d947f8, + 0xa55f2b08, 0x12cf2ddb, 0x7e49412b, 0xcbc3f43b, 0xa74598cb, + 0x14e0f99e, 0x7866956e, 0xcdec207e, 0xa16a4c8e, 0x16fa4a5d, + 0x7a7c26ad, 0xcff693bd, 0xa370ff4d, 0x18bf5114, 0x74393de4, + 0xc1b388f4, 0xad35e404, 0x1aa5e2d7, 0x76238e27, 0xc3a93b37, + 0xaf2f57c7, 0x1c8a3692, 0x700c5a62, 0xc586ef72, 0xa9008382, + 0x1e908551, 0x7216e9a1, 0xc79c5cb1, 0xab1a3041, 0x21ab3c30, + 0x4d2d50c0, 0xf8a7e5d0, 0x94218920, 0x23b18ff3, 0x4f37e303, + 0xfabd5613, 0x963b3ae3, 0x259e5bb6, 0x49183746, 0xfc928256, + 0x9014eea6, 0x2784e875, 0x4b028485, 0xfe883195, 0x920e5d65, + 0x29c1f33c, 0x45479fcc, 0xf0cd2adc, 0x9c4b462c, 0x2bdb40ff, + 0x475d2c0f, 0xf2d7991f, 0x9e51f5ef, 0x2df494ba, 0x4172f84a, + 0xf4f84d5a, 0x987e21aa, 0x2fee2779, 0x43684b89, 0xf6e2fe99, + 0x9a649269, 0x317ea228, 0x5df8ced8, 0xe8727bc8, 0x84f41738, + 0x336411eb, 0x5fe27d1b, 0xea68c80b, 0x86eea4fb, 0x354bc5ae, + 0x59cda95e, 0xec471c4e, 0x80c170be, 0x3751766d, 0x5bd71a9d, + 0xee5daf8d, 0x82dbc37d, 0x39146d24, 0x559201d4, 0xe018b4c4, + 0x8c9ed834, 0x3b0edee7, 0x5788b217, 0xe2020707, 0x8e846bf7, + 0x3d210aa2, 0x51a76652, 0xe42dd342, 0x88abbfb2, 0x3f3bb961, + 0x53bdd591, 0xe6376081, 0x8ab10c71, 0x43567860, 0x2fd01490, + 0x9a5aa180, 0xf6dccd70, 0x414ccba3, 0x2dcaa753, 0x98401243, + 0xf4c67eb3, 0x47631fe6, 0x2be57316, 0x9e6fc606, 0xf2e9aaf6, + 0x4579ac25, 0x29ffc0d5, 0x9c7575c5, 0xf0f31935, 0x4b3cb76c, + 0x27badb9c, 0x92306e8c, 0xfeb6027c, 0x492604af, 0x25a0685f, + 0x902add4f, 0xfcacb1bf, 0x4f09d0ea, 0x238fbc1a, 0x9605090a, + 0xfa8365fa, 0x4d136329, 0x21950fd9, 0x941fbac9, 0xf899d639, + 0x5383e678, 0x3f058a88, 0x8a8f3f98, 0xe6095368, 0x519955bb, + 0x3d1f394b, 0x88958c5b, 0xe413e0ab, 0x57b681fe, 0x3b30ed0e, + 0x8eba581e, 0xe23c34ee, 0x55ac323d, 0x392a5ecd, 0x8ca0ebdd, + 0xe026872d, 0x5be92974, 0x376f4584, 0x82e5f094, 0xee639c64, + 0x59f39ab7, 0x3575f647, 0x80ff4357, 0xec792fa7, 0x5fdc4ef2, + 0x335a2202, 0x86d09712, 0xea56fbe2, 0x5dc6fd31, 0x314091c1, + 0x84ca24d1, 0xe84c4821, 0x62fd4450, 0x0e7b28a0, 0xbbf19db0, + 0xd777f140, 0x60e7f793, 0x0c619b63, 0xb9eb2e73, 0xd56d4283, + 0x66c823d6, 0x0a4e4f26, 0xbfc4fa36, 0xd34296c6, 0x64d29015, + 0x0854fce5, 0xbdde49f5, 0xd1582505, 0x6a978b5c, 0x0611e7ac, + 0xb39b52bc, 0xdf1d3e4c, 0x688d389f, 0x040b546f, 0xb181e17f, + 0xdd078d8f, 0x6ea2ecda, 0x0224802a, 0xb7ae353a, 0xdb2859ca, + 0x6cb85f19, 0x003e33e9, 0xb5b486f9, 0xd932ea09, 0x7228da48, + 0x1eaeb6b8, 0xab2403a8, 0xc7a26f58, 0x7032698b, 0x1cb4057b, + 0xa93eb06b, 0xc5b8dc9b, 0x761dbdce, 0x1a9bd13e, 0xaf11642e, + 0xc39708de, 0x74070e0d, 0x188162fd, 0xad0bd7ed, 0xc18dbb1d, + 0x7a421544, 0x16c479b4, 0xa34ecca4, 0xcfc8a054, 0x7858a687, + 0x14deca77, 0xa1547f67, 0xcdd21397, 0x7e7772c2, 0x12f11e32, + 0xa77bab22, 0xcbfdc7d2, 0x7c6dc101, 0x10ebadf1, 0xa56118e1, + 0xc9e77411}}; + +static const word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0xf06c866c00000000, 0xe0d90cd900000000, + 0x10b58ab500000000, 0xc3b31a0200000000, 0x33df9c6e00000000, + 0x236a16db00000000, 0xd30690b700000000, 0x8667350400000000, + 0x760bb36800000000, 0x66be39dd00000000, 0x96d2bfb100000000, + 0x45d42f0600000000, 0xb5b8a96a00000000, 0xa50d23df00000000, + 0x5561a5b300000000, 0x0ccf6a0800000000, 0xfca3ec6400000000, + 0xec1666d100000000, 0x1c7ae0bd00000000, 0xcf7c700a00000000, + 0x3f10f66600000000, 0x2fa57cd300000000, 0xdfc9fabf00000000, + 0x8aa85f0c00000000, 0x7ac4d96000000000, 0x6a7153d500000000, + 0x9a1dd5b900000000, 0x491b450e00000000, 0xb977c36200000000, + 0xa9c249d700000000, 0x59aecfbb00000000, 0x189ed51000000000, + 0xe8f2537c00000000, 0xf847d9c900000000, 0x082b5fa500000000, + 0xdb2dcf1200000000, 0x2b41497e00000000, 0x3bf4c3cb00000000, + 0xcb9845a700000000, 0x9ef9e01400000000, 0x6e95667800000000, + 0x7e20eccd00000000, 0x8e4c6aa100000000, 0x5d4afa1600000000, + 0xad267c7a00000000, 0xbd93f6cf00000000, 0x4dff70a300000000, + 0x1451bf1800000000, 0xe43d397400000000, 0xf488b3c100000000, + 0x04e435ad00000000, 0xd7e2a51a00000000, 0x278e237600000000, + 0x373ba9c300000000, 0xc7572faf00000000, 0x92368a1c00000000, + 0x625a0c7000000000, 0x72ef86c500000000, 0x828300a900000000, + 0x5185901e00000000, 0xa1e9167200000000, 0xb15c9cc700000000, + 0x41301aab00000000, 0x303cab2100000000, 0xc0502d4d00000000, + 0xd0e5a7f800000000, 0x2089219400000000, 0xf38fb12300000000, + 0x03e3374f00000000, 0x1356bdfa00000000, 0xe33a3b9600000000, + 0xb65b9e2500000000, 0x4637184900000000, 0x568292fc00000000, + 0xa6ee149000000000, 0x75e8842700000000, 0x8584024b00000000, + 0x953188fe00000000, 0x655d0e9200000000, 0x3cf3c12900000000, + 0xcc9f474500000000, 0xdc2acdf000000000, 0x2c464b9c00000000, + 0xff40db2b00000000, 0x0f2c5d4700000000, 0x1f99d7f200000000, + 0xeff5519e00000000, 0xba94f42d00000000, 0x4af8724100000000, + 0x5a4df8f400000000, 0xaa217e9800000000, 0x7927ee2f00000000, + 0x894b684300000000, 0x99fee2f600000000, 0x6992649a00000000, + 0x28a27e3100000000, 0xd8cef85d00000000, 0xc87b72e800000000, + 0x3817f48400000000, 0xeb11643300000000, 0x1b7de25f00000000, + 0x0bc868ea00000000, 0xfba4ee8600000000, 0xaec54b3500000000, + 0x5ea9cd5900000000, 0x4e1c47ec00000000, 0xbe70c18000000000, + 0x6d76513700000000, 0x9d1ad75b00000000, 0x8daf5dee00000000, + 0x7dc3db8200000000, 0x246d143900000000, 0xd401925500000000, + 0xc4b418e000000000, 0x34d89e8c00000000, 0xe7de0e3b00000000, + 0x17b2885700000000, 0x070702e200000000, 0xf76b848e00000000, + 0xa20a213d00000000, 0x5266a75100000000, 0x42d32de400000000, + 0xb2bfab8800000000, 0x61b93b3f00000000, 0x91d5bd5300000000, + 0x816037e600000000, 0x710cb18a00000000, 0x6078564300000000, + 0x9014d02f00000000, 0x80a15a9a00000000, 0x70cddcf600000000, + 0xa3cb4c4100000000, 0x53a7ca2d00000000, 0x4312409800000000, + 0xb37ec6f400000000, 0xe61f634700000000, 0x1673e52b00000000, + 0x06c66f9e00000000, 0xf6aae9f200000000, 0x25ac794500000000, + 0xd5c0ff2900000000, 0xc575759c00000000, 0x3519f3f000000000, + 0x6cb73c4b00000000, 0x9cdbba2700000000, 0x8c6e309200000000, + 0x7c02b6fe00000000, 0xaf04264900000000, 0x5f68a02500000000, + 0x4fdd2a9000000000, 0xbfb1acfc00000000, 0xead0094f00000000, + 0x1abc8f2300000000, 0x0a09059600000000, 0xfa6583fa00000000, + 0x2963134d00000000, 0xd90f952100000000, 0xc9ba1f9400000000, + 0x39d699f800000000, 0x78e6835300000000, 0x888a053f00000000, + 0x983f8f8a00000000, 0x685309e600000000, 0xbb55995100000000, + 0x4b391f3d00000000, 0x5b8c958800000000, 0xabe013e400000000, + 0xfe81b65700000000, 0x0eed303b00000000, 0x1e58ba8e00000000, + 0xee343ce200000000, 0x3d32ac5500000000, 0xcd5e2a3900000000, + 0xddeba08c00000000, 0x2d8726e000000000, 0x7429e95b00000000, + 0x84456f3700000000, 0x94f0e58200000000, 0x649c63ee00000000, + 0xb79af35900000000, 0x47f6753500000000, 0x5743ff8000000000, + 0xa72f79ec00000000, 0xf24edc5f00000000, 0x02225a3300000000, + 0x1297d08600000000, 0xe2fb56ea00000000, 0x31fdc65d00000000, + 0xc191403100000000, 0xd124ca8400000000, 0x21484ce800000000, + 0x5044fd6200000000, 0xa0287b0e00000000, 0xb09df1bb00000000, + 0x40f177d700000000, 0x93f7e76000000000, 0x639b610c00000000, + 0x732eebb900000000, 0x83426dd500000000, 0xd623c86600000000, + 0x264f4e0a00000000, 0x36fac4bf00000000, 0xc69642d300000000, + 0x1590d26400000000, 0xe5fc540800000000, 0xf549debd00000000, + 0x052558d100000000, 0x5c8b976a00000000, 0xace7110600000000, + 0xbc529bb300000000, 0x4c3e1ddf00000000, 0x9f388d6800000000, + 0x6f540b0400000000, 0x7fe181b100000000, 0x8f8d07dd00000000, + 0xdaeca26e00000000, 0x2a80240200000000, 0x3a35aeb700000000, + 0xca5928db00000000, 0x195fb86c00000000, 0xe9333e0000000000, + 0xf986b4b500000000, 0x09ea32d900000000, 0x48da287200000000, + 0xb8b6ae1e00000000, 0xa80324ab00000000, 0x586fa2c700000000, + 0x8b69327000000000, 0x7b05b41c00000000, 0x6bb03ea900000000, + 0x9bdcb8c500000000, 0xcebd1d7600000000, 0x3ed19b1a00000000, + 0x2e6411af00000000, 0xde0897c300000000, 0x0d0e077400000000, + 0xfd62811800000000, 0xedd70bad00000000, 0x1dbb8dc100000000, + 0x4415427a00000000, 0xb479c41600000000, 0xa4cc4ea300000000, + 0x54a0c8cf00000000, 0x87a6587800000000, 0x77cade1400000000, + 0x677f54a100000000, 0x9713d2cd00000000, 0xc272777e00000000, + 0x321ef11200000000, 0x22ab7ba700000000, 0xd2c7fdcb00000000, + 0x01c16d7c00000000, 0xf1adeb1000000000, 0xe11861a500000000, + 0x1174e7c900000000}, + {0x0000000000000000, 0x6c766c7700000000, 0xd8ecd8ee00000000, + 0xb49ab49900000000, 0xb3d9b26d00000000, 0xdfafde1a00000000, + 0x6b356a8300000000, 0x074306f400000000, 0x66b365db00000000, + 0x0ac509ac00000000, 0xbe5fbd3500000000, 0xd229d14200000000, + 0xd56ad7b600000000, 0xb91cbbc100000000, 0x0d860f5800000000, + 0x61f0632f00000000, 0xcf66c80600000000, 0xa310a47100000000, + 0x178a10e800000000, 0x7bfc7c9f00000000, 0x7cbf7a6b00000000, + 0x10c9161c00000000, 0xa453a28500000000, 0xc825cef200000000, + 0xa9d5addd00000000, 0xc5a3c1aa00000000, 0x7139753300000000, + 0x1d4f194400000000, 0x1a0c1fb000000000, 0x767a73c700000000, + 0xc2e0c75e00000000, 0xae96ab2900000000, 0x9ecd900d00000000, + 0xf2bbfc7a00000000, 0x462148e300000000, 0x2a57249400000000, + 0x2d14226000000000, 0x41624e1700000000, 0xf5f8fa8e00000000, + 0x998e96f900000000, 0xf87ef5d600000000, 0x940899a100000000, + 0x20922d3800000000, 0x4ce4414f00000000, 0x4ba747bb00000000, + 0x27d12bcc00000000, 0x934b9f5500000000, 0xff3df32200000000, + 0x51ab580b00000000, 0x3ddd347c00000000, 0x894780e500000000, + 0xe531ec9200000000, 0xe272ea6600000000, 0x8e04861100000000, + 0x3a9e328800000000, 0x56e85eff00000000, 0x37183dd000000000, + 0x5b6e51a700000000, 0xeff4e53e00000000, 0x8382894900000000, + 0x84c18fbd00000000, 0xe8b7e3ca00000000, 0x5c2d575300000000, + 0x305b3b2400000000, 0x3c9b211b00000000, 0x50ed4d6c00000000, + 0xe477f9f500000000, 0x8801958200000000, 0x8f42937600000000, + 0xe334ff0100000000, 0x57ae4b9800000000, 0x3bd827ef00000000, + 0x5a2844c000000000, 0x365e28b700000000, 0x82c49c2e00000000, + 0xeeb2f05900000000, 0xe9f1f6ad00000000, 0x85879ada00000000, + 0x311d2e4300000000, 0x5d6b423400000000, 0xf3fde91d00000000, + 0x9f8b856a00000000, 0x2b1131f300000000, 0x47675d8400000000, + 0x40245b7000000000, 0x2c52370700000000, 0x98c8839e00000000, + 0xf4beefe900000000, 0x954e8cc600000000, 0xf938e0b100000000, + 0x4da2542800000000, 0x21d4385f00000000, 0x26973eab00000000, + 0x4ae152dc00000000, 0xfe7be64500000000, 0x920d8a3200000000, + 0xa256b11600000000, 0xce20dd6100000000, 0x7aba69f800000000, + 0x16cc058f00000000, 0x118f037b00000000, 0x7df96f0c00000000, + 0xc963db9500000000, 0xa515b7e200000000, 0xc4e5d4cd00000000, + 0xa893b8ba00000000, 0x1c090c2300000000, 0x707f605400000000, + 0x773c66a000000000, 0x1b4a0ad700000000, 0xafd0be4e00000000, + 0xc3a6d23900000000, 0x6d30791000000000, 0x0146156700000000, + 0xb5dca1fe00000000, 0xd9aacd8900000000, 0xdee9cb7d00000000, + 0xb29fa70a00000000, 0x0605139300000000, 0x6a737fe400000000, + 0x0b831ccb00000000, 0x67f570bc00000000, 0xd36fc42500000000, + 0xbf19a85200000000, 0xb85aaea600000000, 0xd42cc2d100000000, + 0x60b6764800000000, 0x0cc01a3f00000000, 0x7836433600000000, + 0x14402f4100000000, 0xa0da9bd800000000, 0xccacf7af00000000, + 0xcbeff15b00000000, 0xa7999d2c00000000, 0x130329b500000000, + 0x7f7545c200000000, 0x1e8526ed00000000, 0x72f34a9a00000000, + 0xc669fe0300000000, 0xaa1f927400000000, 0xad5c948000000000, + 0xc12af8f700000000, 0x75b04c6e00000000, 0x19c6201900000000, + 0xb7508b3000000000, 0xdb26e74700000000, 0x6fbc53de00000000, + 0x03ca3fa900000000, 0x0489395d00000000, 0x68ff552a00000000, + 0xdc65e1b300000000, 0xb0138dc400000000, 0xd1e3eeeb00000000, + 0xbd95829c00000000, 0x090f360500000000, 0x65795a7200000000, + 0x623a5c8600000000, 0x0e4c30f100000000, 0xbad6846800000000, + 0xd6a0e81f00000000, 0xe6fbd33b00000000, 0x8a8dbf4c00000000, + 0x3e170bd500000000, 0x526167a200000000, 0x5522615600000000, + 0x39540d2100000000, 0x8dceb9b800000000, 0xe1b8d5cf00000000, + 0x8048b6e000000000, 0xec3eda9700000000, 0x58a46e0e00000000, + 0x34d2027900000000, 0x3391048d00000000, 0x5fe768fa00000000, + 0xeb7ddc6300000000, 0x870bb01400000000, 0x299d1b3d00000000, + 0x45eb774a00000000, 0xf171c3d300000000, 0x9d07afa400000000, + 0x9a44a95000000000, 0xf632c52700000000, 0x42a871be00000000, + 0x2ede1dc900000000, 0x4f2e7ee600000000, 0x2358129100000000, + 0x97c2a60800000000, 0xfbb4ca7f00000000, 0xfcf7cc8b00000000, + 0x9081a0fc00000000, 0x241b146500000000, 0x486d781200000000, + 0x44ad622d00000000, 0x28db0e5a00000000, 0x9c41bac300000000, + 0xf037d6b400000000, 0xf774d04000000000, 0x9b02bc3700000000, + 0x2f9808ae00000000, 0x43ee64d900000000, 0x221e07f600000000, + 0x4e686b8100000000, 0xfaf2df1800000000, 0x9684b36f00000000, + 0x91c7b59b00000000, 0xfdb1d9ec00000000, 0x492b6d7500000000, + 0x255d010200000000, 0x8bcbaa2b00000000, 0xe7bdc65c00000000, + 0x532772c500000000, 0x3f511eb200000000, 0x3812184600000000, + 0x5464743100000000, 0xe0fec0a800000000, 0x8c88acdf00000000, + 0xed78cff000000000, 0x810ea38700000000, 0x3594171e00000000, + 0x59e27b6900000000, 0x5ea17d9d00000000, 0x32d711ea00000000, + 0x864da57300000000, 0xea3bc90400000000, 0xda60f22000000000, + 0xb6169e5700000000, 0x028c2ace00000000, 0x6efa46b900000000, + 0x69b9404d00000000, 0x05cf2c3a00000000, 0xb15598a300000000, + 0xdd23f4d400000000, 0xbcd397fb00000000, 0xd0a5fb8c00000000, + 0x643f4f1500000000, 0x0849236200000000, 0x0f0a259600000000, + 0x637c49e100000000, 0xd7e6fd7800000000, 0xbb90910f00000000, + 0x15063a2600000000, 0x7970565100000000, 0xcdeae2c800000000, + 0xa19c8ebf00000000, 0xa6df884b00000000, 0xcaa9e43c00000000, + 0x7e3350a500000000, 0x12453cd200000000, 0x73b55ffd00000000, + 0x1fc3338a00000000, 0xab59871300000000, 0xc72feb6400000000, + 0xc06ced9000000000, 0xac1a81e700000000, 0x1880357e00000000, + 0x74f6590900000000}, + {0x0000000000000000, 0x7600b73000000000, 0xec006e6100000000, + 0x9a00d95100000000, 0xd801dcc200000000, 0xae016bf200000000, + 0x3401b2a300000000, 0x4201059300000000, 0xb303bb3500000000, + 0xc5030c0500000000, 0x5f03d55400000000, 0x2903626400000000, + 0x6b0267f700000000, 0x1d02d0c700000000, 0x8702099600000000, + 0xf102bea600000000, 0x6607766b00000000, 0x1007c15b00000000, + 0x8a07180a00000000, 0xfc07af3a00000000, 0xbe06aaa900000000, + 0xc8061d9900000000, 0x5206c4c800000000, 0x240673f800000000, + 0xd504cd5e00000000, 0xa3047a6e00000000, 0x3904a33f00000000, + 0x4f04140f00000000, 0x0d05119c00000000, 0x7b05a6ac00000000, + 0xe1057ffd00000000, 0x9705c8cd00000000, 0xcc0eecd600000000, + 0xba0e5be600000000, 0x200e82b700000000, 0x560e358700000000, + 0x140f301400000000, 0x620f872400000000, 0xf80f5e7500000000, + 0x8e0fe94500000000, 0x7f0d57e300000000, 0x090de0d300000000, + 0x930d398200000000, 0xe50d8eb200000000, 0xa70c8b2100000000, + 0xd10c3c1100000000, 0x4b0ce54000000000, 0x3d0c527000000000, + 0xaa099abd00000000, 0xdc092d8d00000000, 0x4609f4dc00000000, + 0x300943ec00000000, 0x7208467f00000000, 0x0408f14f00000000, + 0x9e08281e00000000, 0xe8089f2e00000000, 0x190a218800000000, + 0x6f0a96b800000000, 0xf50a4fe900000000, 0x830af8d900000000, + 0xc10bfd4a00000000, 0xb70b4a7a00000000, 0x2d0b932b00000000, + 0x5b0b241b00000000, 0x9b1ddb1d00000000, 0xed1d6c2d00000000, + 0x771db57c00000000, 0x011d024c00000000, 0x431c07df00000000, + 0x351cb0ef00000000, 0xaf1c69be00000000, 0xd91cde8e00000000, + 0x281e602800000000, 0x5e1ed71800000000, 0xc41e0e4900000000, + 0xb21eb97900000000, 0xf01fbcea00000000, 0x861f0bda00000000, + 0x1c1fd28b00000000, 0x6a1f65bb00000000, 0xfd1aad7600000000, + 0x8b1a1a4600000000, 0x111ac31700000000, 0x671a742700000000, + 0x251b71b400000000, 0x531bc68400000000, 0xc91b1fd500000000, + 0xbf1ba8e500000000, 0x4e19164300000000, 0x3819a17300000000, + 0xa219782200000000, 0xd419cf1200000000, 0x9618ca8100000000, + 0xe0187db100000000, 0x7a18a4e000000000, 0x0c1813d000000000, + 0x571337cb00000000, 0x211380fb00000000, 0xbb1359aa00000000, + 0xcd13ee9a00000000, 0x8f12eb0900000000, 0xf9125c3900000000, + 0x6312856800000000, 0x1512325800000000, 0xe4108cfe00000000, + 0x92103bce00000000, 0x0810e29f00000000, 0x7e1055af00000000, + 0x3c11503c00000000, 0x4a11e70c00000000, 0xd0113e5d00000000, + 0xa611896d00000000, 0x311441a000000000, 0x4714f69000000000, + 0xdd142fc100000000, 0xab1498f100000000, 0xe9159d6200000000, + 0x9f152a5200000000, 0x0515f30300000000, 0x7315443300000000, + 0x8217fa9500000000, 0xf4174da500000000, 0x6e1794f400000000, + 0x181723c400000000, 0x5a16265700000000, 0x2c16916700000000, + 0xb616483600000000, 0xc016ff0600000000, 0x363bb63b00000000, + 0x403b010b00000000, 0xda3bd85a00000000, 0xac3b6f6a00000000, + 0xee3a6af900000000, 0x983addc900000000, 0x023a049800000000, + 0x743ab3a800000000, 0x85380d0e00000000, 0xf338ba3e00000000, + 0x6938636f00000000, 0x1f38d45f00000000, 0x5d39d1cc00000000, + 0x2b3966fc00000000, 0xb139bfad00000000, 0xc739089d00000000, + 0x503cc05000000000, 0x263c776000000000, 0xbc3cae3100000000, + 0xca3c190100000000, 0x883d1c9200000000, 0xfe3daba200000000, + 0x643d72f300000000, 0x123dc5c300000000, 0xe33f7b6500000000, + 0x953fcc5500000000, 0x0f3f150400000000, 0x793fa23400000000, + 0x3b3ea7a700000000, 0x4d3e109700000000, 0xd73ec9c600000000, + 0xa13e7ef600000000, 0xfa355aed00000000, 0x8c35eddd00000000, + 0x1635348c00000000, 0x603583bc00000000, 0x2234862f00000000, + 0x5434311f00000000, 0xce34e84e00000000, 0xb8345f7e00000000, + 0x4936e1d800000000, 0x3f3656e800000000, 0xa5368fb900000000, + 0xd336388900000000, 0x91373d1a00000000, 0xe7378a2a00000000, + 0x7d37537b00000000, 0x0b37e44b00000000, 0x9c322c8600000000, + 0xea329bb600000000, 0x703242e700000000, 0x0632f5d700000000, + 0x4433f04400000000, 0x3233477400000000, 0xa8339e2500000000, + 0xde33291500000000, 0x2f3197b300000000, 0x5931208300000000, + 0xc331f9d200000000, 0xb5314ee200000000, 0xf7304b7100000000, + 0x8130fc4100000000, 0x1b30251000000000, 0x6d30922000000000, + 0xad266d2600000000, 0xdb26da1600000000, 0x4126034700000000, + 0x3726b47700000000, 0x7527b1e400000000, 0x032706d400000000, + 0x9927df8500000000, 0xef2768b500000000, 0x1e25d61300000000, + 0x6825612300000000, 0xf225b87200000000, 0x84250f4200000000, + 0xc6240ad100000000, 0xb024bde100000000, 0x2a2464b000000000, + 0x5c24d38000000000, 0xcb211b4d00000000, 0xbd21ac7d00000000, + 0x2721752c00000000, 0x5121c21c00000000, 0x1320c78f00000000, + 0x652070bf00000000, 0xff20a9ee00000000, 0x89201ede00000000, + 0x7822a07800000000, 0x0e22174800000000, 0x9422ce1900000000, + 0xe222792900000000, 0xa0237cba00000000, 0xd623cb8a00000000, + 0x4c2312db00000000, 0x3a23a5eb00000000, 0x612881f000000000, + 0x172836c000000000, 0x8d28ef9100000000, 0xfb2858a100000000, + 0xb9295d3200000000, 0xcf29ea0200000000, 0x5529335300000000, + 0x2329846300000000, 0xd22b3ac500000000, 0xa42b8df500000000, + 0x3e2b54a400000000, 0x482be39400000000, 0x0a2ae60700000000, + 0x7c2a513700000000, 0xe62a886600000000, 0x902a3f5600000000, + 0x072ff79b00000000, 0x712f40ab00000000, 0xeb2f99fa00000000, + 0x9d2f2eca00000000, 0xdf2e2b5900000000, 0xa92e9c6900000000, + 0x332e453800000000, 0x452ef20800000000, 0xb42c4cae00000000, + 0xc22cfb9e00000000, 0x582c22cf00000000, 0x2e2c95ff00000000, + 0x6c2d906c00000000, 0x1a2d275c00000000, 0x802dfe0d00000000, + 0xf62d493d00000000}, + {0x0000000000000000, 0x01c151ac00000000, 0x0182a0e800000000, + 0x0043f14400000000, 0x0104426100000000, 0x00c513cd00000000, + 0x0086e28900000000, 0x0147b32500000000, 0x020884c200000000, + 0x03c9d56e00000000, 0x038a242a00000000, 0x024b758600000000, + 0x030cc6a300000000, 0x02cd970f00000000, 0x028e664b00000000, + 0x034f37e700000000, 0x07100b3500000000, 0x06d15a9900000000, + 0x0692abdd00000000, 0x0753fa7100000000, 0x0614495400000000, + 0x07d518f800000000, 0x0796e9bc00000000, 0x0657b81000000000, + 0x05188ff700000000, 0x04d9de5b00000000, 0x049a2f1f00000000, + 0x055b7eb300000000, 0x041ccd9600000000, 0x05dd9c3a00000000, + 0x059e6d7e00000000, 0x045f3cd200000000, 0x0e20166a00000000, + 0x0fe147c600000000, 0x0fa2b68200000000, 0x0e63e72e00000000, + 0x0f24540b00000000, 0x0ee505a700000000, 0x0ea6f4e300000000, + 0x0f67a54f00000000, 0x0c2892a800000000, 0x0de9c30400000000, + 0x0daa324000000000, 0x0c6b63ec00000000, 0x0d2cd0c900000000, + 0x0ced816500000000, 0x0cae702100000000, 0x0d6f218d00000000, + 0x09301d5f00000000, 0x08f14cf300000000, 0x08b2bdb700000000, + 0x0973ec1b00000000, 0x08345f3e00000000, 0x09f50e9200000000, + 0x09b6ffd600000000, 0x0877ae7a00000000, 0x0b38999d00000000, + 0x0af9c83100000000, 0x0aba397500000000, 0x0b7b68d900000000, + 0x0a3cdbfc00000000, 0x0bfd8a5000000000, 0x0bbe7b1400000000, + 0x0a7f2ab800000000, 0x1c402cd400000000, 0x1d817d7800000000, + 0x1dc28c3c00000000, 0x1c03dd9000000000, 0x1d446eb500000000, + 0x1c853f1900000000, 0x1cc6ce5d00000000, 0x1d079ff100000000, + 0x1e48a81600000000, 0x1f89f9ba00000000, 0x1fca08fe00000000, + 0x1e0b595200000000, 0x1f4cea7700000000, 0x1e8dbbdb00000000, + 0x1ece4a9f00000000, 0x1f0f1b3300000000, 0x1b5027e100000000, + 0x1a91764d00000000, 0x1ad2870900000000, 0x1b13d6a500000000, + 0x1a54658000000000, 0x1b95342c00000000, 0x1bd6c56800000000, + 0x1a1794c400000000, 0x1958a32300000000, 0x1899f28f00000000, + 0x18da03cb00000000, 0x191b526700000000, 0x185ce14200000000, + 0x199db0ee00000000, 0x19de41aa00000000, 0x181f100600000000, + 0x12603abe00000000, 0x13a16b1200000000, 0x13e29a5600000000, + 0x1223cbfa00000000, 0x136478df00000000, 0x12a5297300000000, + 0x12e6d83700000000, 0x1327899b00000000, 0x1068be7c00000000, + 0x11a9efd000000000, 0x11ea1e9400000000, 0x102b4f3800000000, + 0x116cfc1d00000000, 0x10adadb100000000, 0x10ee5cf500000000, + 0x112f0d5900000000, 0x1570318b00000000, 0x14b1602700000000, + 0x14f2916300000000, 0x1533c0cf00000000, 0x147473ea00000000, + 0x15b5224600000000, 0x15f6d30200000000, 0x143782ae00000000, + 0x1778b54900000000, 0x16b9e4e500000000, 0x16fa15a100000000, + 0x173b440d00000000, 0x167cf72800000000, 0x17bda68400000000, + 0x17fe57c000000000, 0x163f066c00000000, 0x3b805b1800000000, + 0x3a410ab400000000, 0x3a02fbf000000000, 0x3bc3aa5c00000000, + 0x3a84197900000000, 0x3b4548d500000000, 0x3b06b99100000000, + 0x3ac7e83d00000000, 0x3988dfda00000000, 0x38498e7600000000, + 0x380a7f3200000000, 0x39cb2e9e00000000, 0x388c9dbb00000000, + 0x394dcc1700000000, 0x390e3d5300000000, 0x38cf6cff00000000, + 0x3c90502d00000000, 0x3d51018100000000, 0x3d12f0c500000000, + 0x3cd3a16900000000, 0x3d94124c00000000, 0x3c5543e000000000, + 0x3c16b2a400000000, 0x3dd7e30800000000, 0x3e98d4ef00000000, + 0x3f59854300000000, 0x3f1a740700000000, 0x3edb25ab00000000, + 0x3f9c968e00000000, 0x3e5dc72200000000, 0x3e1e366600000000, + 0x3fdf67ca00000000, 0x35a04d7200000000, 0x34611cde00000000, + 0x3422ed9a00000000, 0x35e3bc3600000000, 0x34a40f1300000000, + 0x35655ebf00000000, 0x3526affb00000000, 0x34e7fe5700000000, + 0x37a8c9b000000000, 0x3669981c00000000, 0x362a695800000000, + 0x37eb38f400000000, 0x36ac8bd100000000, 0x376dda7d00000000, + 0x372e2b3900000000, 0x36ef7a9500000000, 0x32b0464700000000, + 0x337117eb00000000, 0x3332e6af00000000, 0x32f3b70300000000, + 0x33b4042600000000, 0x3275558a00000000, 0x3236a4ce00000000, + 0x33f7f56200000000, 0x30b8c28500000000, 0x3179932900000000, + 0x313a626d00000000, 0x30fb33c100000000, 0x31bc80e400000000, + 0x307dd14800000000, 0x303e200c00000000, 0x31ff71a000000000, + 0x27c077cc00000000, 0x2601266000000000, 0x2642d72400000000, + 0x2783868800000000, 0x26c435ad00000000, 0x2705640100000000, + 0x2746954500000000, 0x2687c4e900000000, 0x25c8f30e00000000, + 0x2409a2a200000000, 0x244a53e600000000, 0x258b024a00000000, + 0x24ccb16f00000000, 0x250de0c300000000, 0x254e118700000000, + 0x248f402b00000000, 0x20d07cf900000000, 0x21112d5500000000, + 0x2152dc1100000000, 0x20938dbd00000000, 0x21d43e9800000000, + 0x20156f3400000000, 0x20569e7000000000, 0x2197cfdc00000000, + 0x22d8f83b00000000, 0x2319a99700000000, 0x235a58d300000000, + 0x229b097f00000000, 0x23dcba5a00000000, 0x221debf600000000, + 0x225e1ab200000000, 0x239f4b1e00000000, 0x29e061a600000000, + 0x2821300a00000000, 0x2862c14e00000000, 0x29a390e200000000, + 0x28e423c700000000, 0x2925726b00000000, 0x2966832f00000000, + 0x28a7d28300000000, 0x2be8e56400000000, 0x2a29b4c800000000, + 0x2a6a458c00000000, 0x2bab142000000000, 0x2aeca70500000000, + 0x2b2df6a900000000, 0x2b6e07ed00000000, 0x2aaf564100000000, + 0x2ef06a9300000000, 0x2f313b3f00000000, 0x2f72ca7b00000000, + 0x2eb39bd700000000, 0x2ff428f200000000, 0x2e35795e00000000, + 0x2e76881a00000000, 0x2fb7d9b600000000, 0x2cf8ee5100000000, + 0x2d39bffd00000000, 0x2d7a4eb900000000, 0x2cbb1f1500000000, + 0x2dfcac3000000000, 0x2c3dfd9c00000000, 0x2c7e0cd800000000, + 0x2dbf5d7400000000}, + {0x0000000000000000, 0xc0503d9000000000, 0x83a1799000000000, + 0x43f1440000000000, 0x0543f09000000000, 0xc513cd0000000000, + 0x86e2890000000000, 0x46b2b49000000000, 0x0986e39100000000, + 0xc9d6de0100000000, 0x8a279a0100000000, 0x4a77a79100000000, + 0x0cc5130100000000, 0xcc952e9100000000, 0x8f646a9100000000, + 0x4f34570100000000, 0x110cc49300000000, 0xd15cf90300000000, + 0x92adbd0300000000, 0x52fd809300000000, 0x144f340300000000, + 0xd41f099300000000, 0x97ee4d9300000000, 0x57be700300000000, + 0x188a270200000000, 0xd8da1a9200000000, 0x9b2b5e9200000000, + 0x5b7b630200000000, 0x1dc9d79200000000, 0xdd99ea0200000000, + 0x9e68ae0200000000, 0x5e38939200000000, 0x21188b9700000000, + 0xe148b60700000000, 0xa2b9f20700000000, 0x62e9cf9700000000, + 0x245b7b0700000000, 0xe40b469700000000, 0xa7fa029700000000, + 0x67aa3f0700000000, 0x289e680600000000, 0xe8ce559600000000, + 0xab3f119600000000, 0x6b6f2c0600000000, 0x2ddd989600000000, + 0xed8da50600000000, 0xae7ce10600000000, 0x6e2cdc9600000000, + 0x30144f0400000000, 0xf044729400000000, 0xb3b5369400000000, + 0x73e50b0400000000, 0x3557bf9400000000, 0xf507820400000000, + 0xb6f6c60400000000, 0x76a6fb9400000000, 0x3992ac9500000000, + 0xf9c2910500000000, 0xba33d50500000000, 0x7a63e89500000000, + 0x3cd15c0500000000, 0xfc81619500000000, 0xbf70259500000000, + 0x7f20180500000000, 0x4130159f00000000, 0x8160280f00000000, + 0xc2916c0f00000000, 0x02c1519f00000000, 0x4473e50f00000000, + 0x8423d89f00000000, 0xc7d29c9f00000000, 0x0782a10f00000000, + 0x48b6f60e00000000, 0x88e6cb9e00000000, 0xcb178f9e00000000, + 0x0b47b20e00000000, 0x4df5069e00000000, 0x8da53b0e00000000, + 0xce547f0e00000000, 0x0e04429e00000000, 0x503cd10c00000000, + 0x906cec9c00000000, 0xd39da89c00000000, 0x13cd950c00000000, + 0x557f219c00000000, 0x952f1c0c00000000, 0xd6de580c00000000, + 0x168e659c00000000, 0x59ba329d00000000, 0x99ea0f0d00000000, + 0xda1b4b0d00000000, 0x1a4b769d00000000, 0x5cf9c20d00000000, + 0x9ca9ff9d00000000, 0xdf58bb9d00000000, 0x1f08860d00000000, + 0x60289e0800000000, 0xa078a39800000000, 0xe389e79800000000, + 0x23d9da0800000000, 0x656b6e9800000000, 0xa53b530800000000, + 0xe6ca170800000000, 0x269a2a9800000000, 0x69ae7d9900000000, + 0xa9fe400900000000, 0xea0f040900000000, 0x2a5f399900000000, + 0x6ced8d0900000000, 0xacbdb09900000000, 0xef4cf49900000000, + 0x2f1cc90900000000, 0x71245a9b00000000, 0xb174670b00000000, + 0xf285230b00000000, 0x32d51e9b00000000, 0x7467aa0b00000000, + 0xb437979b00000000, 0xf7c6d39b00000000, 0x3796ee0b00000000, + 0x78a2b90a00000000, 0xb8f2849a00000000, 0xfb03c09a00000000, + 0x3b53fd0a00000000, 0x7de1499a00000000, 0xbdb1740a00000000, + 0xfe40300a00000000, 0x3e100d9a00000000, 0x8160298e00000000, + 0x4130141e00000000, 0x02c1501e00000000, 0xc2916d8e00000000, + 0x8423d91e00000000, 0x4473e48e00000000, 0x0782a08e00000000, + 0xc7d29d1e00000000, 0x88e6ca1f00000000, 0x48b6f78f00000000, + 0x0b47b38f00000000, 0xcb178e1f00000000, 0x8da53a8f00000000, + 0x4df5071f00000000, 0x0e04431f00000000, 0xce547e8f00000000, + 0x906ced1d00000000, 0x503cd08d00000000, 0x13cd948d00000000, + 0xd39da91d00000000, 0x952f1d8d00000000, 0x557f201d00000000, + 0x168e641d00000000, 0xd6de598d00000000, 0x99ea0e8c00000000, + 0x59ba331c00000000, 0x1a4b771c00000000, 0xda1b4a8c00000000, + 0x9ca9fe1c00000000, 0x5cf9c38c00000000, 0x1f08878c00000000, + 0xdf58ba1c00000000, 0xa078a21900000000, 0x60289f8900000000, + 0x23d9db8900000000, 0xe389e61900000000, 0xa53b528900000000, + 0x656b6f1900000000, 0x269a2b1900000000, 0xe6ca168900000000, + 0xa9fe418800000000, 0x69ae7c1800000000, 0x2a5f381800000000, + 0xea0f058800000000, 0xacbdb11800000000, 0x6ced8c8800000000, + 0x2f1cc88800000000, 0xef4cf51800000000, 0xb174668a00000000, + 0x71245b1a00000000, 0x32d51f1a00000000, 0xf285228a00000000, + 0xb437961a00000000, 0x7467ab8a00000000, 0x3796ef8a00000000, + 0xf7c6d21a00000000, 0xb8f2851b00000000, 0x78a2b88b00000000, + 0x3b53fc8b00000000, 0xfb03c11b00000000, 0xbdb1758b00000000, + 0x7de1481b00000000, 0x3e100c1b00000000, 0xfe40318b00000000, + 0xc0503c1100000000, 0x0000018100000000, 0x43f1458100000000, + 0x83a1781100000000, 0xc513cc8100000000, 0x0543f11100000000, + 0x46b2b51100000000, 0x86e2888100000000, 0xc9d6df8000000000, + 0x0986e21000000000, 0x4a77a61000000000, 0x8a279b8000000000, + 0xcc952f1000000000, 0x0cc5128000000000, 0x4f34568000000000, + 0x8f646b1000000000, 0xd15cf88200000000, 0x110cc51200000000, + 0x52fd811200000000, 0x92adbc8200000000, 0xd41f081200000000, + 0x144f358200000000, 0x57be718200000000, 0x97ee4c1200000000, + 0xd8da1b1300000000, 0x188a268300000000, 0x5b7b628300000000, + 0x9b2b5f1300000000, 0xdd99eb8300000000, 0x1dc9d61300000000, + 0x5e38921300000000, 0x9e68af8300000000, 0xe148b78600000000, + 0x21188a1600000000, 0x62e9ce1600000000, 0xa2b9f38600000000, + 0xe40b471600000000, 0x245b7a8600000000, 0x67aa3e8600000000, + 0xa7fa031600000000, 0xe8ce541700000000, 0x289e698700000000, + 0x6b6f2d8700000000, 0xab3f101700000000, 0xed8da48700000000, + 0x2ddd991700000000, 0x6e2cdd1700000000, 0xae7ce08700000000, + 0xf044731500000000, 0x30144e8500000000, 0x73e50a8500000000, + 0xb3b5371500000000, 0xf507838500000000, 0x3557be1500000000, + 0x76a6fa1500000000, 0xb6f6c78500000000, 0xf9c2908400000000, + 0x3992ad1400000000, 0x7a63e91400000000, 0xba33d48400000000, + 0xfc81601400000000, 0x3cd15d8400000000, 0x7f20198400000000, + 0xbf70241400000000}, + {0x0000000000000000, 0x50fd906c00000000, 0xa0fa21d900000000, + 0xf007b1b500000000, 0x43f5400200000000, 0x1308d06e00000000, + 0xe30f61db00000000, 0xb3f2f1b700000000, 0x86ea810400000000, + 0xd617116800000000, 0x2610a0dd00000000, 0x76ed30b100000000, + 0xc51fc10600000000, 0x95e2516a00000000, 0x65e5e0df00000000, + 0x351870b300000000, 0x0cd5030900000000, 0x5c28936500000000, + 0xac2f22d000000000, 0xfcd2b2bc00000000, 0x4f20430b00000000, + 0x1fddd36700000000, 0xefda62d200000000, 0xbf27f2be00000000, + 0x8a3f820d00000000, 0xdac2126100000000, 0x2ac5a3d400000000, + 0x7a3833b800000000, 0xc9cac20f00000000, 0x9937526300000000, + 0x6930e3d600000000, 0x39cd73ba00000000, 0x18aa071200000000, + 0x4857977e00000000, 0xb85026cb00000000, 0xe8adb6a700000000, + 0x5b5f471000000000, 0x0ba2d77c00000000, 0xfba566c900000000, + 0xab58f6a500000000, 0x9e40861600000000, 0xcebd167a00000000, + 0x3ebaa7cf00000000, 0x6e4737a300000000, 0xddb5c61400000000, + 0x8d48567800000000, 0x7d4fe7cd00000000, 0x2db277a100000000, + 0x147f041b00000000, 0x4482947700000000, 0xb48525c200000000, + 0xe478b5ae00000000, 0x578a441900000000, 0x0777d47500000000, + 0xf77065c000000000, 0xa78df5ac00000000, 0x9295851f00000000, + 0xc268157300000000, 0x326fa4c600000000, 0x629234aa00000000, + 0xd160c51d00000000, 0x819d557100000000, 0x719ae4c400000000, + 0x216774a800000000, 0x30540f2400000000, 0x60a99f4800000000, + 0x90ae2efd00000000, 0xc053be9100000000, 0x73a14f2600000000, + 0x235cdf4a00000000, 0xd35b6eff00000000, 0x83a6fe9300000000, + 0xb6be8e2000000000, 0xe6431e4c00000000, 0x1644aff900000000, + 0x46b93f9500000000, 0xf54bce2200000000, 0xa5b65e4e00000000, + 0x55b1effb00000000, 0x054c7f9700000000, 0x3c810c2d00000000, + 0x6c7c9c4100000000, 0x9c7b2df400000000, 0xcc86bd9800000000, + 0x7f744c2f00000000, 0x2f89dc4300000000, 0xdf8e6df600000000, + 0x8f73fd9a00000000, 0xba6b8d2900000000, 0xea961d4500000000, + 0x1a91acf000000000, 0x4a6c3c9c00000000, 0xf99ecd2b00000000, + 0xa9635d4700000000, 0x5964ecf200000000, 0x09997c9e00000000, + 0x28fe083600000000, 0x7803985a00000000, 0x880429ef00000000, + 0xd8f9b98300000000, 0x6b0b483400000000, 0x3bf6d85800000000, + 0xcbf169ed00000000, 0x9b0cf98100000000, 0xae14893200000000, + 0xfee9195e00000000, 0x0eeea8eb00000000, 0x5e13388700000000, + 0xede1c93000000000, 0xbd1c595c00000000, 0x4d1be8e900000000, + 0x1de6788500000000, 0x242b0b3f00000000, 0x74d69b5300000000, + 0x84d12ae600000000, 0xd42cba8a00000000, 0x67de4b3d00000000, + 0x3723db5100000000, 0xc7246ae400000000, 0x97d9fa8800000000, + 0xa2c18a3b00000000, 0xf23c1a5700000000, 0x023babe200000000, + 0x52c63b8e00000000, 0xe134ca3900000000, 0xb1c95a5500000000, + 0x41ceebe000000000, 0x11337b8c00000000, 0x60a81e4800000000, + 0x30558e2400000000, 0xc0523f9100000000, 0x90afaffd00000000, + 0x235d5e4a00000000, 0x73a0ce2600000000, 0x83a77f9300000000, + 0xd35aefff00000000, 0xe6429f4c00000000, 0xb6bf0f2000000000, + 0x46b8be9500000000, 0x16452ef900000000, 0xa5b7df4e00000000, + 0xf54a4f2200000000, 0x054dfe9700000000, 0x55b06efb00000000, + 0x6c7d1d4100000000, 0x3c808d2d00000000, 0xcc873c9800000000, + 0x9c7aacf400000000, 0x2f885d4300000000, 0x7f75cd2f00000000, + 0x8f727c9a00000000, 0xdf8fecf600000000, 0xea979c4500000000, + 0xba6a0c2900000000, 0x4a6dbd9c00000000, 0x1a902df000000000, + 0xa962dc4700000000, 0xf99f4c2b00000000, 0x0998fd9e00000000, + 0x59656df200000000, 0x7802195a00000000, 0x28ff893600000000, + 0xd8f8388300000000, 0x8805a8ef00000000, 0x3bf7595800000000, + 0x6b0ac93400000000, 0x9b0d788100000000, 0xcbf0e8ed00000000, + 0xfee8985e00000000, 0xae15083200000000, 0x5e12b98700000000, + 0x0eef29eb00000000, 0xbd1dd85c00000000, 0xede0483000000000, + 0x1de7f98500000000, 0x4d1a69e900000000, 0x74d71a5300000000, + 0x242a8a3f00000000, 0xd42d3b8a00000000, 0x84d0abe600000000, + 0x37225a5100000000, 0x67dfca3d00000000, 0x97d87b8800000000, + 0xc725ebe400000000, 0xf23d9b5700000000, 0xa2c00b3b00000000, + 0x52c7ba8e00000000, 0x023a2ae200000000, 0xb1c8db5500000000, + 0xe1354b3900000000, 0x1132fa8c00000000, 0x41cf6ae000000000, + 0x50fc116c00000000, 0x0001810000000000, 0xf00630b500000000, + 0xa0fba0d900000000, 0x1309516e00000000, 0x43f4c10200000000, + 0xb3f370b700000000, 0xe30ee0db00000000, 0xd616906800000000, + 0x86eb000400000000, 0x76ecb1b100000000, 0x261121dd00000000, + 0x95e3d06a00000000, 0xc51e400600000000, 0x3519f1b300000000, + 0x65e461df00000000, 0x5c29126500000000, 0x0cd4820900000000, + 0xfcd333bc00000000, 0xac2ea3d000000000, 0x1fdc526700000000, + 0x4f21c20b00000000, 0xbf2673be00000000, 0xefdbe3d200000000, + 0xdac3936100000000, 0x8a3e030d00000000, 0x7a39b2b800000000, + 0x2ac422d400000000, 0x9936d36300000000, 0xc9cb430f00000000, + 0x39ccf2ba00000000, 0x693162d600000000, 0x4856167e00000000, + 0x18ab861200000000, 0xe8ac37a700000000, 0xb851a7cb00000000, + 0x0ba3567c00000000, 0x5b5ec61000000000, 0xab5977a500000000, + 0xfba4e7c900000000, 0xcebc977a00000000, 0x9e41071600000000, + 0x6e46b6a300000000, 0x3ebb26cf00000000, 0x8d49d77800000000, + 0xddb4471400000000, 0x2db3f6a100000000, 0x7d4e66cd00000000, + 0x4483157700000000, 0x147e851b00000000, 0xe47934ae00000000, + 0xb484a4c200000000, 0x0776557500000000, 0x578bc51900000000, + 0xa78c74ac00000000, 0xf771e4c000000000, 0xc269947300000000, + 0x9294041f00000000, 0x6293b5aa00000000, 0x326e25c600000000, + 0x819cd47100000000, 0xd161441d00000000, 0x2166f5a800000000, + 0x719b65c400000000}, + {0x0000000000000000, 0xfdc06c2d00000000, 0xfa81d95a00000000, + 0x0741b57700000000, 0xf403b3b500000000, 0x09c3df9800000000, + 0x0e826aef00000000, 0xf34206c200000000, 0xeb0765db00000000, + 0x16c709f600000000, 0x1186bc8100000000, 0xec46d0ac00000000, + 0x1f04d66e00000000, 0xe2c4ba4300000000, 0xe5850f3400000000, + 0x1845631900000000, 0xd50fc90600000000, 0x28cfa52b00000000, + 0x2f8e105c00000000, 0xd24e7c7100000000, 0x210c7ab300000000, + 0xdccc169e00000000, 0xdb8da3e900000000, 0x264dcfc400000000, + 0x3e08acdd00000000, 0xc3c8c0f000000000, 0xc489758700000000, + 0x394919aa00000000, 0xca0b1f6800000000, 0x37cb734500000000, + 0x308ac63200000000, 0xcd4aaa1f00000000, 0xaa1f920d00000000, + 0x57dffe2000000000, 0x509e4b5700000000, 0xad5e277a00000000, + 0x5e1c21b800000000, 0xa3dc4d9500000000, 0xa49df8e200000000, + 0x595d94cf00000000, 0x4118f7d600000000, 0xbcd89bfb00000000, + 0xbb992e8c00000000, 0x465942a100000000, 0xb51b446300000000, + 0x48db284e00000000, 0x4f9a9d3900000000, 0xb25af11400000000, + 0x7f105b0b00000000, 0x82d0372600000000, 0x8591825100000000, + 0x7851ee7c00000000, 0x8b13e8be00000000, 0x76d3849300000000, + 0x719231e400000000, 0x8c525dc900000000, 0x94173ed000000000, + 0x69d752fd00000000, 0x6e96e78a00000000, 0x93568ba700000000, + 0x60148d6500000000, 0x9dd4e14800000000, 0x9a95543f00000000, + 0x6755381200000000, 0x543f241b00000000, 0xa9ff483600000000, + 0xaebefd4100000000, 0x537e916c00000000, 0xa03c97ae00000000, + 0x5dfcfb8300000000, 0x5abd4ef400000000, 0xa77d22d900000000, + 0xbf3841c000000000, 0x42f82ded00000000, 0x45b9989a00000000, + 0xb879f4b700000000, 0x4b3bf27500000000, 0xb6fb9e5800000000, + 0xb1ba2b2f00000000, 0x4c7a470200000000, 0x8130ed1d00000000, + 0x7cf0813000000000, 0x7bb1344700000000, 0x8671586a00000000, + 0x75335ea800000000, 0x88f3328500000000, 0x8fb287f200000000, + 0x7272ebdf00000000, 0x6a3788c600000000, 0x97f7e4eb00000000, + 0x90b6519c00000000, 0x6d763db100000000, 0x9e343b7300000000, + 0x63f4575e00000000, 0x64b5e22900000000, 0x99758e0400000000, + 0xfe20b61600000000, 0x03e0da3b00000000, 0x04a16f4c00000000, + 0xf961036100000000, 0x0a2305a300000000, 0xf7e3698e00000000, + 0xf0a2dcf900000000, 0x0d62b0d400000000, 0x1527d3cd00000000, + 0xe8e7bfe000000000, 0xefa60a9700000000, 0x126666ba00000000, + 0xe124607800000000, 0x1ce40c5500000000, 0x1ba5b92200000000, + 0xe665d50f00000000, 0x2b2f7f1000000000, 0xd6ef133d00000000, + 0xd1aea64a00000000, 0x2c6eca6700000000, 0xdf2ccca500000000, + 0x22eca08800000000, 0x25ad15ff00000000, 0xd86d79d200000000, + 0xc0281acb00000000, 0x3de876e600000000, 0x3aa9c39100000000, + 0xc769afbc00000000, 0x342ba97e00000000, 0xc9ebc55300000000, + 0xceaa702400000000, 0x336a1c0900000000, 0xa87e483600000000, + 0x55be241b00000000, 0x52ff916c00000000, 0xaf3ffd4100000000, + 0x5c7dfb8300000000, 0xa1bd97ae00000000, 0xa6fc22d900000000, + 0x5b3c4ef400000000, 0x43792ded00000000, 0xbeb941c000000000, + 0xb9f8f4b700000000, 0x4438989a00000000, 0xb77a9e5800000000, + 0x4abaf27500000000, 0x4dfb470200000000, 0xb03b2b2f00000000, + 0x7d71813000000000, 0x80b1ed1d00000000, 0x87f0586a00000000, + 0x7a30344700000000, 0x8972328500000000, 0x74b25ea800000000, + 0x73f3ebdf00000000, 0x8e3387f200000000, 0x9676e4eb00000000, + 0x6bb688c600000000, 0x6cf73db100000000, 0x9137519c00000000, + 0x6275575e00000000, 0x9fb53b7300000000, 0x98f48e0400000000, + 0x6534e22900000000, 0x0261da3b00000000, 0xffa1b61600000000, + 0xf8e0036100000000, 0x05206f4c00000000, 0xf662698e00000000, + 0x0ba205a300000000, 0x0ce3b0d400000000, 0xf123dcf900000000, + 0xe966bfe000000000, 0x14a6d3cd00000000, 0x13e766ba00000000, + 0xee270a9700000000, 0x1d650c5500000000, 0xe0a5607800000000, + 0xe7e4d50f00000000, 0x1a24b92200000000, 0xd76e133d00000000, + 0x2aae7f1000000000, 0x2defca6700000000, 0xd02fa64a00000000, + 0x236da08800000000, 0xdeadcca500000000, 0xd9ec79d200000000, + 0x242c15ff00000000, 0x3c6976e600000000, 0xc1a91acb00000000, + 0xc6e8afbc00000000, 0x3b28c39100000000, 0xc86ac55300000000, + 0x35aaa97e00000000, 0x32eb1c0900000000, 0xcf2b702400000000, + 0xfc416c2d00000000, 0x0181000000000000, 0x06c0b57700000000, + 0xfb00d95a00000000, 0x0842df9800000000, 0xf582b3b500000000, + 0xf2c306c200000000, 0x0f036aef00000000, 0x174609f600000000, + 0xea8665db00000000, 0xedc7d0ac00000000, 0x1007bc8100000000, + 0xe345ba4300000000, 0x1e85d66e00000000, 0x19c4631900000000, + 0xe4040f3400000000, 0x294ea52b00000000, 0xd48ec90600000000, + 0xd3cf7c7100000000, 0x2e0f105c00000000, 0xdd4d169e00000000, + 0x208d7ab300000000, 0x27cccfc400000000, 0xda0ca3e900000000, + 0xc249c0f000000000, 0x3f89acdd00000000, 0x38c819aa00000000, + 0xc508758700000000, 0x364a734500000000, 0xcb8a1f6800000000, + 0xcccbaa1f00000000, 0x310bc63200000000, 0x565efe2000000000, + 0xab9e920d00000000, 0xacdf277a00000000, 0x511f4b5700000000, + 0xa25d4d9500000000, 0x5f9d21b800000000, 0x58dc94cf00000000, + 0xa51cf8e200000000, 0xbd599bfb00000000, 0x4099f7d600000000, + 0x47d842a100000000, 0xba182e8c00000000, 0x495a284e00000000, + 0xb49a446300000000, 0xb3dbf11400000000, 0x4e1b9d3900000000, + 0x8351372600000000, 0x7e915b0b00000000, 0x79d0ee7c00000000, + 0x8410825100000000, 0x7752849300000000, 0x8a92e8be00000000, + 0x8dd35dc900000000, 0x701331e400000000, 0x685652fd00000000, + 0x95963ed000000000, 0x92d78ba700000000, 0x6f17e78a00000000, + 0x9c55e14800000000, 0x61958d6500000000, 0x66d4381200000000, + 0x9b14543f00000000}, + {0x0000000000000000, 0xc1917ce100000000, 0x8123fa7200000000, + 0x40b2869300000000, 0x0247f4e500000000, 0xc3d6880400000000, + 0x83640e9700000000, 0x42f5727600000000, 0x078eeb7b00000000, + 0xc61f979a00000000, 0x86ad110900000000, 0x473c6de800000000, + 0x05c91f9e00000000, 0xc458637f00000000, 0x84eae5ec00000000, + 0x457b990d00000000, 0x0e1cd7f700000000, 0xcf8dab1600000000, + 0x8f3f2d8500000000, 0x4eae516400000000, 0x0c5b231200000000, + 0xcdca5ff300000000, 0x8d78d96000000000, 0x4ce9a58100000000, + 0x09923c8c00000000, 0xc803406d00000000, 0x88b1c6fe00000000, + 0x4920ba1f00000000, 0x0bd5c86900000000, 0xca44b48800000000, + 0x8af6321b00000000, 0x4b674efa00000000, 0x1f38ad5f00000000, + 0xdea9d1be00000000, 0x9e1b572d00000000, 0x5f8a2bcc00000000, + 0x1d7f59ba00000000, 0xdcee255b00000000, 0x9c5ca3c800000000, + 0x5dcddf2900000000, 0x18b6462400000000, 0xd9273ac500000000, + 0x9995bc5600000000, 0x5804c0b700000000, 0x1af1b2c100000000, + 0xdb60ce2000000000, 0x9bd248b300000000, 0x5a43345200000000, + 0x11247aa800000000, 0xd0b5064900000000, 0x900780da00000000, + 0x5196fc3b00000000, 0x13638e4d00000000, 0xd2f2f2ac00000000, + 0x9240743f00000000, 0x53d108de00000000, 0x16aa91d300000000, + 0xd73bed3200000000, 0x97896ba100000000, 0x5618174000000000, + 0x14ed653600000000, 0xd57c19d700000000, 0x95ce9f4400000000, + 0x545fe3a500000000, 0x3e705abf00000000, 0xffe1265e00000000, + 0xbf53a0cd00000000, 0x7ec2dc2c00000000, 0x3c37ae5a00000000, + 0xfda6d2bb00000000, 0xbd14542800000000, 0x7c8528c900000000, + 0x39feb1c400000000, 0xf86fcd2500000000, 0xb8dd4bb600000000, + 0x794c375700000000, 0x3bb9452100000000, 0xfa2839c000000000, + 0xba9abf5300000000, 0x7b0bc3b200000000, 0x306c8d4800000000, + 0xf1fdf1a900000000, 0xb14f773a00000000, 0x70de0bdb00000000, + 0x322b79ad00000000, 0xf3ba054c00000000, 0xb30883df00000000, + 0x7299ff3e00000000, 0x37e2663300000000, 0xf6731ad200000000, + 0xb6c19c4100000000, 0x7750e0a000000000, 0x35a592d600000000, + 0xf434ee3700000000, 0xb48668a400000000, 0x7517144500000000, + 0x2148f7e000000000, 0xe0d98b0100000000, 0xa06b0d9200000000, + 0x61fa717300000000, 0x230f030500000000, 0xe29e7fe400000000, + 0xa22cf97700000000, 0x63bd859600000000, 0x26c61c9b00000000, + 0xe757607a00000000, 0xa7e5e6e900000000, 0x66749a0800000000, + 0x2481e87e00000000, 0xe510949f00000000, 0xa5a2120c00000000, + 0x64336eed00000000, 0x2f54201700000000, 0xeec55cf600000000, + 0xae77da6500000000, 0x6fe6a68400000000, 0x2d13d4f200000000, + 0xec82a81300000000, 0xac302e8000000000, 0x6da1526100000000, + 0x28dacb6c00000000, 0xe94bb78d00000000, 0xa9f9311e00000000, + 0x68684dff00000000, 0x2a9d3f8900000000, 0xeb0c436800000000, + 0xabbec5fb00000000, 0x6a2fb91a00000000, 0x7fe0b7ce00000000, + 0xbe71cb2f00000000, 0xfec34dbc00000000, 0x3f52315d00000000, + 0x7da7432b00000000, 0xbc363fca00000000, 0xfc84b95900000000, + 0x3d15c5b800000000, 0x786e5cb500000000, 0xb9ff205400000000, + 0xf94da6c700000000, 0x38dcda2600000000, 0x7a29a85000000000, + 0xbbb8d4b100000000, 0xfb0a522200000000, 0x3a9b2ec300000000, + 0x71fc603900000000, 0xb06d1cd800000000, 0xf0df9a4b00000000, + 0x314ee6aa00000000, 0x73bb94dc00000000, 0xb22ae83d00000000, + 0xf2986eae00000000, 0x3309124f00000000, 0x76728b4200000000, + 0xb7e3f7a300000000, 0xf751713000000000, 0x36c00dd100000000, + 0x74357fa700000000, 0xb5a4034600000000, 0xf51685d500000000, + 0x3487f93400000000, 0x60d81a9100000000, 0xa149667000000000, + 0xe1fbe0e300000000, 0x206a9c0200000000, 0x629fee7400000000, + 0xa30e929500000000, 0xe3bc140600000000, 0x222d68e700000000, + 0x6756f1ea00000000, 0xa6c78d0b00000000, 0xe6750b9800000000, + 0x27e4777900000000, 0x6511050f00000000, 0xa48079ee00000000, + 0xe432ff7d00000000, 0x25a3839c00000000, 0x6ec4cd6600000000, + 0xaf55b18700000000, 0xefe7371400000000, 0x2e764bf500000000, + 0x6c83398300000000, 0xad12456200000000, 0xeda0c3f100000000, + 0x2c31bf1000000000, 0x694a261d00000000, 0xa8db5afc00000000, + 0xe869dc6f00000000, 0x29f8a08e00000000, 0x6b0dd2f800000000, + 0xaa9cae1900000000, 0xea2e288a00000000, 0x2bbf546b00000000, + 0x4190ed7100000000, 0x8001919000000000, 0xc0b3170300000000, + 0x01226be200000000, 0x43d7199400000000, 0x8246657500000000, + 0xc2f4e3e600000000, 0x03659f0700000000, 0x461e060a00000000, + 0x878f7aeb00000000, 0xc73dfc7800000000, 0x06ac809900000000, + 0x4459f2ef00000000, 0x85c88e0e00000000, 0xc57a089d00000000, + 0x04eb747c00000000, 0x4f8c3a8600000000, 0x8e1d466700000000, + 0xceafc0f400000000, 0x0f3ebc1500000000, 0x4dcbce6300000000, + 0x8c5ab28200000000, 0xcce8341100000000, 0x0d7948f000000000, + 0x4802d1fd00000000, 0x8993ad1c00000000, 0xc9212b8f00000000, + 0x08b0576e00000000, 0x4a45251800000000, 0x8bd459f900000000, + 0xcb66df6a00000000, 0x0af7a38b00000000, 0x5ea8402e00000000, + 0x9f393ccf00000000, 0xdf8bba5c00000000, 0x1e1ac6bd00000000, + 0x5cefb4cb00000000, 0x9d7ec82a00000000, 0xddcc4eb900000000, + 0x1c5d325800000000, 0x5926ab5500000000, 0x98b7d7b400000000, + 0xd805512700000000, 0x19942dc600000000, 0x5b615fb000000000, + 0x9af0235100000000, 0xda42a5c200000000, 0x1bd3d92300000000, + 0x50b497d900000000, 0x9125eb3800000000, 0xd1976dab00000000, + 0x1006114a00000000, 0x52f3633c00000000, 0x93621fdd00000000, + 0xd3d0994e00000000, 0x1241e5af00000000, 0x573a7ca200000000, + 0x96ab004300000000, 0xd61986d000000000, 0x1788fa3100000000, + 0x557d884700000000, 0x94ecf4a600000000, 0xd45e723500000000, + 0x15cf0ed400000000}}; + +#else /* W == 4 */ + +static const crc_t crc_braid_table[][256] = { + {0x00000000, 0x47596181, 0x8eb2c302, 0xc9eba283, 0xad668607, + 0xea3fe786, 0x23d44505, 0x648d2484, 0xeace0c0d, 0xad976d8c, + 0x647ccf0f, 0x2325ae8e, 0x47a88a0a, 0x00f1eb8b, 0xc91a4908, + 0x8e432889, 0x659f1819, 0x22c67998, 0xeb2ddb1b, 0xac74ba9a, + 0xc8f99e1e, 0x8fa0ff9f, 0x464b5d1c, 0x01123c9d, 0x8f511414, + 0xc8087595, 0x01e3d716, 0x46bab697, 0x22379213, 0x656ef392, + 0xac855111, 0xebdc3090, 0xcb3e3032, 0x8c6751b3, 0x458cf330, + 0x02d592b1, 0x6658b635, 0x2101d7b4, 0xe8ea7537, 0xafb314b6, + 0x21f03c3f, 0x66a95dbe, 0xaf42ff3d, 0xe81b9ebc, 0x8c96ba38, + 0xcbcfdbb9, 0x0224793a, 0x457d18bb, 0xaea1282b, 0xe9f849aa, + 0x2013eb29, 0x674a8aa8, 0x03c7ae2c, 0x449ecfad, 0x8d756d2e, + 0xca2c0caf, 0x446f2426, 0x033645a7, 0xcadde724, 0x8d8486a5, + 0xe909a221, 0xae50c3a0, 0x67bb6123, 0x20e200a2, 0x267f6067, + 0x612601e6, 0xa8cda365, 0xef94c2e4, 0x8b19e660, 0xcc4087e1, + 0x05ab2562, 0x42f244e3, 0xccb16c6a, 0x8be80deb, 0x4203af68, + 0x055acee9, 0x61d7ea6d, 0x268e8bec, 0xef65296f, 0xa83c48ee, + 0x43e0787e, 0x04b919ff, 0xcd52bb7c, 0x8a0bdafd, 0xee86fe79, + 0xa9df9ff8, 0x60343d7b, 0x276d5cfa, 0xa92e7473, 0xee7715f2, + 0x279cb771, 0x60c5d6f0, 0x0448f274, 0x431193f5, 0x8afa3176, + 0xcda350f7, 0xed415055, 0xaa1831d4, 0x63f39357, 0x24aaf2d6, + 0x4027d652, 0x077eb7d3, 0xce951550, 0x89cc74d1, 0x078f5c58, + 0x40d63dd9, 0x893d9f5a, 0xce64fedb, 0xaae9da5f, 0xedb0bbde, + 0x245b195d, 0x630278dc, 0x88de484c, 0xcf8729cd, 0x066c8b4e, + 0x4135eacf, 0x25b8ce4b, 0x62e1afca, 0xab0a0d49, 0xec536cc8, + 0x62104441, 0x254925c0, 0xeca28743, 0xabfbe6c2, 0xcf76c246, + 0x882fa3c7, 0x41c40144, 0x069d60c5, 0x4cfec0ce, 0x0ba7a14f, + 0xc24c03cc, 0x8515624d, 0xe19846c9, 0xa6c12748, 0x6f2a85cb, + 0x2873e44a, 0xa630ccc3, 0xe169ad42, 0x28820fc1, 0x6fdb6e40, + 0x0b564ac4, 0x4c0f2b45, 0x85e489c6, 0xc2bde847, 0x2961d8d7, + 0x6e38b956, 0xa7d31bd5, 0xe08a7a54, 0x84075ed0, 0xc35e3f51, + 0x0ab59dd2, 0x4decfc53, 0xc3afd4da, 0x84f6b55b, 0x4d1d17d8, + 0x0a447659, 0x6ec952dd, 0x2990335c, 0xe07b91df, 0xa722f05e, + 0x87c0f0fc, 0xc099917d, 0x097233fe, 0x4e2b527f, 0x2aa676fb, + 0x6dff177a, 0xa414b5f9, 0xe34dd478, 0x6d0efcf1, 0x2a579d70, + 0xe3bc3ff3, 0xa4e55e72, 0xc0687af6, 0x87311b77, 0x4edab9f4, + 0x0983d875, 0xe25fe8e5, 0xa5068964, 0x6ced2be7, 0x2bb44a66, + 0x4f396ee2, 0x08600f63, 0xc18bade0, 0x86d2cc61, 0x0891e4e8, + 0x4fc88569, 0x862327ea, 0xc17a466b, 0xa5f762ef, 0xe2ae036e, + 0x2b45a1ed, 0x6c1cc06c, 0x6a81a0a9, 0x2dd8c128, 0xe43363ab, + 0xa36a022a, 0xc7e726ae, 0x80be472f, 0x4955e5ac, 0x0e0c842d, + 0x804faca4, 0xc716cd25, 0x0efd6fa6, 0x49a40e27, 0x2d292aa3, + 0x6a704b22, 0xa39be9a1, 0xe4c28820, 0x0f1eb8b0, 0x4847d931, + 0x81ac7bb2, 0xc6f51a33, 0xa2783eb7, 0xe5215f36, 0x2ccafdb5, + 0x6b939c34, 0xe5d0b4bd, 0xa289d53c, 0x6b6277bf, 0x2c3b163e, + 0x48b632ba, 0x0fef533b, 0xc604f1b8, 0x815d9039, 0xa1bf909b, + 0xe6e6f11a, 0x2f0d5399, 0x68543218, 0x0cd9169c, 0x4b80771d, + 0x826bd59e, 0xc532b41f, 0x4b719c96, 0x0c28fd17, 0xc5c35f94, + 0x829a3e15, 0xe6171a91, 0xa14e7b10, 0x68a5d993, 0x2ffcb812, + 0xc4208882, 0x8379e903, 0x4a924b80, 0x0dcb2a01, 0x69460e85, + 0x2e1f6f04, 0xe7f4cd87, 0xa0adac06, 0x2eee848f, 0x69b7e50e, + 0xa05c478d, 0xe705260c, 0x83880288, 0xc4d16309, 0x0d3ac18a, + 0x4a63a00b}, + {0x00000000, 0x99fd819c, 0x83f8033b, 0x1a0582a7, 0xb7f30675, + 0x2e0e87e9, 0x340b054e, 0xadf684d2, 0xdfe50ce9, 0x46188d75, + 0x5c1d0fd2, 0xc5e08e4e, 0x68160a9c, 0xf1eb8b00, 0xebee09a7, + 0x7213883b, 0x0fc919d1, 0x9634984d, 0x8c311aea, 0x15cc9b76, + 0xb83a1fa4, 0x21c79e38, 0x3bc21c9f, 0xa23f9d03, 0xd02c1538, + 0x49d194a4, 0x53d41603, 0xca29979f, 0x67df134d, 0xfe2292d1, + 0xe4271076, 0x7dda91ea, 0x1f9233a2, 0x866fb23e, 0x9c6a3099, + 0x0597b105, 0xa86135d7, 0x319cb44b, 0x2b9936ec, 0xb264b770, + 0xc0773f4b, 0x598abed7, 0x438f3c70, 0xda72bdec, 0x7784393e, + 0xee79b8a2, 0xf47c3a05, 0x6d81bb99, 0x105b2a73, 0x89a6abef, + 0x93a32948, 0x0a5ea8d4, 0xa7a82c06, 0x3e55ad9a, 0x24502f3d, + 0xbdadaea1, 0xcfbe269a, 0x5643a706, 0x4c4625a1, 0xd5bba43d, + 0x784d20ef, 0xe1b0a173, 0xfbb523d4, 0x6248a248, 0x3f246744, + 0xa6d9e6d8, 0xbcdc647f, 0x2521e5e3, 0x88d76131, 0x112ae0ad, + 0x0b2f620a, 0x92d2e396, 0xe0c16bad, 0x793cea31, 0x63396896, + 0xfac4e90a, 0x57326dd8, 0xcecfec44, 0xd4ca6ee3, 0x4d37ef7f, + 0x30ed7e95, 0xa910ff09, 0xb3157dae, 0x2ae8fc32, 0x871e78e0, + 0x1ee3f97c, 0x04e67bdb, 0x9d1bfa47, 0xef08727c, 0x76f5f3e0, + 0x6cf07147, 0xf50df0db, 0x58fb7409, 0xc106f595, 0xdb037732, + 0x42fef6ae, 0x20b654e6, 0xb94bd57a, 0xa34e57dd, 0x3ab3d641, + 0x97455293, 0x0eb8d30f, 0x14bd51a8, 0x8d40d034, 0xff53580f, + 0x66aed993, 0x7cab5b34, 0xe556daa8, 0x48a05e7a, 0xd15ddfe6, + 0xcb585d41, 0x52a5dcdd, 0x2f7f4d37, 0xb682ccab, 0xac874e0c, + 0x357acf90, 0x988c4b42, 0x0171cade, 0x1b744879, 0x8289c9e5, + 0xf09a41de, 0x6967c042, 0x736242e5, 0xea9fc379, 0x476947ab, + 0xde94c637, 0xc4914490, 0x5d6cc50c, 0x7e48ce88, 0xe7b54f14, + 0xfdb0cdb3, 0x644d4c2f, 0xc9bbc8fd, 0x50464961, 0x4a43cbc6, + 0xd3be4a5a, 0xa1adc261, 0x385043fd, 0x2255c15a, 0xbba840c6, + 0x165ec414, 0x8fa34588, 0x95a6c72f, 0x0c5b46b3, 0x7181d759, + 0xe87c56c5, 0xf279d462, 0x6b8455fe, 0xc672d12c, 0x5f8f50b0, + 0x458ad217, 0xdc77538b, 0xae64dbb0, 0x37995a2c, 0x2d9cd88b, + 0xb4615917, 0x1997ddc5, 0x806a5c59, 0x9a6fdefe, 0x03925f62, + 0x61dafd2a, 0xf8277cb6, 0xe222fe11, 0x7bdf7f8d, 0xd629fb5f, + 0x4fd47ac3, 0x55d1f864, 0xcc2c79f8, 0xbe3ff1c3, 0x27c2705f, + 0x3dc7f2f8, 0xa43a7364, 0x09ccf7b6, 0x9031762a, 0x8a34f48d, + 0x13c97511, 0x6e13e4fb, 0xf7ee6567, 0xedebe7c0, 0x7416665c, + 0xd9e0e28e, 0x401d6312, 0x5a18e1b5, 0xc3e56029, 0xb1f6e812, + 0x280b698e, 0x320eeb29, 0xabf36ab5, 0x0605ee67, 0x9ff86ffb, + 0x85fded5c, 0x1c006cc0, 0x416ca9cc, 0xd8912850, 0xc294aaf7, + 0x5b692b6b, 0xf69fafb9, 0x6f622e25, 0x7567ac82, 0xec9a2d1e, + 0x9e89a525, 0x077424b9, 0x1d71a61e, 0x848c2782, 0x297aa350, + 0xb08722cc, 0xaa82a06b, 0x337f21f7, 0x4ea5b01d, 0xd7583181, + 0xcd5db326, 0x54a032ba, 0xf956b668, 0x60ab37f4, 0x7aaeb553, + 0xe35334cf, 0x9140bcf4, 0x08bd3d68, 0x12b8bfcf, 0x8b453e53, + 0x26b3ba81, 0xbf4e3b1d, 0xa54bb9ba, 0x3cb63826, 0x5efe9a6e, + 0xc7031bf2, 0xdd069955, 0x44fb18c9, 0xe90d9c1b, 0x70f01d87, + 0x6af59f20, 0xf3081ebc, 0x811b9687, 0x18e6171b, 0x02e395bc, + 0x9b1e1420, 0x36e890f2, 0xaf15116e, 0xb51093c9, 0x2ced1255, + 0x513783bf, 0xc8ca0223, 0xd2cf8084, 0x4b320118, 0xe6c485ca, + 0x7f390456, 0x653c86f1, 0xfcc1076d, 0x8ed28f56, 0x172f0eca, + 0x0d2a8c6d, 0x94d70df1, 0x39218923, 0xa0dc08bf, 0xbad98a18, + 0x23240b84}, + {0x00000000, 0xfc919d10, 0x49203a23, 0xb5b1a733, 0x92407446, + 0x6ed1e956, 0xdb604e65, 0x27f1d375, 0x9483e88f, 0x6812759f, + 0xdda3d2ac, 0x21324fbc, 0x06c39cc9, 0xfa5201d9, 0x4fe3a6ea, + 0xb3723bfa, 0x9904d11d, 0x65954c0d, 0xd024eb3e, 0x2cb5762e, + 0x0b44a55b, 0xf7d5384b, 0x42649f78, 0xbef50268, 0x0d873992, + 0xf116a482, 0x44a703b1, 0xb8369ea1, 0x9fc74dd4, 0x6356d0c4, + 0xd6e777f7, 0x2a76eae7, 0x820aa239, 0x7e9b3f29, 0xcb2a981a, + 0x37bb050a, 0x104ad67f, 0xecdb4b6f, 0x596aec5c, 0xa5fb714c, + 0x16894ab6, 0xea18d7a6, 0x5fa97095, 0xa338ed85, 0x84c93ef0, + 0x7858a3e0, 0xcde904d3, 0x317899c3, 0x1b0e7324, 0xe79fee34, + 0x522e4907, 0xaebfd417, 0x894e0762, 0x75df9a72, 0xc06e3d41, + 0x3cffa051, 0x8f8d9bab, 0x731c06bb, 0xc6ada188, 0x3a3c3c98, + 0x1dcdefed, 0xe15c72fd, 0x54edd5ce, 0xa87c48de, 0xb4164471, + 0x4887d961, 0xfd367e52, 0x01a7e342, 0x26563037, 0xdac7ad27, + 0x6f760a14, 0x93e79704, 0x2095acfe, 0xdc0431ee, 0x69b596dd, + 0x95240bcd, 0xb2d5d8b8, 0x4e4445a8, 0xfbf5e29b, 0x07647f8b, + 0x2d12956c, 0xd183087c, 0x6432af4f, 0x98a3325f, 0xbf52e12a, + 0x43c37c3a, 0xf672db09, 0x0ae34619, 0xb9917de3, 0x4500e0f3, + 0xf0b147c0, 0x0c20dad0, 0x2bd109a5, 0xd74094b5, 0x62f13386, + 0x9e60ae96, 0x361ce648, 0xca8d7b58, 0x7f3cdc6b, 0x83ad417b, + 0xa45c920e, 0x58cd0f1e, 0xed7ca82d, 0x11ed353d, 0xa29f0ec7, + 0x5e0e93d7, 0xebbf34e4, 0x172ea9f4, 0x30df7a81, 0xcc4ee791, + 0x79ff40a2, 0x856eddb2, 0xaf183755, 0x5389aa45, 0xe6380d76, + 0x1aa99066, 0x3d584313, 0xc1c9de03, 0x74787930, 0x88e9e420, + 0x3b9bdfda, 0xc70a42ca, 0x72bbe5f9, 0x8e2a78e9, 0xa9dbab9c, + 0x554a368c, 0xe0fb91bf, 0x1c6a0caf, 0xd82f88e1, 0x24be15f1, + 0x910fb2c2, 0x6d9e2fd2, 0x4a6ffca7, 0xb6fe61b7, 0x034fc684, + 0xffde5b94, 0x4cac606e, 0xb03dfd7e, 0x058c5a4d, 0xf91dc75d, + 0xdeec1428, 0x227d8938, 0x97cc2e0b, 0x6b5db31b, 0x412b59fc, + 0xbdbac4ec, 0x080b63df, 0xf49afecf, 0xd36b2dba, 0x2ffab0aa, + 0x9a4b1799, 0x66da8a89, 0xd5a8b173, 0x29392c63, 0x9c888b50, + 0x60191640, 0x47e8c535, 0xbb795825, 0x0ec8ff16, 0xf2596206, + 0x5a252ad8, 0xa6b4b7c8, 0x130510fb, 0xef948deb, 0xc8655e9e, + 0x34f4c38e, 0x814564bd, 0x7dd4f9ad, 0xcea6c257, 0x32375f47, + 0x8786f874, 0x7b176564, 0x5ce6b611, 0xa0772b01, 0x15c68c32, + 0xe9571122, 0xc321fbc5, 0x3fb066d5, 0x8a01c1e6, 0x76905cf6, + 0x51618f83, 0xadf01293, 0x1841b5a0, 0xe4d028b0, 0x57a2134a, + 0xab338e5a, 0x1e822969, 0xe213b479, 0xc5e2670c, 0x3973fa1c, + 0x8cc25d2f, 0x7053c03f, 0x6c39cc90, 0x90a85180, 0x2519f6b3, + 0xd9886ba3, 0xfe79b8d6, 0x02e825c6, 0xb75982f5, 0x4bc81fe5, + 0xf8ba241f, 0x042bb90f, 0xb19a1e3c, 0x4d0b832c, 0x6afa5059, + 0x966bcd49, 0x23da6a7a, 0xdf4bf76a, 0xf53d1d8d, 0x09ac809d, + 0xbc1d27ae, 0x408cbabe, 0x677d69cb, 0x9becf4db, 0x2e5d53e8, + 0xd2cccef8, 0x61bef502, 0x9d2f6812, 0x289ecf21, 0xd40f5231, + 0xf3fe8144, 0x0f6f1c54, 0xbadebb67, 0x464f2677, 0xee336ea9, + 0x12a2f3b9, 0xa713548a, 0x5b82c99a, 0x7c731aef, 0x80e287ff, + 0x355320cc, 0xc9c2bddc, 0x7ab08626, 0x86211b36, 0x3390bc05, + 0xcf012115, 0xe8f0f260, 0x14616f70, 0xa1d0c843, 0x5d415553, + 0x7737bfb4, 0x8ba622a4, 0x3e178597, 0xc2861887, 0xe577cbf2, + 0x19e656e2, 0xac57f1d1, 0x50c66cc1, 0xe3b4573b, 0x1f25ca2b, + 0xaa946d18, 0x5605f008, 0x71f4237d, 0x8d65be6d, 0x38d4195e, + 0xc445844e}, + {0x00000000, 0x005c11c1, 0x00b82382, 0x00e43243, 0x01704704, + 0x012c56c5, 0x01c86486, 0x01947547, 0x02e08e08, 0x02bc9fc9, + 0x0258ad8a, 0x0204bc4b, 0x0390c90c, 0x03ccd8cd, 0x0328ea8e, + 0x0374fb4f, 0x05c11c10, 0x059d0dd1, 0x05793f92, 0x05252e53, + 0x04b15b14, 0x04ed4ad5, 0x04097896, 0x04556957, 0x07219218, + 0x077d83d9, 0x0799b19a, 0x07c5a05b, 0x0651d51c, 0x060dc4dd, + 0x06e9f69e, 0x06b5e75f, 0x0b823820, 0x0bde29e1, 0x0b3a1ba2, + 0x0b660a63, 0x0af27f24, 0x0aae6ee5, 0x0a4a5ca6, 0x0a164d67, + 0x0962b628, 0x093ea7e9, 0x09da95aa, 0x0986846b, 0x0812f12c, + 0x084ee0ed, 0x08aad2ae, 0x08f6c36f, 0x0e432430, 0x0e1f35f1, + 0x0efb07b2, 0x0ea71673, 0x0f336334, 0x0f6f72f5, 0x0f8b40b6, + 0x0fd75177, 0x0ca3aa38, 0x0cffbbf9, 0x0c1b89ba, 0x0c47987b, + 0x0dd3ed3c, 0x0d8ffcfd, 0x0d6bcebe, 0x0d37df7f, 0x17047040, + 0x17586181, 0x17bc53c2, 0x17e04203, 0x16743744, 0x16282685, + 0x16cc14c6, 0x16900507, 0x15e4fe48, 0x15b8ef89, 0x155cddca, + 0x1500cc0b, 0x1494b94c, 0x14c8a88d, 0x142c9ace, 0x14708b0f, + 0x12c56c50, 0x12997d91, 0x127d4fd2, 0x12215e13, 0x13b52b54, + 0x13e93a95, 0x130d08d6, 0x13511917, 0x1025e258, 0x1079f399, + 0x109dc1da, 0x10c1d01b, 0x1155a55c, 0x1109b49d, 0x11ed86de, + 0x11b1971f, 0x1c864860, 0x1cda59a1, 0x1c3e6be2, 0x1c627a23, + 0x1df60f64, 0x1daa1ea5, 0x1d4e2ce6, 0x1d123d27, 0x1e66c668, + 0x1e3ad7a9, 0x1edee5ea, 0x1e82f42b, 0x1f16816c, 0x1f4a90ad, + 0x1faea2ee, 0x1ff2b32f, 0x19475470, 0x191b45b1, 0x19ff77f2, + 0x19a36633, 0x18371374, 0x186b02b5, 0x188f30f6, 0x18d32137, + 0x1ba7da78, 0x1bfbcbb9, 0x1b1ff9fa, 0x1b43e83b, 0x1ad79d7c, + 0x1a8b8cbd, 0x1a6fbefe, 0x1a33af3f, 0x2e08e080, 0x2e54f141, + 0x2eb0c302, 0x2eecd2c3, 0x2f78a784, 0x2f24b645, 0x2fc08406, + 0x2f9c95c7, 0x2ce86e88, 0x2cb47f49, 0x2c504d0a, 0x2c0c5ccb, + 0x2d98298c, 0x2dc4384d, 0x2d200a0e, 0x2d7c1bcf, 0x2bc9fc90, + 0x2b95ed51, 0x2b71df12, 0x2b2dced3, 0x2ab9bb94, 0x2ae5aa55, + 0x2a019816, 0x2a5d89d7, 0x29297298, 0x29756359, 0x2991511a, + 0x29cd40db, 0x2859359c, 0x2805245d, 0x28e1161e, 0x28bd07df, + 0x258ad8a0, 0x25d6c961, 0x2532fb22, 0x256eeae3, 0x24fa9fa4, + 0x24a68e65, 0x2442bc26, 0x241eade7, 0x276a56a8, 0x27364769, + 0x27d2752a, 0x278e64eb, 0x261a11ac, 0x2646006d, 0x26a2322e, + 0x26fe23ef, 0x204bc4b0, 0x2017d571, 0x20f3e732, 0x20aff6f3, + 0x213b83b4, 0x21679275, 0x2183a036, 0x21dfb1f7, 0x22ab4ab8, + 0x22f75b79, 0x2213693a, 0x224f78fb, 0x23db0dbc, 0x23871c7d, + 0x23632e3e, 0x233f3fff, 0x390c90c0, 0x39508101, 0x39b4b342, + 0x39e8a283, 0x387cd7c4, 0x3820c605, 0x38c4f446, 0x3898e587, + 0x3bec1ec8, 0x3bb00f09, 0x3b543d4a, 0x3b082c8b, 0x3a9c59cc, + 0x3ac0480d, 0x3a247a4e, 0x3a786b8f, 0x3ccd8cd0, 0x3c919d11, + 0x3c75af52, 0x3c29be93, 0x3dbdcbd4, 0x3de1da15, 0x3d05e856, + 0x3d59f997, 0x3e2d02d8, 0x3e711319, 0x3e95215a, 0x3ec9309b, + 0x3f5d45dc, 0x3f01541d, 0x3fe5665e, 0x3fb9779f, 0x328ea8e0, + 0x32d2b921, 0x32368b62, 0x326a9aa3, 0x33feefe4, 0x33a2fe25, + 0x3346cc66, 0x331adda7, 0x306e26e8, 0x30323729, 0x30d6056a, + 0x308a14ab, 0x311e61ec, 0x3142702d, 0x31a6426e, 0x31fa53af, + 0x374fb4f0, 0x3713a531, 0x37f79772, 0x37ab86b3, 0x363ff3f4, + 0x3663e235, 0x3687d076, 0x36dbc1b7, 0x35af3af8, 0x35f32b39, + 0x3517197a, 0x354b08bb, 0x34df7dfc, 0x34836c3d, 0x34675e7e, + 0x343b4fbf}}; + +static const word_t crc_braid_big_table[][256] = { + {0x00000000, 0xc1115c00, 0x8223b800, 0x4332e400, 0x04477001, + 0xc5562c01, 0x8664c801, 0x47759401, 0x088ee002, 0xc99fbc02, + 0x8aad5802, 0x4bbc0402, 0x0cc99003, 0xcdd8cc03, 0x8eea2803, + 0x4ffb7403, 0x101cc105, 0xd10d9d05, 0x923f7905, 0x532e2505, + 0x145bb104, 0xd54aed04, 0x96780904, 0x57695504, 0x18922107, + 0xd9837d07, 0x9ab19907, 0x5ba0c507, 0x1cd55106, 0xddc40d06, + 0x9ef6e906, 0x5fe7b506, 0x2038820b, 0xe129de0b, 0xa21b3a0b, + 0x630a660b, 0x247ff20a, 0xe56eae0a, 0xa65c4a0a, 0x674d160a, + 0x28b66209, 0xe9a73e09, 0xaa95da09, 0x6b848609, 0x2cf11208, + 0xede04e08, 0xaed2aa08, 0x6fc3f608, 0x3024430e, 0xf1351f0e, + 0xb207fb0e, 0x7316a70e, 0x3463330f, 0xf5726f0f, 0xb6408b0f, + 0x7751d70f, 0x38aaa30c, 0xf9bbff0c, 0xba891b0c, 0x7b98470c, + 0x3cedd30d, 0xfdfc8f0d, 0xbece6b0d, 0x7fdf370d, 0x40700417, + 0x81615817, 0xc253bc17, 0x0342e017, 0x44377416, 0x85262816, + 0xc614cc16, 0x07059016, 0x48fee415, 0x89efb815, 0xcadd5c15, + 0x0bcc0015, 0x4cb99414, 0x8da8c814, 0xce9a2c14, 0x0f8b7014, + 0x506cc512, 0x917d9912, 0xd24f7d12, 0x135e2112, 0x542bb513, + 0x953ae913, 0xd6080d13, 0x17195113, 0x58e22510, 0x99f37910, + 0xdac19d10, 0x1bd0c110, 0x5ca55511, 0x9db40911, 0xde86ed11, + 0x1f97b111, 0x6048861c, 0xa159da1c, 0xe26b3e1c, 0x237a621c, + 0x640ff61d, 0xa51eaa1d, 0xe62c4e1d, 0x273d121d, 0x68c6661e, + 0xa9d73a1e, 0xeae5de1e, 0x2bf4821e, 0x6c81161f, 0xad904a1f, + 0xeea2ae1f, 0x2fb3f21f, 0x70544719, 0xb1451b19, 0xf277ff19, + 0x3366a319, 0x74133718, 0xb5026b18, 0xf6308f18, 0x3721d318, + 0x78daa71b, 0xb9cbfb1b, 0xfaf91f1b, 0x3be8431b, 0x7c9dd71a, + 0xbd8c8b1a, 0xfebe6f1a, 0x3faf331a, 0x80e0082e, 0x41f1542e, + 0x02c3b02e, 0xc3d2ec2e, 0x84a7782f, 0x45b6242f, 0x0684c02f, + 0xc7959c2f, 0x886ee82c, 0x497fb42c, 0x0a4d502c, 0xcb5c0c2c, + 0x8c29982d, 0x4d38c42d, 0x0e0a202d, 0xcf1b7c2d, 0x90fcc92b, + 0x51ed952b, 0x12df712b, 0xd3ce2d2b, 0x94bbb92a, 0x55aae52a, + 0x1698012a, 0xd7895d2a, 0x98722929, 0x59637529, 0x1a519129, + 0xdb40cd29, 0x9c355928, 0x5d240528, 0x1e16e128, 0xdf07bd28, + 0xa0d88a25, 0x61c9d625, 0x22fb3225, 0xe3ea6e25, 0xa49ffa24, + 0x658ea624, 0x26bc4224, 0xe7ad1e24, 0xa8566a27, 0x69473627, + 0x2a75d227, 0xeb648e27, 0xac111a26, 0x6d004626, 0x2e32a226, + 0xef23fe26, 0xb0c44b20, 0x71d51720, 0x32e7f320, 0xf3f6af20, + 0xb4833b21, 0x75926721, 0x36a08321, 0xf7b1df21, 0xb84aab22, + 0x795bf722, 0x3a691322, 0xfb784f22, 0xbc0ddb23, 0x7d1c8723, + 0x3e2e6323, 0xff3f3f23, 0xc0900c39, 0x01815039, 0x42b3b439, + 0x83a2e839, 0xc4d77c38, 0x05c62038, 0x46f4c438, 0x87e59838, + 0xc81eec3b, 0x090fb03b, 0x4a3d543b, 0x8b2c083b, 0xcc599c3a, + 0x0d48c03a, 0x4e7a243a, 0x8f6b783a, 0xd08ccd3c, 0x119d913c, + 0x52af753c, 0x93be293c, 0xd4cbbd3d, 0x15dae13d, 0x56e8053d, + 0x97f9593d, 0xd8022d3e, 0x1913713e, 0x5a21953e, 0x9b30c93e, + 0xdc455d3f, 0x1d54013f, 0x5e66e53f, 0x9f77b93f, 0xe0a88e32, + 0x21b9d232, 0x628b3632, 0xa39a6a32, 0xe4effe33, 0x25fea233, + 0x66cc4633, 0xa7dd1a33, 0xe8266e30, 0x29373230, 0x6a05d630, + 0xab148a30, 0xec611e31, 0x2d704231, 0x6e42a631, 0xaf53fa31, + 0xf0b44f37, 0x31a51337, 0x7297f737, 0xb386ab37, 0xf4f33f36, + 0x35e26336, 0x76d08736, 0xb7c1db36, 0xf83aaf35, 0x392bf335, + 0x7a191735, 0xbb084b35, 0xfc7ddf34, 0x3d6c8334, 0x7e5e6734, + 0xbf4f3b34}, + {0x00000000, 0x109d91fc, 0x233a2049, 0x33a7b1b5, 0x46744092, + 0x56e9d16e, 0x654e60db, 0x75d3f127, 0x8fe88394, 0x9f751268, + 0xacd2a3dd, 0xbc4f3221, 0xc99cc306, 0xd90152fa, 0xeaa6e34f, + 0xfa3b72b3, 0x1dd10499, 0x0d4c9565, 0x3eeb24d0, 0x2e76b52c, + 0x5ba5440b, 0x4b38d5f7, 0x789f6442, 0x6802f5be, 0x9239870d, + 0x82a416f1, 0xb103a744, 0xa19e36b8, 0xd44dc79f, 0xc4d05663, + 0xf777e7d6, 0xe7ea762a, 0x39a20a82, 0x293f9b7e, 0x1a982acb, + 0x0a05bb37, 0x7fd64a10, 0x6f4bdbec, 0x5cec6a59, 0x4c71fba5, + 0xb64a8916, 0xa6d718ea, 0x9570a95f, 0x85ed38a3, 0xf03ec984, + 0xe0a35878, 0xd304e9cd, 0xc3997831, 0x24730e1b, 0x34ee9fe7, + 0x07492e52, 0x17d4bfae, 0x62074e89, 0x729adf75, 0x413d6ec0, + 0x51a0ff3c, 0xab9b8d8f, 0xbb061c73, 0x88a1adc6, 0x983c3c3a, + 0xedefcd1d, 0xfd725ce1, 0xced5ed54, 0xde487ca8, 0x714416b4, + 0x61d98748, 0x527e36fd, 0x42e3a701, 0x37305626, 0x27adc7da, + 0x140a766f, 0x0497e793, 0xfeac9520, 0xee3104dc, 0xdd96b569, + 0xcd0b2495, 0xb8d8d5b2, 0xa845444e, 0x9be2f5fb, 0x8b7f6407, + 0x6c95122d, 0x7c0883d1, 0x4faf3264, 0x5f32a398, 0x2ae152bf, + 0x3a7cc343, 0x09db72f6, 0x1946e30a, 0xe37d91b9, 0xf3e00045, + 0xc047b1f0, 0xd0da200c, 0xa509d12b, 0xb59440d7, 0x8633f162, + 0x96ae609e, 0x48e61c36, 0x587b8dca, 0x6bdc3c7f, 0x7b41ad83, + 0x0e925ca4, 0x1e0fcd58, 0x2da87ced, 0x3d35ed11, 0xc70e9fa2, + 0xd7930e5e, 0xe434bfeb, 0xf4a92e17, 0x817adf30, 0x91e74ecc, + 0xa240ff79, 0xb2dd6e85, 0x553718af, 0x45aa8953, 0x760d38e6, + 0x6690a91a, 0x1343583d, 0x03dec9c1, 0x30797874, 0x20e4e988, + 0xdadf9b3b, 0xca420ac7, 0xf9e5bb72, 0xe9782a8e, 0x9cabdba9, + 0x8c364a55, 0xbf91fbe0, 0xaf0c6a1c, 0xe1882fd8, 0xf115be24, + 0xc2b20f91, 0xd22f9e6d, 0xa7fc6f4a, 0xb761feb6, 0x84c64f03, + 0x945bdeff, 0x6e60ac4c, 0x7efd3db0, 0x4d5a8c05, 0x5dc71df9, + 0x2814ecde, 0x38897d22, 0x0b2ecc97, 0x1bb35d6b, 0xfc592b41, + 0xecc4babd, 0xdf630b08, 0xcffe9af4, 0xba2d6bd3, 0xaab0fa2f, + 0x99174b9a, 0x898ada66, 0x73b1a8d5, 0x632c3929, 0x508b889c, + 0x40161960, 0x35c5e847, 0x255879bb, 0x16ffc80e, 0x066259f2, + 0xd82a255a, 0xc8b7b4a6, 0xfb100513, 0xeb8d94ef, 0x9e5e65c8, + 0x8ec3f434, 0xbd644581, 0xadf9d47d, 0x57c2a6ce, 0x475f3732, + 0x74f88687, 0x6465177b, 0x11b6e65c, 0x012b77a0, 0x328cc615, + 0x221157e9, 0xc5fb21c3, 0xd566b03f, 0xe6c1018a, 0xf65c9076, + 0x838f6151, 0x9312f0ad, 0xa0b54118, 0xb028d0e4, 0x4a13a257, + 0x5a8e33ab, 0x6929821e, 0x79b413e2, 0x0c67e2c5, 0x1cfa7339, + 0x2f5dc28c, 0x3fc05370, 0x90cc396c, 0x8051a890, 0xb3f61925, + 0xa36b88d9, 0xd6b879fe, 0xc625e802, 0xf58259b7, 0xe51fc84b, + 0x1f24baf8, 0x0fb92b04, 0x3c1e9ab1, 0x2c830b4d, 0x5950fa6a, + 0x49cd6b96, 0x7a6ada23, 0x6af74bdf, 0x8d1d3df5, 0x9d80ac09, + 0xae271dbc, 0xbeba8c40, 0xcb697d67, 0xdbf4ec9b, 0xe8535d2e, + 0xf8ceccd2, 0x02f5be61, 0x12682f9d, 0x21cf9e28, 0x31520fd4, + 0x4481fef3, 0x541c6f0f, 0x67bbdeba, 0x77264f46, 0xa96e33ee, + 0xb9f3a212, 0x8a5413a7, 0x9ac9825b, 0xef1a737c, 0xff87e280, + 0xcc205335, 0xdcbdc2c9, 0x2686b07a, 0x361b2186, 0x05bc9033, + 0x152101cf, 0x60f2f0e8, 0x706f6114, 0x43c8d0a1, 0x5355415d, + 0xb4bf3777, 0xa422a68b, 0x9785173e, 0x871886c2, 0xf2cb77e5, + 0xe256e619, 0xd1f157ac, 0xc16cc650, 0x3b57b4e3, 0x2bca251f, + 0x186d94aa, 0x08f00556, 0x7d23f471, 0x6dbe658d, 0x5e19d438, + 0x4e8445c4}, + {0x00000000, 0x9c81fd99, 0x3b03f883, 0xa782051a, 0x7506f3b7, + 0xe9870e2e, 0x4e050b34, 0xd284f6ad, 0xe90ce5df, 0x758d1846, + 0xd20f1d5c, 0x4e8ee0c5, 0x9c0a1668, 0x008bebf1, 0xa709eeeb, + 0x3b881372, 0xd119c90f, 0x4d983496, 0xea1a318c, 0x769bcc15, + 0xa41f3ab8, 0x389ec721, 0x9f1cc23b, 0x039d3fa2, 0x38152cd0, + 0xa494d149, 0x0316d453, 0x9f9729ca, 0x4d13df67, 0xd19222fe, + 0x761027e4, 0xea91da7d, 0xa233921f, 0x3eb26f86, 0x99306a9c, + 0x05b19705, 0xd73561a8, 0x4bb49c31, 0xec36992b, 0x70b764b2, + 0x4b3f77c0, 0xd7be8a59, 0x703c8f43, 0xecbd72da, 0x3e398477, + 0xa2b879ee, 0x053a7cf4, 0x99bb816d, 0x732a5b10, 0xefaba689, + 0x4829a393, 0xd4a85e0a, 0x062ca8a7, 0x9aad553e, 0x3d2f5024, + 0xa1aeadbd, 0x9a26becf, 0x06a74356, 0xa125464c, 0x3da4bbd5, + 0xef204d78, 0x73a1b0e1, 0xd423b5fb, 0x48a24862, 0x4467243f, + 0xd8e6d9a6, 0x7f64dcbc, 0xe3e52125, 0x3161d788, 0xade02a11, + 0x0a622f0b, 0x96e3d292, 0xad6bc1e0, 0x31ea3c79, 0x96683963, + 0x0ae9c4fa, 0xd86d3257, 0x44eccfce, 0xe36ecad4, 0x7fef374d, + 0x957eed30, 0x09ff10a9, 0xae7d15b3, 0x32fce82a, 0xe0781e87, + 0x7cf9e31e, 0xdb7be604, 0x47fa1b9d, 0x7c7208ef, 0xe0f3f576, + 0x4771f06c, 0xdbf00df5, 0x0974fb58, 0x95f506c1, 0x327703db, + 0xaef6fe42, 0xe654b620, 0x7ad54bb9, 0xdd574ea3, 0x41d6b33a, + 0x93524597, 0x0fd3b80e, 0xa851bd14, 0x34d0408d, 0x0f5853ff, + 0x93d9ae66, 0x345bab7c, 0xa8da56e5, 0x7a5ea048, 0xe6df5dd1, + 0x415d58cb, 0xdddca552, 0x374d7f2f, 0xabcc82b6, 0x0c4e87ac, + 0x90cf7a35, 0x424b8c98, 0xdeca7101, 0x7948741b, 0xe5c98982, + 0xde419af0, 0x42c06769, 0xe5426273, 0x79c39fea, 0xab476947, + 0x37c694de, 0x904491c4, 0x0cc56c5d, 0x88ce487e, 0x144fb5e7, + 0xb3cdb0fd, 0x2f4c4d64, 0xfdc8bbc9, 0x61494650, 0xc6cb434a, + 0x5a4abed3, 0x61c2ada1, 0xfd435038, 0x5ac15522, 0xc640a8bb, + 0x14c45e16, 0x8845a38f, 0x2fc7a695, 0xb3465b0c, 0x59d78171, + 0xc5567ce8, 0x62d479f2, 0xfe55846b, 0x2cd172c6, 0xb0508f5f, + 0x17d28a45, 0x8b5377dc, 0xb0db64ae, 0x2c5a9937, 0x8bd89c2d, + 0x175961b4, 0xc5dd9719, 0x595c6a80, 0xfede6f9a, 0x625f9203, + 0x2afdda61, 0xb67c27f8, 0x11fe22e2, 0x8d7fdf7b, 0x5ffb29d6, + 0xc37ad44f, 0x64f8d155, 0xf8792ccc, 0xc3f13fbe, 0x5f70c227, + 0xf8f2c73d, 0x64733aa4, 0xb6f7cc09, 0x2a763190, 0x8df4348a, + 0x1175c913, 0xfbe4136e, 0x6765eef7, 0xc0e7ebed, 0x5c661674, + 0x8ee2e0d9, 0x12631d40, 0xb5e1185a, 0x2960e5c3, 0x12e8f6b1, + 0x8e690b28, 0x29eb0e32, 0xb56af3ab, 0x67ee0506, 0xfb6ff89f, + 0x5cedfd85, 0xc06c001c, 0xcca96c41, 0x502891d8, 0xf7aa94c2, + 0x6b2b695b, 0xb9af9ff6, 0x252e626f, 0x82ac6775, 0x1e2d9aec, + 0x25a5899e, 0xb9247407, 0x1ea6711d, 0x82278c84, 0x50a37a29, + 0xcc2287b0, 0x6ba082aa, 0xf7217f33, 0x1db0a54e, 0x813158d7, + 0x26b35dcd, 0xba32a054, 0x68b656f9, 0xf437ab60, 0x53b5ae7a, + 0xcf3453e3, 0xf4bc4091, 0x683dbd08, 0xcfbfb812, 0x533e458b, + 0x81bab326, 0x1d3b4ebf, 0xbab94ba5, 0x2638b63c, 0x6e9afe5e, + 0xf21b03c7, 0x559906dd, 0xc918fb44, 0x1b9c0de9, 0x871df070, + 0x209ff56a, 0xbc1e08f3, 0x87961b81, 0x1b17e618, 0xbc95e302, + 0x20141e9b, 0xf290e836, 0x6e1115af, 0xc99310b5, 0x5512ed2c, + 0xbf833751, 0x2302cac8, 0x8480cfd2, 0x1801324b, 0xca85c4e6, + 0x5604397f, 0xf1863c65, 0x6d07c1fc, 0x568fd28e, 0xca0e2f17, + 0x6d8c2a0d, 0xf10dd794, 0x23892139, 0xbf08dca0, 0x188ad9ba, + 0x840b2423}, + {0x00000000, 0x81615947, 0x02c3b28e, 0x83a2ebc9, 0x078666ad, + 0x86e73fea, 0x0545d423, 0x84248d64, 0x0d0cceea, 0x8c6d97ad, + 0x0fcf7c64, 0x8eae2523, 0x0a8aa847, 0x8bebf100, 0x08491ac9, + 0x8928438e, 0x19189f65, 0x9879c622, 0x1bdb2deb, 0x9aba74ac, + 0x1e9ef9c8, 0x9fffa08f, 0x1c5d4b46, 0x9d3c1201, 0x1414518f, + 0x957508c8, 0x16d7e301, 0x97b6ba46, 0x13923722, 0x92f36e65, + 0x115185ac, 0x9030dceb, 0x32303ecb, 0xb351678c, 0x30f38c45, + 0xb192d502, 0x35b65866, 0xb4d70121, 0x3775eae8, 0xb614b3af, + 0x3f3cf021, 0xbe5da966, 0x3dff42af, 0xbc9e1be8, 0x38ba968c, + 0xb9dbcfcb, 0x3a792402, 0xbb187d45, 0x2b28a1ae, 0xaa49f8e9, + 0x29eb1320, 0xa88a4a67, 0x2caec703, 0xadcf9e44, 0x2e6d758d, + 0xaf0c2cca, 0x26246f44, 0xa7453603, 0x24e7ddca, 0xa586848d, + 0x21a209e9, 0xa0c350ae, 0x2361bb67, 0xa200e220, 0x67607f26, + 0xe6012661, 0x65a3cda8, 0xe4c294ef, 0x60e6198b, 0xe18740cc, + 0x6225ab05, 0xe344f242, 0x6a6cb1cc, 0xeb0de88b, 0x68af0342, + 0xe9ce5a05, 0x6dead761, 0xec8b8e26, 0x6f2965ef, 0xee483ca8, + 0x7e78e043, 0xff19b904, 0x7cbb52cd, 0xfdda0b8a, 0x79fe86ee, + 0xf89fdfa9, 0x7b3d3460, 0xfa5c6d27, 0x73742ea9, 0xf21577ee, + 0x71b79c27, 0xf0d6c560, 0x74f24804, 0xf5931143, 0x7631fa8a, + 0xf750a3cd, 0x555041ed, 0xd43118aa, 0x5793f363, 0xd6f2aa24, + 0x52d62740, 0xd3b77e07, 0x501595ce, 0xd174cc89, 0x585c8f07, + 0xd93dd640, 0x5a9f3d89, 0xdbfe64ce, 0x5fdae9aa, 0xdebbb0ed, + 0x5d195b24, 0xdc780263, 0x4c48de88, 0xcd2987cf, 0x4e8b6c06, + 0xcfea3541, 0x4bceb825, 0xcaafe162, 0x490d0aab, 0xc86c53ec, + 0x41441062, 0xc0254925, 0x4387a2ec, 0xc2e6fbab, 0x46c276cf, + 0xc7a32f88, 0x4401c441, 0xc5609d06, 0xcec0fe4c, 0x4fa1a70b, + 0xcc034cc2, 0x4d621585, 0xc94698e1, 0x4827c1a6, 0xcb852a6f, + 0x4ae47328, 0xc3cc30a6, 0x42ad69e1, 0xc10f8228, 0x406edb6f, + 0xc44a560b, 0x452b0f4c, 0xc689e485, 0x47e8bdc2, 0xd7d86129, + 0x56b9386e, 0xd51bd3a7, 0x547a8ae0, 0xd05e0784, 0x513f5ec3, + 0xd29db50a, 0x53fcec4d, 0xdad4afc3, 0x5bb5f684, 0xd8171d4d, + 0x5976440a, 0xdd52c96e, 0x5c339029, 0xdf917be0, 0x5ef022a7, + 0xfcf0c087, 0x7d9199c0, 0xfe337209, 0x7f522b4e, 0xfb76a62a, + 0x7a17ff6d, 0xf9b514a4, 0x78d44de3, 0xf1fc0e6d, 0x709d572a, + 0xf33fbce3, 0x725ee5a4, 0xf67a68c0, 0x771b3187, 0xf4b9da4e, + 0x75d88309, 0xe5e85fe2, 0x648906a5, 0xe72bed6c, 0x664ab42b, + 0xe26e394f, 0x630f6008, 0xe0ad8bc1, 0x61ccd286, 0xe8e49108, + 0x6985c84f, 0xea272386, 0x6b467ac1, 0xef62f7a5, 0x6e03aee2, + 0xeda1452b, 0x6cc01c6c, 0xa9a0816a, 0x28c1d82d, 0xab6333e4, + 0x2a026aa3, 0xae26e7c7, 0x2f47be80, 0xace55549, 0x2d840c0e, + 0xa4ac4f80, 0x25cd16c7, 0xa66ffd0e, 0x270ea449, 0xa32a292d, + 0x224b706a, 0xa1e99ba3, 0x2088c2e4, 0xb0b81e0f, 0x31d94748, + 0xb27bac81, 0x331af5c6, 0xb73e78a2, 0x365f21e5, 0xb5fdca2c, + 0x349c936b, 0xbdb4d0e5, 0x3cd589a2, 0xbf77626b, 0x3e163b2c, + 0xba32b648, 0x3b53ef0f, 0xb8f104c6, 0x39905d81, 0x9b90bfa1, + 0x1af1e6e6, 0x99530d2f, 0x18325468, 0x9c16d90c, 0x1d77804b, + 0x9ed56b82, 0x1fb432c5, 0x969c714b, 0x17fd280c, 0x945fc3c5, + 0x153e9a82, 0x911a17e6, 0x107b4ea1, 0x93d9a568, 0x12b8fc2f, + 0x828820c4, 0x03e97983, 0x804b924a, 0x012acb0d, 0x850e4669, + 0x046f1f2e, 0x87cdf4e7, 0x06acada0, 0x8f84ee2e, 0x0ee5b769, + 0x8d475ca0, 0x0c2605e7, 0x88028883, 0x0963d1c4, 0x8ac13a0d, + 0x0ba0634a}}; + +#endif + +#endif + +#endif + +static const crc_t x2n_table[] = { + 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, + 0xd8018001, 0xf8818001, 0xf0810001, 0x28008000, 0xd0818001, + 0xf8010001, 0x28800000, 0x08808000, 0xd8810001, 0x20808000, + 0xd0010001, 0x20000000, 0x08000000, 0x00800000, 0x00008000, + 0xd8018001, 0xf8818001, 0xf0810001, 0x28008000, 0xd0818001, + 0xf8010001, 0x28800000, 0x08808000, 0xd8810001, 0x20808000, + 0xd0010001, 0x20000000}; diff --git a/src/utils/log.c b/src/utils/log.c index 257029b51..f10dff56b 100644 --- a/src/utils/log.c +++ b/src/utils/log.c @@ -106,7 +106,6 @@ log_out(void *priv, const char *fmt, va_list ap) { log_t *log = (log_t *) priv; char temp[1024]; - char fmt2[1024]; if (log == NULL) pclog("WARNING: Logging called with a NULL log pointer\n"); @@ -115,18 +114,20 @@ log_out(void *priv, const char *fmt, va_list ap) else if (fmt[0] != '\0') { log_ensure_stdlog_open(); - vsprintf(temp, fmt, ap); + vsnprintf(temp, sizeof(temp), fmt, ap); + if (log->suppr_seen && !strcmp(log->buff, temp)) log->seen++; else { if (log->suppr_seen && log->seen) { - log_copy(log, fmt2, "*** %d repeats ***\n", 1024); - fprintf(stdlog, fmt2, log->seen); + fprintf(stdlog, "*** %d repeats ***\n", log->seen); } log->seen = 0; - strcpy(log->buff, temp); - log_copy(log, fmt2, temp, 1024); - fprintf(stdlog, fmt2, ap); + + strncpy(log->buff, temp, sizeof(log->buff) - 1); + log->buff[sizeof(log->buff) - 1] = '\0'; + + fprintf(stdlog, "%s", temp); } fflush(stdlog); diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 062fc272a..1159c93e2 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -11,75 +11,135 @@ # Authors: David Hrdlička, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2025 starfrost # add_library(vid OBJECT + + # Video Core agpgart.c video.c vid_table.c + + # RAMDAC (Should this be its own library?) + ramdac/vid_ramdac_ati68860.c + ramdac/vid_ramdac_ati68875.c + ramdac/vid_ramdac_att20c49x.c + ramdac/vid_ramdac_att2xc498.c + ramdac/vid_ramdac_bt48x.c + ramdac/vid_ramdac_bt481.c + ramdac/vid_ramdac_ibm_rgb528.c + ramdac/vid_ramdac_sc1148x.c + ramdac/vid_ramdac_sc1502x.c + ramdac/vid_ramdac_sdac.c + ramdac/vid_ramdac_stg1702.c + ramdac/vid_ramdac_tkd8001.c + ramdac/vid_ramdac_tvp3026.c + + # Clock generator chips + clockgen/vid_clockgen_av9194.c + clockgen/vid_clockgen_icd2061.c + clockgen/vid_clockgen_ics2494.c + clockgen/vid_clockgen_ics2595.c + + # DDC / monitor identification stuff + vid_ddc.c + + # CARDS start here + + # CGA / Super CGA vid_cga.c vid_cga_comp.c - vid_compaq_cga.c + vid_cga_compaq.c + vid_cga_compaq_plasma.c + vid_cga_colorplus.c + vid_cga_ncr.c + vid_cga_olivetti.c + vid_cga_quadcolor.c + vid_cga_toshiba_t1000.c + vid_cga_toshiba_t3100e.c + + # PCJr/Tandy + vid_pcjr.c + vid_tandy.c vid_mda.c + + # Hercules vid_hercules.c - vid_herculesplus.c - vid_incolor.c - vid_colorplus.c + vid_hercules_plus.c + vid_hercules_incolor.c + + # Other early CGA-era cards vid_genius.c + vid_sigma.c + + # PGC / IM1024 / WY700 high-resolution vid_pgc.c vid_im1024.c - vid_sigma.c vid_wy700.c + + # EGA vid_ega.c vid_ega_render.c - vid_svga.c - vid_8514a.c - vid_svga_render.c - vid_ddc.c + vid_jega.c + + # (Real IBM) VGA vid_vga.c + + # Super VGA core + vid_svga.c + vid_svga_render.c + + # 8514/A, XGA and derivatives + vid_8514a.c + vid_xga.c + vid_ps55da2.c + + # ATI Technologies vid_ati_eeprom.c vid_ati18800.c vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c - vid_ati68875_ramdac.c - vid_ati68860_ramdac.c - vid_bt481_ramdac.c - vid_bt48x_ramdac.c + + # Chips & Technologies vid_chips_69000.c - vid_av9194.c - vid_icd2061.c - vid_ics2494.c - vid_ics2595.c + + # Cirrus Logic vid_cl54xx.c + + # Tseng Labs vid_et3000.c vid_et4000.c - vid_sc1148x_ramdac.c - vid_sc1502x_ramdac.c vid_et4000w32.c - vid_stg_ramdac.c + + # Headland vid_ht216.c vid_oak_oti.c + + # Paradise 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 + + # Trident + vid_tvga.c + vid_tgui9440.c + + # S3 Graphics + vid_s3.c + vid_s3_virge.c + + # Matrox vid_mga.c - vid_nga.c - vid_tvp3026_ramdac.c - vid_att2xc498_ramdac.c - vid_xga.c - vid_bochs_vbe.c - vid_ps55da2.c - vid_jega.c + + # NVidia (pending) nv/nv_rivatimer.c + + # Generic + vid_bochs_vbe.c + ) if(G100) @@ -90,6 +150,7 @@ if(XL24) target_compile_definitions(vid PRIVATE USE_XL24) endif() +# 3Dfx Voodoo add_library(voodoo OBJECT vid_voodoo.c vid_voodoo_banshee.c diff --git a/src/video/vid_av9194.c b/src/video/clockgen/vid_clockgen_av9194.c similarity index 100% rename from src/video/vid_av9194.c rename to src/video/clockgen/vid_clockgen_av9194.c diff --git a/src/video/vid_icd2061.c b/src/video/clockgen/vid_clockgen_icd2061.c similarity index 100% rename from src/video/vid_icd2061.c rename to src/video/clockgen/vid_clockgen_icd2061.c diff --git a/src/video/vid_ics2494.c b/src/video/clockgen/vid_clockgen_ics2494.c similarity index 100% rename from src/video/vid_ics2494.c rename to src/video/clockgen/vid_clockgen_ics2494.c diff --git a/src/video/vid_ics2595.c b/src/video/clockgen/vid_clockgen_ics2595.c similarity index 100% rename from src/video/vid_ics2595.c rename to src/video/clockgen/vid_clockgen_ics2595.c diff --git a/src/video/vid_ati68860_ramdac.c b/src/video/ramdac/vid_ramdac_ati68860.c similarity index 78% rename from src/video/vid_ati68860_ramdac.c rename to src/video/ramdac/vid_ramdac_ati68860.c index 17b2a6d22..4411f2ee2 100644 --- a/src/video/vid_ati68860_ramdac.c +++ b/src/video/ramdac/vid_ramdac_ati68860.c @@ -67,22 +67,22 @@ typedef struct ati68860_ramdac_t { } ati68860_ramdac_t; void -ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) +ati68860_ramdac_out(uint16_t addr, uint8_t val, int is_8514, void *priv, svga_t *svga) { ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; switch (addr) { case 0: - svga_out(0x3c8, val, svga); + svga_out(is_8514 ? 0x2ec : 0x3c8, val, svga); break; case 1: - svga_out(0x3c9, val, svga); + svga_out(is_8514 ? 0x2ed : 0x3c9, val, svga); break; case 2: - svga_out(0x3c6, val, svga); + svga_out(is_8514 ? 0x2ea : 0x3c6, val, svga); break; case 3: - svga_out(0x3c7, val, svga); + svga_out(is_8514 ? 0x2eb : 0x3c7, val, svga); break; default: ramdac->regs[addr & 0xf] = val; @@ -172,23 +172,23 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) } uint8_t -ati68860_ramdac_in(uint16_t addr, void *priv, svga_t *svga) +ati68860_ramdac_in(uint16_t addr, int is_8514, void *priv, svga_t *svga) { const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; uint8_t temp = 0; switch (addr) { case 0: - temp = svga_in(0x3c8, svga); + temp = svga_in(is_8514 ? 0x2ec : 0x3c8, svga); break; case 1: - temp = svga_in(0x3c9, svga); + temp = svga_in(is_8514 ? 0x2ed : 0x3c9, svga); break; case 2: - temp = svga_in(0x3c6, svga); + temp = svga_in(is_8514 ? 0x2ea : 0x3c6, svga); break; case 3: - temp = svga_in(0x3c7, svga); + temp = svga_in(is_8514 ? 0x2eb : 0x3c7, svga); break; case 4: case 8: @@ -261,38 +261,57 @@ void ati68860_hwcursor_draw(svga_t *svga, int displine) { const ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; + int comb; int offset; - uint8_t dat; + int x_pos; + int y_pos; + int shift = 0; + uint16_t dat; uint32_t col0 = ramdac->pallook[0]; uint32_t col1 = ramdac->pallook[1]; + uint32_t *p; - offset = svga->dac_hwcursor_latch.xoff; - for (uint32_t x = 0; x < 64 - svga->dac_hwcursor_latch.xoff; x += 4) { - dat = svga->vram[svga->dac_hwcursor_latch.addr + (offset >> 2)]; - if (!(dat & 2)) - buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) - buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) - buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) - buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) - buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) - buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) - buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) - buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] ^= 0xFFFFFF; - dat >>= 2; - offset += 4; + offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff; + if (svga->packed_4bpp) + shift = 1; + + for (int x = 0; x < svga->dac_hwcursor_latch.cur_xsize; x += (8 >> shift)) { + if (shift) { + dat = svga->vram[(svga->dac_hwcursor_latch.addr) & svga->vram_mask] & 0x0f; + dat |= (svga->vram[(svga->dac_hwcursor_latch.addr + 1) & svga->vram_mask] << 4); + dat |= (svga->vram[(svga->dac_hwcursor_latch.addr + 2) & svga->vram_mask] << 8); + dat |= (svga->vram[(svga->dac_hwcursor_latch.addr + 3) & svga->vram_mask] << 12); + } else { + dat = svga->vram[svga->dac_hwcursor_latch.addr & svga->vram_mask]; + dat |= (svga->vram[(svga->dac_hwcursor_latch.addr + 1) & svga->vram_mask] << 8); + } + for (int xx = 0; xx < (8 >> shift); xx++) { + comb = (dat >> (xx << 1)) & 0x03; + + y_pos = displine; + x_pos = offset + svga->x_add; + p = buffer32->line[y_pos]; + + if (offset >= svga->dac_hwcursor_latch.x) { + switch (comb) { + case 0: + p[x_pos] = col0; + break; + case 1: + p[x_pos] = col1; + break; + case 3: + p[x_pos] ^= 0xffffff; + break; + + default: + break; + } + } + offset++; + } + svga->dac_hwcursor_latch.addr += 2; } - - svga->dac_hwcursor_latch.addr += 16; } static void diff --git a/src/video/vid_ati68875_ramdac.c b/src/video/ramdac/vid_ramdac_ati68875.c similarity index 84% rename from src/video/vid_ati68875_ramdac.c rename to src/video/ramdac/vid_ramdac_ati68875.c index 5d573a282..4de0ed3d9 100644 --- a/src/video/vid_ati68875_ramdac.c +++ b/src/video/ramdac/vid_ramdac_ati68875.c @@ -38,7 +38,7 @@ typedef struct ati68875_ramdac_t { } ati68875_ramdac_t; void -ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga) +ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, int is_8514, void *priv, svga_t *svga) { ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) priv; uint8_t rs = (addr & 0x03); @@ -48,10 +48,16 @@ ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, sv switch (rs) { case 0x00: /* Palette Write Index Register (RS value = 0000) */ + svga_out(is_8514 ? 0x2ec : 0x3c8, val, svga); + break; case 0x01: /* Palette Data Register (RS value = 0001) */ + svga_out(is_8514 ? 0x2ed : 0x3c9, val, svga); + break; case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ - case 0x03: - svga_out(addr, val, svga); + svga_out(is_8514 ? 0x2ea : 0x3c6, val, svga); + break; + case 0x03: /* Palette Read Index Register (RS value = 0011) */ + svga_out(is_8514 ? 0x2eb : 0x3c7, val, svga); break; case 0x08: /* General Control Register (RS value = 1000) */ ramdac->gen_cntl = val; @@ -83,7 +89,7 @@ ati68875_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, sv } uint8_t -ati68875_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga) +ati68875_ramdac_in(uint16_t addr, int rs2, int rs3, int is_8514, void *priv, svga_t *svga) { const ati68875_ramdac_t *ramdac = (ati68875_ramdac_t *) priv; uint8_t rs = (addr & 0x03); @@ -94,10 +100,16 @@ ati68875_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga) switch (rs) { case 0x00: /* Palette Write Index Register (RS value = 0000) */ + temp = svga_in(is_8514 ? 0x2ec : 0x3c8, svga); + break; case 0x01: /* Palette Data Register (RS value = 0001) */ + temp = svga_in(is_8514 ? 0x2ed : 0x3c9, svga); + break; case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ - case 0x03: - temp = svga_in(addr, svga); + temp = svga_in(is_8514 ? 0x2ea : 0x3c6, svga); + break; + case 0x03: /* Palette Read Index Register (RS value = 0011) */ + temp = svga_in(is_8514 ? 0x2eb : 0x3c7, svga); break; case 0x08: /* General Control Register (RS value = 1000) */ temp = ramdac->gen_cntl; diff --git a/src/video/vid_att20c49x_ramdac.c b/src/video/ramdac/vid_ramdac_att20c49x.c similarity index 100% rename from src/video/vid_att20c49x_ramdac.c rename to src/video/ramdac/vid_ramdac_att20c49x.c diff --git a/src/video/vid_att2xc498_ramdac.c b/src/video/ramdac/vid_ramdac_att2xc498.c similarity index 100% rename from src/video/vid_att2xc498_ramdac.c rename to src/video/ramdac/vid_ramdac_att2xc498.c diff --git a/src/video/vid_bt481_ramdac.c b/src/video/ramdac/vid_ramdac_bt481.c similarity index 100% rename from src/video/vid_bt481_ramdac.c rename to src/video/ramdac/vid_ramdac_bt481.c diff --git a/src/video/vid_bt48x_ramdac.c b/src/video/ramdac/vid_ramdac_bt48x.c similarity index 100% rename from src/video/vid_bt48x_ramdac.c rename to src/video/ramdac/vid_ramdac_bt48x.c diff --git a/src/video/vid_ibm_rgb528_ramdac.c b/src/video/ramdac/vid_ramdac_ibm_rgb528.c similarity index 91% rename from src/video/vid_ibm_rgb528_ramdac.c rename to src/video/ramdac/vid_ramdac_ibm_rgb528.c index dcdbbb25b..cd7d5c1b6 100644 --- a/src/video/vid_ibm_rgb528_ramdac.c +++ b/src/video/ramdac/vid_ramdac_ibm_rgb528.c @@ -104,7 +104,7 @@ ibm_rgb528_render_4bpp(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->changedvram[(svga->memaddr >> 12) + 2] || svga->fullchange) { p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -114,8 +114,8 @@ ibm_rgb528_render_4bpp(svga_t *svga) for (int x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { if (vram_size == 3) { if (!(x & 31)) { - dat64 = *(uint64_t *) (&svga->vram[svga->ma]); - dat642 = *(uint64_t *) (&svga->vram[svga->ma + 8]); + dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]); + dat642 = *(uint64_t *) (&svga->vram[svga->memaddr + 8]); if (swap_word) { dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); dat642 = (dat642 << 32ULL) | (dat642 >> 32ULL); @@ -127,7 +127,7 @@ ibm_rgb528_render_4bpp(svga_t *svga) dat = (((x & 16) ? dat642 : dat64) >> (((x & 15) << 2) ^ 4)) & 0xf; } else if (vram_size == 1) { if (!(x & 15)) { - dat64 = *(uint64_t *) (&svga->vram[svga->ma]); + dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]); if (swap_word) dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); } @@ -137,7 +137,7 @@ ibm_rgb528_render_4bpp(svga_t *svga) dat = (dat64 >> (((x & 15) << 2) ^ 4)) & 0xf; } else { if (!(x & 7)) - dat32 = *(uint32_t *) (&svga->vram[svga->ma]); + dat32 = *(uint32_t *) (&svga->vram[svga->memaddr]); if (swap_nib) dat = (dat32 >> ((x & 7) << 2)) & 0xf; else @@ -156,11 +156,11 @@ ibm_rgb528_render_4bpp(svga_t *svga) p[x] = dat_out.pixel & 0xffffff; if ((vram_size == 3) && ((x & 31) == 31)) - svga->ma = (svga->ma + 16) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 16) & svga->vram_display_mask; if ((vram_size == 1) && ((x & 15) == 15)) - svga->ma = (svga->ma + 8) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 8) & svga->vram_display_mask; else if ((!vram_size) && ((x & 7) == 7)) - svga->ma = (svga->ma + 4) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 4) & svga->vram_display_mask; } } } @@ -182,7 +182,7 @@ ibm_rgb528_render_8bpp(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->changedvram[(svga->memaddr >> 12) + 2] || svga->fullchange) { p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -192,8 +192,8 @@ ibm_rgb528_render_8bpp(svga_t *svga) for (int x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { if (vram_size == 3) { if (!(x & 15)) { - dat64 = *(uint64_t *) (&svga->vram[svga->ma]); - dat642 = *(uint64_t *) (&svga->vram[svga->ma + 8]); + dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]); + dat642 = *(uint64_t *) (&svga->vram[svga->memaddr + 8]); if (swap_word) { dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); dat642 = (dat642 << 32ULL) | (dat642 >> 32ULL); @@ -202,14 +202,14 @@ ibm_rgb528_render_8bpp(svga_t *svga) dat = (((x & 8) ? dat642 : dat64) >> ((x & 7) << 3)) & 0xff; } else if (vram_size == 1) { if (!(x & 7)) { - dat64 = *(uint64_t *) (&svga->vram[svga->ma]); + dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]); if (swap_word) dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); } dat = (dat64 >> ((x & 7) << 3)) & 0xff; } else { if (!(x & 3)) - dat32 = *(uint32_t *) (&svga->vram[svga->ma]); + dat32 = *(uint32_t *) (&svga->vram[svga->memaddr]); dat = (dat32 >> ((x & 3) << 3)) & 0xff; } if (b8_dcol == 0x00) { @@ -225,11 +225,11 @@ ibm_rgb528_render_8bpp(svga_t *svga) p[x] = dat_out.pixel & 0xffffff; if ((vram_size == 3) && ((x & 15) == 15)) - svga->ma = (svga->ma + 16) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 16) & svga->vram_display_mask; else if ((vram_size == 1) && ((x & 7) == 7)) - svga->ma = (svga->ma + 8) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 8) & svga->vram_display_mask; else if ((!vram_size) && ((x & 3) == 3)) - svga->ma = (svga->ma + 4) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 4) & svga->vram_display_mask; } } } @@ -262,7 +262,7 @@ ibm_rgb528_render_15_16bpp(svga_t *svga) if (b555_565 && (b16_dcol != 0x01)) partition &= 0xc0; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->changedvram[(svga->memaddr >> 12) + 2] || svga->fullchange) { p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -272,8 +272,8 @@ ibm_rgb528_render_15_16bpp(svga_t *svga) for (int x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { if (vram_size == 2) { if (!(x & 7)) { - dat64 = *(uint64_t *) (&svga->vram[svga->ma]); - dat642 = *(uint64_t *) (&svga->vram[svga->ma + 8]); + dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]); + dat642 = *(uint64_t *) (&svga->vram[svga->memaddr + 8]); if (swap_word) { dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); dat642 = (dat64 << 32ULL) | (dat642 >> 32ULL); @@ -282,14 +282,14 @@ ibm_rgb528_render_15_16bpp(svga_t *svga) dat = (((x & 4) ? dat642 : dat64) >> ((x & 3) << 4)) & 0xffff; } else if (vram_size == 1) { if (!(x & 3)) { - dat64 = *(uint64_t *) (&svga->vram[svga->ma]); + dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]); if (swap_word) dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); } dat = (dat64 >> ((x & 3) << 4)) & 0xffff; } else { if (!(x & 1)) - dat32 = *(uint32_t *) (&svga->vram[svga->ma]); + dat32 = *(uint32_t *) (&svga->vram[svga->memaddr]); dat = (dat32 >> ((x & 1) << 4)) & 0xffff; } dat_ex = (ibm_rgb528_pixel16_t *) &dat; @@ -350,11 +350,11 @@ ibm_rgb528_render_15_16bpp(svga_t *svga) p[x] = dat_out.pixel & 0xffffff; if ((vram_size == 3) && ((x & 7) == 7)) - svga->ma = (svga->ma + 16) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 16) & svga->vram_display_mask; else if ((vram_size == 1) && ((x & 3) == 3)) - svga->ma = (svga->ma + 8) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 8) & svga->vram_display_mask; else if (!vram_size && ((x & 1) == 1)) - svga->ma = (svga->ma + 4) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 4) & svga->vram_display_mask; } } } @@ -378,7 +378,7 @@ ibm_rgb528_render_24bpp(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->changedvram[(svga->memaddr >> 12) + 2] || svga->fullchange) { p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -389,12 +389,12 @@ ibm_rgb528_render_24bpp(svga_t *svga) dat_ex = (ibm_rgb528_pixel32_t *) &dat; if (vram_size == 3) { if ((x & 15) == 0) { - dat64[0] = *(uint64_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); - dat64[1] = *(uint64_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - dat64[2] = *(uint64_t *) (&svga->vram[(svga->ma + 16) & svga->vram_display_mask]); - dat64[3] = *(uint64_t *) (&svga->vram[(svga->ma + 24) & svga->vram_display_mask]); - dat64[4] = *(uint64_t *) (&svga->vram[(svga->ma + 32) & svga->vram_display_mask]); - dat64[5] = *(uint64_t *) (&svga->vram[(svga->ma + 40) & svga->vram_display_mask]); + dat64[0] = *(uint64_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); + dat64[1] = *(uint64_t *) (&svga->vram[(svga->memaddr + 8) & svga->vram_display_mask]); + dat64[2] = *(uint64_t *) (&svga->vram[(svga->memaddr + 16) & svga->vram_display_mask]); + dat64[3] = *(uint64_t *) (&svga->vram[(svga->memaddr + 24) & svga->vram_display_mask]); + dat64[4] = *(uint64_t *) (&svga->vram[(svga->memaddr + 32) & svga->vram_display_mask]); + dat64[5] = *(uint64_t *) (&svga->vram[(svga->memaddr + 40) & svga->vram_display_mask]); if (swap_word) { dat64[0] = (dat64[0] << 32ULL) | (dat64[0] >> 32ULL); dat64[1] = (dat64[1] << 32ULL) | (dat64[1] >> 32ULL); @@ -407,9 +407,9 @@ ibm_rgb528_render_24bpp(svga_t *svga) dat_ex = (ibm_rgb528_pixel32_t *) &(dat8[(x & 15) * 3]); } else if (vram_size == 1) { if ((x & 7) == 0) { - dat64[0] = *(uint64_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); - dat64[1] = *(uint64_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - dat64[2] = *(uint64_t *) (&svga->vram[(svga->ma + 16) & svga->vram_display_mask]); + dat64[0] = *(uint64_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); + dat64[1] = *(uint64_t *) (&svga->vram[(svga->memaddr + 8) & svga->vram_display_mask]); + dat64[2] = *(uint64_t *) (&svga->vram[(svga->memaddr + 16) & svga->vram_display_mask]); if (swap_word) { dat64[0] = (dat64[0] << 32ULL) | (dat64[0] >> 32ULL); dat64[1] = (dat64[1] << 32ULL) | (dat64[1] >> 32ULL); @@ -441,9 +441,9 @@ ibm_rgb528_render_24bpp(svga_t *svga) p[x] = dat_ex->pixel & 0xffffff; if ((vram_size == 3) && ((x & 15) == 15)) - svga->ma = (svga->ma + 48) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 48) & svga->vram_display_mask; else if ((vram_size == 1) && ((x & 7) == 7)) - svga->ma = (svga->ma + 24) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 24) & svga->vram_display_mask; } } } @@ -468,7 +468,7 @@ ibm_rgb528_render_32bpp(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->changedvram[(svga->memaddr >> 12) + 2] || svga->fullchange) { p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -478,8 +478,8 @@ ibm_rgb528_render_32bpp(svga_t *svga) for (int x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { if (vram_size == 3) { if (!(x & 3)) { - dat64 = *(uint64_t *) (&svga->vram[svga->ma]); - dat642 = *(uint64_t *) (&svga->vram[svga->ma + 8]); + dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]); + dat642 = *(uint64_t *) (&svga->vram[svga->memaddr + 8]); if (swap_word) { dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); dat642 = (dat642 << 32ULL) | (dat642 >> 32ULL); @@ -488,13 +488,13 @@ ibm_rgb528_render_32bpp(svga_t *svga) dat = (((x & 2) ? dat642 : dat64) >> ((x & 1ULL) << 5ULL)) & 0xffffffff; } else if (vram_size == 1) { if (!(x & 1)) { - dat64 = *(uint64_t *) (&svga->vram[svga->ma]); + dat64 = *(uint64_t *) (&svga->vram[svga->memaddr]); if (swap_word) dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); } dat = (dat64 >> ((x & 1ULL) << 5ULL)) & 0xffffffff; } else - dat = *(uint32_t *) (&svga->vram[svga->ma]); + dat = *(uint32_t *) (&svga->vram[svga->memaddr]); dat_ex = (ibm_rgb528_pixel32_t *) &dat; if (swaprb) { temp = dat_ex->r; @@ -520,11 +520,11 @@ ibm_rgb528_render_32bpp(svga_t *svga) p[x] = dat_ex->pixel & 0xffffff; if ((vram_size == 3) && ((x & 3) == 3)) - svga->ma = (svga->ma + 16) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 16) & svga->vram_display_mask; else if ((vram_size == 1) && ((x & 1) == 1)) - svga->ma = (svga->ma + 8) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 8) & svga->vram_display_mask; else if (!vram_size) - svga->ma = (svga->ma + 4) & svga->vram_display_mask; + svga->memaddr = (svga->memaddr + 4) & svga->vram_display_mask; } } } diff --git a/src/video/vid_sc1148x_ramdac.c b/src/video/ramdac/vid_ramdac_sc1148x.c similarity index 100% rename from src/video/vid_sc1148x_ramdac.c rename to src/video/ramdac/vid_ramdac_sc1148x.c diff --git a/src/video/vid_sc1502x_ramdac.c b/src/video/ramdac/vid_ramdac_sc1502x.c similarity index 100% rename from src/video/vid_sc1502x_ramdac.c rename to src/video/ramdac/vid_ramdac_sc1502x.c diff --git a/src/video/vid_sdac_ramdac.c b/src/video/ramdac/vid_ramdac_sdac.c similarity index 100% rename from src/video/vid_sdac_ramdac.c rename to src/video/ramdac/vid_ramdac_sdac.c diff --git a/src/video/vid_stg_ramdac.c b/src/video/ramdac/vid_ramdac_stg1702.c similarity index 100% rename from src/video/vid_stg_ramdac.c rename to src/video/ramdac/vid_ramdac_stg1702.c diff --git a/src/video/vid_tkd8001_ramdac.c b/src/video/ramdac/vid_ramdac_tkd8001.c similarity index 100% rename from src/video/vid_tkd8001_ramdac.c rename to src/video/ramdac/vid_ramdac_tkd8001.c diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/ramdac/vid_ramdac_tvp3026.c similarity index 100% rename from src/video/vid_tvp3026_ramdac.c rename to src/video/ramdac/vid_ramdac_tvp3026.c diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index ba4641259..1c9a482af 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -334,6 +334,9 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + if (dev == NULL) + return; + if (port & 0x8000) { if ((port != 0xe2e8) && (port != 0xe2e9) && (port != 0xe6e8) && (port != 0xe6e9)) { if (port & 0x4000) @@ -459,7 +462,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x42e8: - ibm8514_log("VBLANK stat=%02x, val=%02x.\n", dev->subsys_stat, val); + ibm8514_log("VBLANK status=%02x, val=%02x.\n", dev->subsys_stat, val); if (len == 2) { dev->subsys_cntl = val; dev->subsys_stat &= ~val; @@ -743,6 +746,9 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + if (dev == NULL) + return; + if (port & 0x8000) { if (dev->accel.cmd_back) { dev->fifo_idx++; @@ -777,6 +783,9 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len) uint16_t temp = 0; int cmd = 0; + if (dev == NULL) + return 0xffff; + switch (port) { case 0x82e8: if (len == 2) @@ -911,8 +920,10 @@ ibm8514_accel_in(uint16_t port, svga_t *svga) switch (port) { case 0x2e8: - if (dev->vc == dev->v_syncstart) - temp |= 0x02; + if (dev->vc == dev->v_syncstart) { + if (dev->accel.advfunc_cntl & 0x04) + temp |= 0x02; + } ibm8514_log("Read: Display Status1=%02x.\n", temp); break; @@ -3383,7 +3394,7 @@ ibm8514_render_8bpp(svga_t *svga) if ((dev->displine + svga->y_add) < 0) return; - if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; if (dev->firstline_draw == 2000) @@ -3391,22 +3402,22 @@ ibm8514_render_8bpp(svga_t *svga) dev->lastline_draw = dev->displine; for (int x = 0; x <= dev->h_disp; x += 8) { - dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[dev->memaddr & dev->vram_mask]); p[0] = dev->pallook[dat & dev->dac_mask & 0xff]; p[1] = dev->pallook[(dat >> 8) & dev->dac_mask & 0xff]; p[2] = dev->pallook[(dat >> 16) & dev->dac_mask & 0xff]; p[3] = dev->pallook[(dat >> 24) & dev->dac_mask & 0xff]; - dat = *(uint32_t *) (&dev->vram[(dev->ma + 4) & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 4) & dev->vram_mask]); p[4] = dev->pallook[dat & dev->dac_mask & 0xff]; p[5] = dev->pallook[(dat >> 8) & dev->dac_mask & 0xff]; p[6] = dev->pallook[(dat >> 16) & dev->dac_mask & 0xff]; p[7] = dev->pallook[(dat >> 24) & dev->dac_mask & 0xff]; - dev->ma += 8; + dev->memaddr += 8; p += 8; } - dev->ma &= dev->vram_mask; + dev->memaddr &= dev->vram_mask; } } @@ -3421,7 +3432,7 @@ ibm8514_render_15bpp(svga_t *svga) if ((dev->displine + svga->y_add) < 0) return; - if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; if (dev->firstline_draw == 2000) @@ -3429,24 +3440,24 @@ ibm8514_render_15bpp(svga_t *svga) 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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (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; + dev->memaddr += (x << 1); + dev->memaddr &= dev->vram_mask; } } @@ -3461,7 +3472,7 @@ ibm8514_render_16bpp(svga_t *svga) if ((dev->displine + svga->y_add) < 0) return; - if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; if (dev->firstline_draw == 2000) @@ -3469,24 +3480,24 @@ ibm8514_render_16bpp(svga_t *svga) 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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (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; + dev->memaddr += (x << 1); + dev->memaddr &= dev->vram_mask; } } @@ -3500,7 +3511,7 @@ ibm8514_render_24bpp(svga_t *svga) if ((dev->displine + svga->y_add) < 0) return; - if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; if (dev->firstline_draw == 2000) @@ -3508,21 +3519,21 @@ ibm8514_render_24bpp(svga_t *svga) 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]); + dat = *(uint32_t *) (&dev->vram[dev->memaddr & dev->vram_mask]); p[x] = dat & 0xffffff; - dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 3) & dev->vram_mask]); p[x + 1] = dat & 0xffffff; - dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 6) & dev->vram_mask]); p[x + 2] = dat & 0xffffff; - dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 9) & dev->vram_mask]); p[x + 3] = dat & 0xffffff; - dev->ma += 12; + dev->memaddr += 12; } - dev->ma &= dev->vram_mask; + dev->memaddr &= dev->vram_mask; } } @@ -3536,7 +3547,7 @@ ibm8514_render_BGR(svga_t *svga) if ((dev->displine + svga->y_add) < 0) return; - if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; if (dev->firstline_draw == 2000) @@ -3544,21 +3555,21 @@ ibm8514_render_BGR(svga_t *svga) 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]); + dat = *(uint32_t *) (&dev->vram[dev->memaddr & dev->vram_mask]); p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); - dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 9) & dev->vram_mask]); p[x + 3] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); - dev->ma += 12; + dev->memaddr += 12; } - dev->ma &= dev->vram_mask; + dev->memaddr &= dev->vram_mask; } } @@ -3573,7 +3584,7 @@ ibm8514_render_ABGR8888(svga_t *svga) if ((dev->displine + svga->y_add) < 0) return; - if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; if (dev->firstline_draw == 2000) @@ -3581,11 +3592,11 @@ ibm8514_render_ABGR8888(svga_t *svga) 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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 2)) & dev->vram_mask]); *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); } - dev->ma += (x * 4); - dev->ma &= dev->vram_mask; + dev->memaddr += (x * 4); + dev->memaddr &= dev->vram_mask; } } @@ -3600,7 +3611,7 @@ ibm8514_render_32bpp(svga_t *svga) 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) { + if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || dev->changedvram[(dev->memaddr >> 12) + 2] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; if (dev->firstline_draw == 2000) @@ -3608,11 +3619,11 @@ ibm8514_render_32bpp(svga_t *svga) 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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 2)) & dev->vram_mask]); p[x] = dat & 0xffffff; } - dev->ma += (x * 4); - dev->ma &= dev->vram_mask; + dev->memaddr += (x * 4); + dev->memaddr &= dev->vram_mask; } } @@ -3681,7 +3692,7 @@ ibm8514_poll(void *priv) if (dev->dispon) { dev->hdisp_on = 1; - dev->ma &= dev->vram_mask; + dev->memaddr &= dev->vram_mask; if (dev->firstline == 2000) { dev->firstline = dev->displine; @@ -3689,14 +3700,14 @@ ibm8514_poll(void *priv) } if (dev->hwcursor_on) - dev->changedvram[dev->ma >> 12] = dev->changedvram[(dev->ma >> 12) + 1] = dev->interlace ? 3 : 2; + dev->changedvram[dev->memaddr >> 12] = dev->changedvram[(dev->memaddr >> 12) + 1] = dev->interlace ? 3 : 2; svga->render8514(svga); - svga->x_add = (overscan_x >> 1); + svga->x_add = svga->left_overscan; ibm8514_render_overscan_left(dev, svga); ibm8514_render_overscan_right(dev, svga); - svga->x_add = (overscan_x >> 1); + svga->x_add = svga->left_overscan; if (dev->hwcursor_on) { if (svga->hwcursor_draw) @@ -3726,18 +3737,18 @@ ibm8514_poll(void *priv) dev->linepos = 0; if (dev->dispon) { - if (dev->sc == dev->rowcount) { - dev->sc = 0; - dev->maback += (dev->rowoffset << 3); + if (dev->scanline == dev->rowcount) { + dev->scanline = 0; + dev->memaddr_backup += (dev->rowoffset << 3); if (dev->interlace) - dev->maback += (dev->rowoffset << 3); + dev->memaddr_backup += (dev->rowoffset << 3); - dev->maback &= dev->vram_mask; - dev->ma = dev->maback; + dev->memaddr_backup &= dev->vram_mask; + dev->memaddr = dev->memaddr_backup; } else { - dev->sc++; - dev->sc &= 0x1f; - dev->ma = dev->maback; + dev->scanline++; + dev->scanline &= 0x1f; + dev->memaddr = dev->memaddr_backup; } } @@ -3783,20 +3794,20 @@ ibm8514_poll(void *priv) svga->vslines = 0; if (dev->interlace && dev->oddeven) - dev->ma = dev->maback = (dev->rowoffset << 1); + dev->memaddr = dev->memaddr_backup = (dev->rowoffset << 1); else - dev->ma = dev->maback = 0; + dev->memaddr = dev->memaddr_backup = 0; - dev->ma = (dev->ma << 2); - dev->maback = (dev->maback << 2); + dev->memaddr = (dev->memaddr << 2); + dev->memaddr_backup = (dev->memaddr_backup << 2); } if (dev->vc == dev->v_total) { dev->vc = 0; - dev->sc = (svga->crtc[0x8] & 0x1f); + dev->scanline = (svga->crtc[0x8] & 0x1f); dev->dispon = 1; dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; - svga->x_add = (overscan_x >> 1); + svga->x_add = svga->left_overscan; dev->hwcursor_on = 0; dev->hwcursor_latch = dev->hwcursor; @@ -3827,10 +3838,14 @@ ibm8514_recalctimings(svga_t *svga) dev->vdisp += 2; dev->v_total = dev->v_total_reg + 1; + if (dev->v_total == 1) + dev->v_total = 0x0669; if (dev->interlace) dev->v_total >>= 1; dev->v_syncstart = dev->v_sync_start + 1; + if (dev->v_syncstart == 1) + dev->v_syncstart = 0x0601; if (dev->interlace) dev->v_syncstart >>= 1; @@ -3848,6 +3863,7 @@ ibm8514_recalctimings(svga_t *svga) dev->h_disp = dev->hdisp; dev->dispend = dev->vdisp; + dev->h_disp_time = dev->hdisp >> 3; if (dev->accel.advfunc_cntl & 0x04) svga->clock_8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; @@ -3966,7 +3982,7 @@ ibm8514_init(const device_t *info) bios_addr = 0xc6000; switch (dev->extensions) { - case 1: + case ATI: if (rom_present(BIOS_MACH8_ROM_PATH)) { mach_t * mach = (mach_t *) calloc(1, sizeof(mach_t)); svga->ext8514 = mach; @@ -3977,13 +3993,14 @@ ibm8514_init(const device_t *info) 0, MEM_MAPPING_EXTERNAL); ati8514_init(svga, svga->ext8514, svga->dev8514); - mach->accel.scratch0 = ((((bios_addr >> 7) - 0x1000) >> 4)); + mach->accel.scratch0 = ((bios_addr >> 7) - 0x1000) >> 4; bios_rom_eeprom = mach->accel.scratch0; if (dev->type & DEVICE_MCA) { dev->pos_regs[0] = 0x88; dev->pos_regs[1] = 0x80; mach->eeprom.data[0] = 0x0000; mach->eeprom.data[1] = bios_rom_eeprom | ((bios_rom_eeprom | 0x01) << 8); + ibm8514_log("EEPROM Data1=%04x.\n", mach->eeprom.data[1]); mca_add(ati8514_mca_read, ati8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga); ati_eeprom_load_mach8(&mach->eeprom, "ati8514_mca.nvr", 1); mem_mapping_disable(&dev->bios_rom.mapping); @@ -4067,19 +4084,19 @@ static const device_config_t isa_ext8514_config[] = { .description = "Vendor", .type = CONFIG_SELECTION, .default_string = NULL, - .default_int = 0, + .default_int = IBM, .file_filter = NULL, .spinner = { 0 }, .selection = { - { .description = "IBM", .value = 0 }, - { .description = "ATI", .value = 1 }, + { .description = "IBM", .value = IBM }, + { .description = "ATI", .value = ATI }, { .description = "" } }, .bios = { { 0 } } }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xc8000, @@ -4127,12 +4144,12 @@ static const device_config_t mca_ext8514_config[] = { .description = "Vendor", .type = CONFIG_SELECTION, .default_string = NULL, - .default_int = 0, + .default_int = IBM, .file_filter = NULL, .spinner = { 0 }, .selection = { - { .description = "IBM", .value = 0 }, - { .description = "ATI", .value = 1 }, + { .description = "IBM", .value = IBM }, + { .description = "ATI", .value = ATI }, { .description = "" } }, .bios = { { 0 } } @@ -4145,7 +4162,7 @@ const device_t gen8514_isa_device = { .name = "IBM 8514/A clone (ISA)", .internal_name = "8514_isa", .flags = DEVICE_ISA16, - .local = 0, + .local = IBM_8514A_TYPE, .init = ibm8514_init, .close = ibm8514_close, .reset = NULL, @@ -4159,7 +4176,7 @@ const device_t ibm8514_mca_device = { .name = "IBM 8514/A (MCA)", .internal_name = "8514_mca", .flags = DEVICE_MCA, - .local = 0, + .local = IBM_8514A_TYPE, .init = ibm8514_init, .close = ibm8514_close, .reset = NULL, diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index 9a9be6ff6..9c87746c6 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -109,7 +109,7 @@ ati18800_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -223,7 +223,7 @@ ati18800_recalctimings(svga_t *svga) else { svga->render = svga_render_8bpp_highres; if (!svga->packed_4bpp) { - svga->ma_latch <<= 1; + svga->memaddr_latch <<= 1; svga->rowoffset <<= 1; } } diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 156e95425..284abe78c 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -206,7 +206,7 @@ ati28800_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -416,10 +416,10 @@ ati28800_recalctimings(svga_t *svga) ((ati28800->regs[0xb9] & 2) << 1); if (ati28800->regs[0xa3] & 0x10) - svga->ma_latch |= 0x10000; + svga->memaddr_latch |= 0x10000; if (ati28800->regs[0xb0] & 0x40) - svga->ma_latch |= 0x20000; + svga->memaddr_latch |= 0x20000; if (ati28800->regs[0xb8] & 0x40) svga->clock *= 2; @@ -483,7 +483,7 @@ ati28800_recalctimings(svga_t *svga) else { svga->render = svga_render_8bpp_highres; if (!svga->packed_4bpp) { - svga->ma_latch <<= 1; + svga->memaddr_latch <<= 1; svga->rowoffset <<= 1; } } @@ -496,7 +496,7 @@ ati28800_recalctimings(svga_t *svga) svga->hdisp >>= 1; svga->dots_per_clock >>= 1; svga->rowoffset <<= 1; - svga->ma_latch <<= 1; + svga->memaddr_latch <<= 1; } break; default: diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 4ec9afff8..324023db1 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -37,6 +37,7 @@ #include <86box/video.h> #include <86box/i2c.h> #include <86box/vid_ddc.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #include <86box/vid_ati_eeprom.h> @@ -94,6 +95,7 @@ typedef struct mach64_t { int type; int pci; + int vlb; uint8_t pci_slot; uint8_t irq_state; @@ -424,7 +426,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, svga->ramdac, svga); + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, 0, svga->ramdac, svga); else svga_out(addr, val, svga); return; @@ -456,7 +458,7 @@ mach64_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = svga->monitor->mon_changeframecount; svga_recalctimings(svga); @@ -491,7 +493,7 @@ 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), svga->ramdac, svga); + return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), 0, svga->ramdac, svga); return svga_in(addr, svga); case 0x3D4: @@ -524,14 +526,18 @@ mach64_recalctimings(svga_t *svga) svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; svga->rowoffset = (mach64->crtc_off_pitch >> 22); svga->clock = (cpuclock * (double) (1ULL << 32)) / ics2595_getclock(svga->clock_gen); - svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2; + svga->memaddr_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2; svga->linedbl = svga->rowcount = 0; svga->split = 0xffffff; svga->vblankstart = svga->dispend; svga->rowcount = mach64->crtc_gen_cntl & 1; svga->rowoffset <<= 1; + if (mach64->type == MACH64_GX) ati68860_ramdac_set_render(svga->ramdac, svga); + + svga->packed_4bpp = !!(((mach64->crtc_gen_cntl >> 8) & 7) == BPP_4); + switch ((mach64->crtc_gen_cntl >> 8) & 7) { case BPP_4: if (mach64->type != MACH64_GX) @@ -572,14 +578,16 @@ mach64_recalctimings(svga_t *svga) } svga->vram_display_mask = mach64->vram_mask; - } else + } else { svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff; + } } void mach64_updatemapping(mach64_t *mach64) { svga_t *svga = &mach64->svga; + xga_t *xga = (xga_t *) svga->xga; if (mach64->pci && !(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { mach64_log("Update mapping - PCI disabled\n"); @@ -605,6 +613,8 @@ mach64_updatemapping(mach64_t *mach64) mem_mapping_set_p(&svga->mapping, mach64); mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) + xga->on = 0; break; case 0x8: /*32k at B0000*/ mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); @@ -1670,7 +1680,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) case MONO_SRC_PAT: if (mach64->dst_cntl & DST_24_ROT_EN) { if (!mach64->accel.xx_count) - mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; + mix = mach64->accel.pattern[dst_y & 7][(dst_x / 3) & 7]; } else mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; break; @@ -2310,6 +2320,7 @@ uint8_t mach64_ext_readb(uint32_t addr, void *priv) { mach64_t *mach64 = (mach64_t *) priv; + svga_t *svga = &mach64->svga; uint8_t ret = 0xff; if (!(addr & 0x400)) { @@ -2523,9 +2534,23 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0xc2: case 0xc3: if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga); - else - ret = ati68860_ramdac_in(addr & 3, mach64->svga.ramdac, &mach64->svga); + ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), 0, mach64->svga.ramdac, &mach64->svga); + else { + switch (addr & 3) { + case 0: + ret = svga_in(0x3c8, svga); + break; + case 1: + ret = svga_in(0x3c9, svga); + break; + case 2: + ret = svga_in(0x3c6, svga); + break; + case 3: + ret = svga_in(0x3c7, svga); + break; + } + } break; case 0xc4: case 0xc5: @@ -2962,7 +2987,7 @@ mach64_ext_readl(uint32_t addr, void *priv) uint32_t ret; if (!(addr & 0x400)) { - mach64_log("nmach64_ext_readl: addr=%04x\n", addr); + mach64_log("mach64_ext_readl: addr=%04x\n", addr); ret = 0xffffffff; } else switch (addr & 0x3ff) { @@ -3101,6 +3126,7 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) } else if (addr & 0x300) { mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE); } else { + mach64_log("mach64_ext_writeb: addr=%04x val=%02x\n", addr & 0x3ff, val); switch (addr & 0x3ff) { case 0x00: case 0x01: @@ -3189,39 +3215,48 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) case 0x62: case 0x63: WRITE8(addr, mach64->cur_clr0, val); - if (mach64->type == MACH64_VT2) - ati68860_ramdac_set_pallook(mach64->svga.ramdac, 0, makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff)); break; case 0x64: case 0x65: case 0x66: case 0x67: WRITE8(addr, mach64->cur_clr1, val); - if (mach64->type == MACH64_VT2) - ati68860_ramdac_set_pallook(mach64->svga.ramdac, 1, makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff)); break; case 0x68: case 0x69: case 0x6a: case 0x6b: WRITE8(addr, mach64->cur_offset, val); - svga->dac_hwcursor.addr = (mach64->cur_offset & 0xfffff) * 8; + if (mach64->type == MACH64_GX) + svga->dac_hwcursor.addr = (mach64->cur_offset & 0xfffff) << 3; + else + svga->hwcursor.addr = (mach64->cur_offset & 0xfffff) << 3; break; case 0x6c: case 0x6d: case 0x6e: case 0x6f: WRITE8(addr, mach64->cur_horz_vert_posn, val); - svga->dac_hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff; - svga->dac_hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff; + if (mach64->type == MACH64_GX) { + svga->dac_hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff; + svga->dac_hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff; + } else { + svga->hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff; + svga->hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff; + } break; case 0x70: case 0x71: case 0x72: case 0x73: WRITE8(addr, mach64->cur_horz_vert_off, val); - svga->dac_hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f; - svga->dac_hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f; + if (mach64->type == MACH64_GX) { + svga->dac_hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f; + svga->dac_hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f; + } else { + svga->hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f; + svga->hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f; + } break; case 0x80: @@ -3282,9 +3317,23 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) case 0xc2: case 0xc3: if (mach64->type == MACH64_GX) - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, svga->ramdac, svga); - else - ati68860_ramdac_out(addr & 3, val, svga->ramdac, svga); + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, 0, svga->ramdac, svga); + else { + switch (addr & 3) { + case 0: + svga_out(0x3c8, val, svga); + break; + case 1: + svga_out(0x3c9, val, svga); + break; + case 2: + svga_out(0x3c6, val, svga); + break; + case 3: + svga_out(0x3c7, val, svga); + break; + } + } break; case 0xc4: case 0xc5: @@ -3294,7 +3343,8 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) mach64_log("Ext RAMDAC TYPE write=%x, bit set=%03x.\n", addr & 0x3ff, mach64->dac_cntl & 0x100); if ((addr & 3) >= 1) { svga_set_ramdac_type(svga, !!(mach64->dac_cntl & 0x100)); - ati68860_set_ramdac_type(svga->ramdac, !!(mach64->dac_cntl & 0x100)); + if (mach64->type == MACH64_GX) + ati68860_set_ramdac_type(svga->ramdac, !!(mach64->dac_cntl & 0x100)); } i2c_gpio_set(mach64->i2c, !(mach64->dac_cntl & 0x20000000) || (mach64->dac_cntl & 0x04000000), !(mach64->dac_cntl & 0x10000000) || (mach64->dac_cntl & 0x02000000)); break; @@ -3306,7 +3356,10 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) WRITE8(addr, mach64->gen_test_cntl, val); ati_eeprom_write(&mach64->eeprom, mach64->gen_test_cntl & 0x10, mach64->gen_test_cntl & 2, mach64->gen_test_cntl & 1); mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0); - svga->dac_hwcursor.ena = mach64->gen_test_cntl & 0x80; + if (mach64->type == MACH64_GX) + svga->dac_hwcursor.ena = !!(mach64->gen_test_cntl & 0x80); + else + svga->hwcursor.ena = !!(mach64->gen_test_cntl & 0x80); break; case 0xdc: @@ -3371,6 +3424,7 @@ uint8_t mach64_ext_inb(uint16_t port, void *priv) { mach64_t *mach64 = (mach64_t *) priv; + svga_t *svga = &mach64->svga; uint8_t ret = 0xff; switch (port) { @@ -3384,6 +3438,12 @@ mach64_ext_inb(uint16_t port, void *priv) case 0x7eef: ret = mach64_ext_readb(0x400 | 0x00 | (port & 3), priv); break; + case 0x06ec: + case 0x06ed: + case 0x06ee: + case 0x06ef: + ret = mach64_ext_readb(0x400 | 0x04 | (port & 3), priv); + break; case 0x0aec: case 0x0aed: case 0x0aee: @@ -3518,9 +3578,23 @@ mach64_ext_inb(uint16_t port, void *priv) case 0x5eee: case 0x5eef: if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga); - else - ret = ati68860_ramdac_in(port & 3, mach64->svga.ramdac, &mach64->svga); + ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), 0, mach64->svga.ramdac, &mach64->svga); + else { + switch (port & 3) { + case 0: + ret = svga_in(0x3c8, svga); + break; + case 1: + ret = svga_in(0x3c9, svga); + break; + case 2: + ret = svga_in(0x3c6, svga); + break; + case 3: + ret = svga_in(0x3c7, svga); + break; + } + } break; case 0x62ec: @@ -3617,6 +3691,12 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *priv) case 0x7eef: mach64_ext_writeb(0x400 | 0x00 | (port & 3), val, priv); break; + case 0x06ec: + case 0x06ed: + case 0x06ee: + case 0x06ef: + mach64_ext_writeb(0x400 | 0x04 | (port & 3), val, priv); + break; case 0x0aec: case 0x0aed: case 0x0aee: @@ -3744,9 +3824,23 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *priv) case 0x5eee: case 0x5eef: if (mach64->type == MACH64_GX) - ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, svga->ramdac, svga); - else - ati68860_ramdac_out(port & 3, val, svga->ramdac, svga); + ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, 0, svga->ramdac, svga); + else { + switch (port & 3) { + case 0: + svga_out(0x3c8, val, svga); + break; + case 1: + svga_out(0x3c9, val, svga); + break; + case 2: + svga_out(0x3c6, val, svga); + break; + case 3: + svga_out(0x3c7, val, svga); + break; + } + } break; case 0x62ec: @@ -3768,7 +3862,7 @@ mach64_ext_outb(uint16_t port, uint8_t val, void *priv) case 0x6aee: case 0x6aef: WRITE8(port, mach64->config_cntl, val); - if (!mach64->pci) + if (mach64->vlb) mach64->linear_base = (mach64->config_cntl & 0x3ff0) << 18; mach64_updatemapping(mach64); @@ -3905,6 +3999,63 @@ mach64_readl(uint32_t addr, void *priv) return ret; } +void +mach64_int_hwcursor_draw(svga_t *svga, int displine) +{ + const mach64_t *mach64 = (mach64_t *) svga->priv; + int comb; + int offset; + int x_pos; + int y_pos; + int shift = 0; + uint16_t dat; + uint32_t col0 = makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff); + uint32_t col1 = makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff); + uint32_t *p; + + offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + if (svga->packed_4bpp) + shift = 1; + + for (int x = 0; x < svga->hwcursor_latch.cur_xsize; x += (8 >> shift)) { + if (shift) { + dat = svga->vram[(svga->hwcursor_latch.addr) & svga->vram_mask] & 0x0f; + dat |= (svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_mask] << 4); + dat |= (svga->vram[(svga->hwcursor_latch.addr + 2) & svga->vram_mask] << 8); + dat |= (svga->vram[(svga->hwcursor_latch.addr + 3) & svga->vram_mask] << 12); + } else { + dat = svga->vram[svga->hwcursor_latch.addr & svga->vram_mask]; + dat |= (svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_mask] << 8); + } + for (int xx = 0; xx < (8 >> shift); xx++) { + comb = (dat >> (xx << 1)) & 0x03; + + y_pos = displine; + x_pos = offset + svga->x_add; + p = buffer32->line[y_pos]; + + if (offset >= svga->hwcursor_latch.x) { + switch (comb) { + case 0: + p[x_pos] = col0; + break; + case 1: + p[x_pos] = col1; + break; + case 3: + p[x_pos] ^= 0xffffff; + break; + + default: + break; + } + } + offset++; + } + svga->hwcursor_latch.addr += 2; + } +} + #define CLAMP(x) \ do { \ if ((x) & ~0xff) \ @@ -4550,15 +4701,22 @@ mach64_common_init(const device_t *info) svga = &mach64->svga; + mach64->type = info->local & 0xff; mach64->vram_size = device_get_config_int("memory"); mach64->vram_mask = (mach64->vram_size << 20) - 1; - svga_init(info, svga, mach64, mach64->vram_size << 20, - mach64_recalctimings, - mach64_in, mach64_out, - NULL, - mach64_overlay_draw); - svga->dac_hwcursor.cur_ysize = 64; + if (mach64->type > MACH64_GX) + svga_init(info, svga, mach64, mach64->vram_size << 20, + mach64_recalctimings, + mach64_in, mach64_out, + mach64_int_hwcursor_draw, + mach64_overlay_draw); + else + svga_init(info, svga, mach64, mach64->vram_size << 20, + mach64_recalctimings, + mach64_in, mach64_out, + NULL, + mach64_overlay_draw); mem_mapping_add(&mach64->linear_mapping, 0, 0, mach64_read_linear, mach64_readw_linear, mach64_readl_linear, mach64_write_linear, mach64_writew_linear, mach64_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); @@ -4576,9 +4734,6 @@ mach64_common_init(const device_t *info) mach64->pci_regs[0x32] = 0x0c; mach64->pci_regs[0x33] = 0x00; - svga->ramdac = device_add(&ati68860_ramdac_device); - svga->dac_hwcursor_draw = ati68860_hwcursor_draw; - svga->clock_gen = device_add(&ics2595_device); mach64->dst_cntl = 3; @@ -4598,6 +4753,13 @@ static void * mach64gx_init(const device_t *info) { mach64_t *mach64 = mach64_common_init(info); + svga_t *svga = &mach64->svga; + + svga->ramdac = device_add(&ati68860_ramdac_device); + svga->dac_hwcursor_draw = ati68860_hwcursor_draw; + + svga->dac_hwcursor.cur_ysize = 64; + svga->dac_hwcursor.cur_xsize = 64; if (info->flags & DEVICE_ISA16) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_isa); @@ -4606,12 +4768,12 @@ mach64gx_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_vlb); - mach64->type = MACH64_GX; mach64->pci = !!(info->flags & DEVICE_PCI); + mach64->vlb = !!(info->flags & DEVICE_VLB); 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*/ + mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI 68860, 256Kx16 DRAM*/ if (info->flags & DEVICE_PCI) { mach64->config_stat0 |= 7; /*PCI, 256Kx16 DRAM*/ ati_eeprom_load(&mach64->eeprom, "mach64_pci.nvr", 1); @@ -4635,10 +4797,15 @@ mach64vt2_init(const device_t *info) mach64_t *mach64 = mach64_common_init(info); svga_t *svga = &mach64->svga; + svga->dac_hwcursor_draw = NULL; + + svga->hwcursor.cur_ysize = 64; + svga->hwcursor.cur_xsize = 64; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci); - mach64->type = MACH64_VT2; mach64->pci = 1; + mach64->vlb = 0; mach64->pci_id = 0x5654; mach64->config_chip_id = 0x40005654; mach64->dac_cntl = 1 << 16; /*Internal 24-bit DAC*/ @@ -4757,7 +4924,7 @@ const device_t mach64gx_isa_device = { .name = "ATI Mach64GX ISA", .internal_name = "mach64gx_isa", .flags = DEVICE_ISA16, - .local = 0, + .local = MACH64_GX, .init = mach64gx_init, .close = mach64_close, .reset = NULL, @@ -4771,7 +4938,7 @@ const device_t mach64gx_vlb_device = { .name = "ATI Mach64GX VLB", .internal_name = "mach64gx_vlb", .flags = DEVICE_VLB, - .local = 0, + .local = MACH64_GX, .init = mach64gx_init, .close = mach64_close, .reset = NULL, @@ -4785,7 +4952,7 @@ const device_t mach64gx_pci_device = { .name = "ATI Mach64GX PCI", .internal_name = "mach64gx_pci", .flags = DEVICE_PCI, - .local = 0, + .local = MACH64_GX, .init = mach64gx_init, .close = mach64_close, .reset = NULL, @@ -4799,7 +4966,7 @@ const device_t mach64vt2_device = { .name = "ATI Mach64VT2", .internal_name = "mach64vt2", .flags = DEVICE_PCI, - .local = 0, + .local = MACH64_VT2, .init = mach64vt2_init, .close = mach64_close, .reset = NULL, diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index ce6ee12d5..32b466740 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -270,7 +270,7 @@ mach_log(const char *fmt, ...) static int mach_pixel_write(mach_t *mach) { - if (mach->accel.dp_config & 1) + if (mach->accel.dp_config & 0x01) return 1; return 0; @@ -279,7 +279,7 @@ mach_pixel_write(mach_t *mach) static int mach_pixel_read(mach_t *mach) { - if (mach->accel.dp_config & 1) + if (mach->accel.dp_config & 0x01) return 0; return 1; @@ -817,6 +817,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.dy |= ~0x5ff; /*Destination Width*/ + mach->accel.dx_first_row_start = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + mach->accel.dx_first_row_start |= ~0x5ff; + mach->accel.dx_start = mach->accel.dest_x_start; if (mach->accel.dest_x_start >= 0x600) mach->accel.dx_start |= ~0x5ff; @@ -831,16 +835,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } else if (mach->accel.dx_end < mach->accel.dx_start) { mach->accel.width = (mach->accel.dx_start - mach->accel.dx_end); mach->accel.stepx = -1; - if (dev->accel.dx > 0) - dev->accel.dx--; - mach_log("BitBLT: Dst Negative X, dxstart = %d, end = %d, width = %d, dx = %d, dpconfig = %04x.\n", - mach->accel.dest_x_start, mach->accel.dest_x_end, mach->accel.width, dev->accel.dx, - mach->accel.dp_config); } else { mach->accel.stepx = 1; mach->accel.width = 0; - mach_log("BitBLT: Dst Indeterminate X, dpconfig = %04x, destxend = %d, destxstart = %d.\n", - mach->accel.dp_config, mach->accel.dest_x_end, mach->accel.dest_x_start); } dev->accel.sx = 0; @@ -869,6 +866,24 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach->accel.dp_config == 0x4011) mach->accel.height++; + if (mach->accel.height == 1) { + if (mach->accel.dx_end > mach->accel.dx_first_row_start) { + mach->accel.width = (mach->accel.dx_end - mach->accel.dx_first_row_start); + mach->accel.stepx = 1; + } else if (mach->accel.dx_end < mach->accel.dx_first_row_start) { + mach->accel.width = (mach->accel.dx_first_row_start - mach->accel.dx_end); + mach->accel.stepx = -1; + } else { + mach->accel.stepx = 1; + mach->accel.width = 0; + } + } + + if (mach->accel.stepx == -1) { + if (dev->accel.dx > 0) + dev->accel.dx--; + } + dev->accel.sy = 0; dev->accel.dest = mach->accel.dst_ge_offset + (dev->accel.dy * mach->accel.dst_pitch); @@ -2407,11 +2422,11 @@ mach_out(uint16_t addr, uint8_t val, void *priv) rs2 = !!(mach->accel.ext_ge_config & 0x1000); rs3 = !!(mach->accel.ext_ge_config & 0x2000); mach_log("8514/A Extended mode=%02x.\n", mach->regs[0xb0] & 0x20); - if (ATI_MACH32 && !dev->on) { - if (mach->pci_bus && !mach->ramdac_type) - ati68860_ramdac_out((addr & 0x03) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga); + if (ATI_MACH32) { + if (mach->pci_bus && (mach->ramdac_type == ATI_68860)) + ati68860_ramdac_out((addr & 0x03) | (rs2 << 2) | (rs3 << 3), val, 1, svga->ramdac, svga); else - ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + ati68875_ramdac_out(addr, rs2, rs3, val, 1, svga->ramdac, svga); } else svga_out(addr, val, svga); return; @@ -2423,11 +2438,11 @@ mach_out(uint16_t addr, uint8_t val, void *priv) rs2 = !!(mach->regs[0xa0] & 0x20); rs3 = !!(mach->regs[0xa0] & 0x40); mach_log("VGA Extended mode=%02x.\n", mach->regs[0xb0] & 0x20); - if (ATI_MACH32 && !dev->on) { - if (mach->pci_bus && !mach->ramdac_type) - ati68860_ramdac_out((addr & 0x03) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga); + if (ATI_MACH32) { + if (mach->pci_bus && (mach->ramdac_type == ATI_68860)) + ati68860_ramdac_out((addr & 0x03) | (rs2 << 2) | (rs3 << 3), val, 0, svga->ramdac, svga); else - ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + ati68875_ramdac_out(addr, rs2, rs3, val, 0, svga->ramdac, svga); } else svga_out(addr, val, svga); return; @@ -2461,7 +2476,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = svga->monitor->mon_changeframecount; svga_recalctimings(svga); @@ -2510,6 +2525,12 @@ mach_in(uint16_t addr, void *priv) case 0xa9: temp = svga->vc & 0xff; break; + case 0xaa: + if (ATI_GRAPHICS_ULTRA) + temp = 0x06; + else + temp = 0x00; + break; case 0xb0: temp = mach->regs[0xb0] | 0x80; temp &= ~0x18; @@ -2542,11 +2563,11 @@ mach_in(uint16_t addr, void *priv) case 0x2ed: rs2 = !!(mach->accel.ext_ge_config & 0x1000); rs3 = !!(mach->accel.ext_ge_config & 0x2000); - if (ATI_MACH32 && !dev->on) { - if (mach->pci_bus && !mach->ramdac_type) - temp = ati68860_ramdac_in((addr & 3) | (rs2 << 2) | (rs3 << 3), svga->ramdac, svga); + if (ATI_MACH32) { + if (mach->pci_bus && (mach->ramdac_type == ATI_68860)) + temp = ati68860_ramdac_in((addr & 3) | (rs2 << 2) | (rs3 << 3), 1, svga->ramdac, svga); else - temp = ati68875_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + temp = ati68875_ramdac_in(addr, rs2, rs3, 1, svga->ramdac, svga); } else temp = svga_in(addr, svga); break; @@ -2598,7 +2619,7 @@ ati_render_24bpp(svga_t *svga) if ((dev->displine + svga->y_add) < 0) return; - if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; if (dev->firstline_draw == 2000) @@ -2607,38 +2628,38 @@ ati_render_24bpp(svga_t *svga) if (mach->accel.ext_ge_config & 0x400) { /*BGR, Blue-(23:16), Green-(15:8), Red-(7:0)*/ for (int x = 0; x <= dev->h_disp; x += 4) { - dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[dev->memaddr & dev->vram_mask]); p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); - dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 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]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 9) & dev->vram_mask]); p[x + 3] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); - dev->ma += 12; + dev->memaddr += 12; } } else { /*RGB, Red-(23:16), Green-(15:8), Blue-(7:0)*/ for (int x = 0; x <= dev->h_disp; x += 4) { - dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[dev->memaddr & dev->vram_mask]); p[x] = dat & 0xffffff; - dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 3) & dev->vram_mask]); p[x + 1] = dat & 0xffffff; - dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 6) & dev->vram_mask]); p[x + 2] = dat & 0xffffff; - dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + 9) & dev->vram_mask]); p[x + 3] = dat & 0xffffff; - dev->ma += 12; + dev->memaddr += 12; } } - dev->ma &= dev->vram_mask; + dev->memaddr &= dev->vram_mask; } } @@ -2654,7 +2675,7 @@ ati_render_32bpp(svga_t *svga) 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) { + if (dev->changedvram[dev->memaddr >> 12] || dev->changedvram[(dev->memaddr >> 12) + 1] || dev->changedvram[(dev->memaddr >> 12) + 2] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; if (dev->firstline_draw == 2000) @@ -2663,97 +2684,95 @@ ati_render_32bpp(svga_t *svga) if (mach->accel.ext_ge_config & 0x400) { /*BGR, Blue-(23:16), Green-(15:8), Red-(7:0)*/ for (x = 0; x <= dev->h_disp; x++) { - dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 2)) & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 2)) & dev->vram_mask]); *p++ = ((dat & 0x00ff0000) >> 16) | (dat & 0x0000ff00) | ((dat & 0x000000ff) << 16); } } else { /*RGB, Red-(31:24), Green-(23:16), Blue-(15:8)*/ for (x = 0; x <= dev->h_disp; x++) { - dat = *(uint32_t *) (&dev->vram[(dev->ma + (x << 2)) & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[(dev->memaddr + (x << 2)) & dev->vram_mask]); *p++ = ((dat & 0xffffff00) >> 8); } } - dev->ma += (x * 4); - dev->ma &= dev->vram_mask; + dev->memaddr += (x * 4); + dev->memaddr &= dev->vram_mask; } } /*The situation is the following: - When ATI mode is selected, allow complete auto-detection. - But when 8514/A mode is selected, allow detection based on the shadow register sets. + When ATI (0x4aee) mode is selected, allow complete auto-detection. + When 8514/A (0x4ae8) mode is selected, allow detection based on the shadow register sets. */ - static void mach_set_resolution(mach_t *mach, svga_t *svga) { - ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - int ret = 0; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - dev->h_total = dev->htotal + 1; - - if (dev->h_total == 1) /*Default to 1024x768 87hz 8514/A htotal timings if it goes to 0.*/ + dev->h_total = (dev->htotal + 1); + if (dev->h_total == 8) /*Default to 1024x768 87hz 8514/A htotal timings if it goes to 0.*/ dev->h_total = 0x9e; dev->hdisp = (dev->hdisped + 1) << 3; dev->vdisp = (dev->v_disp + 1) >> 1; - if ((dev->vdisp == 478) || (dev->vdisp == 598) || (dev->vdisp == 766) || (dev->vdisp == 1022)) + if ((dev->vdisp == 478) || (dev->vdisp == 598) || (dev->vdisp == 766) || (dev->vdisp == 898) || (dev->vdisp == 1022)) dev->vdisp += 2; dev->v_total = dev->v_total_reg + 1; - if (dev->interlace) - dev->v_total >>= 1; + if (dev->v_total == 1) + dev->v_total = 0x0669; dev->v_syncstart = dev->v_sync_start + 1; - if (dev->interlace) - dev->v_syncstart >>= 1; + if (dev->v_syncstart == 1) + dev->v_syncstart = 0x0601; - if ((mach->accel.clock_sel & 0x01) && !(mach->old_on2 & 0x01) && - !(dev->accel.advfunc_cntl & 0x01)) - ret = 2; - else if ((dev->accel.advfunc_cntl & 0x01) && !(mach->old_on1 & 0x01) && - !(mach->accel.clock_sel & 0x01)) - ret = 1; - else if ((!(dev->accel.advfunc_cntl & 0x01) && (mach->old_on1 & 0x01)) || - (!(mach->accel.clock_sel & 0x01) && (mach->old_on2 & 0x01))) - ret = 0; + mach_log("ATI Mode: set=%02x, dispcntl=%02x, h_total=%d, hdisp=%d, vdisp=%d, v_total=%04x, v_syncstart=%04x, hsync_start=%d, hsync_width=%d, clocksel=%02x, advancedcntl=%02x.\n", mach->shadow_set & 0x03, dev->disp_cntl, dev->h_total, dev->hdisp, dev->vdisp, dev->v_total, dev->v_syncstart, dev->hsync_start, dev->hsync_width, mach->accel.clock_sel & 0xff, dev->accel.advfunc_cntl & 0x05); + if ((dev->disp_cntl >> 5) == 1) { /*Enable the 8514/A subsystem and set modes according to the shadow sets if needed.*/ + switch (mach->shadow_set & 0x03) { + case 0x01: + if (!(dev->accel.advfunc_cntl & 0x04)) { + dev->h_total = 0x64; + dev->hdisp = 640; + dev->vdisp = 480; + dev->v_total = 0x0419; + dev->v_syncstart = 0x03d7; + } + break; + case 0x02: + if (dev->accel.advfunc_cntl & 0x04) { + dev->h_total = 0x9e; + dev->hdisp = 1024; + dev->vdisp = 768; + dev->v_total = 0x0669; + dev->v_syncstart = 0x0601; + } + break; - if (ret) { - if (ret == 2) - svga_recalctimings(svga); - else { - switch (mach->shadow_set & 0x03) { - case 0x00: - if (mach->crt_resolution) - svga_recalctimings(svga); - else { - if (dev->accel.advfunc_cntl & 0x04) { - if (dev->hdisp == 640) { - dev->hdisp = 1024; - dev->vdisp = 768; - } - } else { - if (dev->hdisp == 1024) { - dev->hdisp = 640; - dev->vdisp = 480; - } - } - svga_recalctimings(svga); - } - break; - case 0x01: - mach->crt_resolution = 0x01; - break; - case 0x02: - mach->crt_resolution = 0x02; - break; - default: - break; + default: + break; + } + svga_recalctimings(svga); + } else if ((dev->disp_cntl >> 5) == 2) { /*Reset 8514/A to defaults if needed.*/ + if (dev->accel.advfunc_cntl & 0x04) { + if (dev->hdisp == 640) { + dev->h_total = 0x9e; + dev->hdisp = 1024; + dev->vdisp = 768; + dev->v_total = 0x0669; + dev->v_syncstart = 0x0601; + svga_recalctimings(svga); + } + } else { + if (dev->hdisp == 1024) { + dev->h_total = 0x64; + dev->hdisp = 640; + dev->vdisp = 480; + dev->v_total = 0x0419; + dev->v_syncstart = 0x03d7; + svga_recalctimings(svga); } } - } else + } else /*No change (type 0) or reset type 3.*/ svga_recalctimings(svga); - - mach_log("Shadow set ATI=%x, shadow set 8514/A and on1=%x, on2=%x, resolution h=%d, v=%d, vtotal=%d, vsyncstart=%d, crtres=%d, ret=%d, actual passthrough=%x.\n", mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x05, mach->accel.clock_sel & 0x01, dev->hdisp, dev->vdisp, dev->v_total, dev->v_syncstart, mach->crt_resolution, ret, dev->on); } void @@ -2764,7 +2783,6 @@ ati8514_recalctimings(svga_t *svga) mach_log("ON=%d, vgahdisp=%d.\n", dev->on, svga->hdisp); if (dev->on) { - mach_log("8514/A ON, pitch=%d.\n", dev->ext_pitch); dev->interlace = !!(dev->disp_cntl & 0x10); dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; @@ -2773,16 +2791,19 @@ ati8514_recalctimings(svga_t *svga) mach->accel.crt_offset = (mach->accel.crt_offset_lo | (mach->accel.crt_offset_hi << 16)) << 2; dev->accel.ge_offset -= mach->accel.crt_offset; + mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x, clocksel=%02x.\n", dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x05, mach->accel.clock_sel & 0x01); - mach->accel.src_pitch = ((mach->accel.ge_pitch & 0xff) << 3); - mach->accel.dst_pitch = ((mach->accel.ge_pitch & 0xff) << 3); + mach->accel.src_pitch = dev->pitch; + mach->accel.dst_pitch = dev->pitch; mach->accel.src_ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)) << 2; mach->accel.dst_ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)) << 2; mach->accel.src_ge_offset -= mach->accel.crt_offset; mach->accel.dst_ge_offset -= mach->accel.crt_offset; + mach_log("8514/A ON, pitch=%d, GE offset=%08x.\n", ((mach->accel.ge_pitch & 0xff) << 3), dev->accel.ge_offset); + dev->h_disp = dev->hdisp; dev->dispend = dev->vdisp; if (dev->dispend == 600) @@ -2809,8 +2830,9 @@ ati8514_recalctimings(svga_t *svga) } dev->accel_bpp = 8; svga->render8514 = ibm8514_render_8bpp; + } else - mach->crt_resolution = 0; + dev->mode = VGA_MODE; } static void @@ -2827,17 +2849,17 @@ mach_recalctimings(svga_t *svga) if (ATI_MACH32) { if (mach->regs[0xad] & 0x04) - svga->ma_latch |= 0x40000; + svga->memaddr_latch |= 0x40000; if (mach->regs[0xad] & 0x08) - svga->ma_latch |= 0x80000; + svga->memaddr_latch |= 0x80000; } if (mach->regs[0xa3] & 0x10) - svga->ma_latch |= 0x10000; + svga->memaddr_latch |= 0x10000; if (mach->regs[0xb0] & 0x40) - svga->ma_latch |= 0x20000; + svga->memaddr_latch |= 0x20000; if ((mach->regs[0xb6] & 0x18) >= 0x10) { svga->hdisp <<= 1; @@ -2864,9 +2886,9 @@ mach_recalctimings(svga_t *svga) svga->ati_4color = 0; } - mach_log("ON=%d, override=%d, gelo=%04x, gehi=%04x, vgahdisp=%d.\n", dev->on, svga->override, mach->accel.ge_offset_lo, mach->accel.ge_offset_hi, svga->hdisp); + mach_log("ON=%d, override=%d, gelo=%04x, gehi=%04x, crtlo=%04x, crthi=%04x, vgahdisp=%d.\n", dev->on, svga->override, mach->accel.ge_offset_lo, mach->accel.ge_offset_hi, mach->accel.crt_offset_lo, mach->accel.crt_offset_hi, svga->hdisp); if (dev->on) { - dev->ma_latch = 0; /*(mach->accel.crt_offset_lo | (mach->accel.crt_offset_hi << 16)) << 2;*/ + dev->memaddr_latch = 0; /*(mach->accel.crt_offset_lo | (mach->accel.crt_offset_hi << 16)) << 2;*/ dev->interlace = !!(dev->disp_cntl & 0x10); dev->pitch = dev->ext_pitch; dev->rowoffset = dev->ext_crt_pitch; @@ -2904,6 +2926,8 @@ mach_recalctimings(svga_t *svga) else if (dev->h_disp == 640) dev->dispend = 480; + dev->h_disp_time = dev->hdisp >> 3; + svga->clock_8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); if (mach->accel.clock_sel & 0x40) svga->clock_8514 *= 2; @@ -2914,8 +2938,8 @@ mach_recalctimings(svga_t *svga) if (ATI_MACH32) { switch ((mach->shadow_set >> 8) & 0x03) { case 0x00: - mach->accel.src_pitch = ((mach->accel.ge_pitch & 0xff) << 3); - mach->accel.dst_pitch = ((mach->accel.ge_pitch & 0xff) << 3); + mach->accel.src_pitch = dev->pitch; + mach->accel.dst_pitch = dev->pitch; mach->accel.src_ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); mach->accel.dst_ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); if (dev->bpp) { @@ -2937,7 +2961,7 @@ mach_recalctimings(svga_t *svga) dev->accel.dst_ge_offset = mach->accel.dst_ge_offset; break; case 0x01: - mach->accel.dst_pitch = ((mach->accel.ge_pitch & 0xff) << 3); + mach->accel.dst_pitch = dev->pitch; mach->accel.dst_ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); if (dev->bpp) mach->accel.dst_ge_offset <<= 1; @@ -2952,7 +2976,7 @@ mach_recalctimings(svga_t *svga) dev->accel.dst_ge_offset = mach->accel.dst_ge_offset; break; case 0x02: - mach->accel.src_pitch = ((mach->accel.ge_pitch & 0xff) << 3); + mach->accel.src_pitch = dev->pitch; mach->accel.src_ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); if (dev->bpp) mach->accel.src_ge_offset <<= 1; @@ -2972,6 +2996,7 @@ mach_recalctimings(svga_t *svga) mach_log("cntl=%d, clksel=%x, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d, vgahdisp=%d.\n", dev->accel.advfunc_cntl & 0x04, mach->accel.clock_sel & 0x01, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace, svga->hdisp); + mach_log("EXTGECONFIG bits 11-15=%04x.\n", mach->accel.ext_ge_config & 0x8800); if ((mach->accel.ext_ge_config & 0x800) || (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800))) { mach_log("hv=%d,%d, pitch=%d, rowoffset=%d, gextconfig=%03x, bpp=%d, shadow=%x, vgahdisp=%d.\n", dev->h_disp, dev->dispend, dev->pitch, dev->ext_crt_pitch, mach->accel.ext_ge_config & 0xcec0, @@ -3009,17 +3034,12 @@ mach_recalctimings(svga_t *svga) } } } else { - mach->accel.src_pitch = ((mach->accel.ge_pitch & 0xff) << 3); - mach->accel.dst_pitch = ((mach->accel.ge_pitch & 0xff) << 3); + mach->accel.src_pitch = dev->pitch; + mach->accel.dst_pitch = dev->pitch; mach->accel.src_ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); mach->accel.dst_ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); - if (dev->bpp) { - mach->accel.src_ge_offset <<= 1; - mach->accel.dst_ge_offset <<= 1; - } else { - mach->accel.src_ge_offset <<= 2; - mach->accel.dst_ge_offset <<= 2; - } + mach->accel.src_ge_offset <<= 2; + mach->accel.dst_ge_offset <<= 2; mach->accel.src_ge_offset -= mach->accel.crt_offset; mach->accel.dst_ge_offset -= mach->accel.crt_offset; @@ -3036,7 +3056,7 @@ mach_recalctimings(svga_t *svga) svga->render8514 = ibm8514_render_8bpp; } } else { - mach->crt_resolution = 0; + dev->mode = VGA_MODE; if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { mach_log("GDCREG5=%02x, ATTR10=%02x, ATI B0 bit 5=%02x, ON=%d.\n", svga->gdcreg[5] & 0x60, svga->attrregs[0x10] & 0x40, mach->regs[0xb0] & 0x20, dev->on); @@ -3070,7 +3090,7 @@ mach_recalctimings(svga_t *svga) else { svga->render = svga_render_8bpp_highres; if (!svga->packed_4bpp) { - svga->ma_latch <<= 1; + svga->memaddr_latch <<= 1; svga->rowoffset <<= 1; } } @@ -3209,7 +3229,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach_log("ATI 8514/A: V_DISP write 16E8=%d, vdisp2=%d.\n", dev->v_disp, dev->v_disp2); mach_log("ATI 8514/A: (0x%04x): vdisp=0x%02x.\n", port, val); } else { - if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/ + if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/ if (!(mach->shadow_cntl & 0x20)) { WRITE8(port, dev->v_disp, val); dev->v_disp &= 0x1fff; @@ -3222,7 +3242,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u if (len == 1) { if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/ if (!(mach->shadow_cntl & 0x20)) { - WRITE8(port, dev->v_disp, val); + WRITE8(port, dev->v_disp, val >> 8); dev->v_disp &= 0x1fff; } } @@ -3234,7 +3254,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0x1ae8: if (len == 2) { - if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/ + if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/ if (!(mach->shadow_cntl & 0x10) && val) { dev->v_sync_start = val; dev->v_sync_start &= 0x1fff; @@ -3243,7 +3263,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach_log("ATI 8514/A: V_SYNCSTART write 1AE8 = %d\n", dev->v_syncstart); mach_log("ATI 8514/A: (0x%04x): vsyncstart=0x%02x.\n", port, val); } else { - if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/ + if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/ if (!(mach->shadow_cntl & 0x10)) { WRITE8(port, dev->v_sync_start, val); dev->v_sync_start &= 0x1fff; @@ -3254,9 +3274,9 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0x1ae9: if (len == 1) { - if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/ + if ((mach->accel.clock_sel & 0x01) || (!(mach->accel.clock_sel & 0x01) && (mach->shadow_set & 0x03))) { /*For 8514/A mode, take the shadow sets into account.*/ if (!(mach->shadow_cntl & 0x10)) { - WRITE8(port, dev->v_sync_start, val); + WRITE8(port, dev->v_sync_start, val >> 8); dev->v_sync_start &= 0x1fff; } } @@ -3282,7 +3302,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0x42e8: case 0x42e9: - mach_log("VBLANK stat=%02x, val=%02x.\n", dev->subsys_stat, val); + mach_log("VBLANK status=%02x, val=%02x.\n", dev->subsys_stat, val); if (len == 2) dev->subsys_cntl = val; else { @@ -3303,7 +3323,6 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0x4ae8: case 0x4ae9: - mach->old_on1 = dev->accel.advfunc_cntl & 0x01; WRITE8(port, dev->accel.advfunc_cntl, val); if (len == 2) { WRITE8(port + 1, dev->accel.advfunc_cntl, val >> 8); @@ -3317,6 +3336,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } } + dev->mode = IBM_MODE; mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): ON=%d, valxor=%x, shadow crt=%x, hdisp=%d, vdisp=%d, extmode=%02x, accelbpp=%d, crt=%d, crtres=%d.\n", CS, cpu_state.pc, port, val & 0x01, dev->on, dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp, mach->regs[0xb0] & 0x20, dev->accel_bpp, dev->_8514crt, mach->crt_resolution); @@ -3655,7 +3675,11 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } else dev->_8514crt = 1; - mach_set_resolution(mach, svga); + if (dev->mode != VGA_MODE) + mach_set_resolution(mach, svga); + else + svga_recalctimings(svga); + if (ATI_GRAPHICS_ULTRA || ATI_MACH32) mach32_updatemapping(mach, svga); @@ -3748,13 +3772,15 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u case 0x4aee: case 0x4aef: - mach->old_on2 = mach->accel.clock_sel & 0x01; WRITE8(port, mach->accel.clock_sel, val); if (len == 2) { WRITE8(port + 1, mach->accel.clock_sel, val >> 8); } - dev->on = mach->accel.clock_sel & 0x01; + if (!(dev->accel.advfunc_cntl & 0x01)) + dev->on = mach->accel.clock_sel & 0x01; + dev->vendor_mode = 1; + dev->mode = ATI_MODE; mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): ON=%d, val=%04x, xor=%d, hdisp=%d, vdisp=%d, accelbpp=%d.\n", CS, cpu_state.pc, port, mach->accel.clock_sel & 0x01, val, dev->on, dev->hdisp, dev->vdisp, dev->accel_bpp); @@ -3906,7 +3932,11 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } svga_set_ramdac_type(svga, !!(mach->accel.ext_ge_config & 0x4000)); mach_log("ATI 8514/A: (0x%04x) Extended Configuration=%04x, val=%04x.\n", port, mach->accel.ext_ge_config, val); - mach_set_resolution(mach, svga); + if (dev->mode != VGA_MODE) + mach_set_resolution(mach, svga); + else + svga_recalctimings(svga); + mach32_updatemapping(mach, svga); } else ati_eeprom_write(&mach->eeprom, !!(mach->accel.ext_ge_config & 0x04), !!(mach->accel.ext_ge_config & 0x02), !!(mach->accel.ext_ge_config & 0x01)); @@ -3957,7 +3987,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0x92ee: - mach_log("Write port 92ee, malatch=%08x.\n", svga->ma_latch); + mach_log("Write port 92ee, malatch=%08x.\n", svga->memaddr_latch); break; case 0x96ee: @@ -4212,7 +4242,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; default: - mach_log("Unknown or reserved write to %04x, val=%04x, len=%d, latch=%08x.\n", port, val, len, svga->ma_latch); + mach_log("Unknown or reserved write to %04x, val=%04x, len=%d, latch=%08x.\n", port, val, len, svga->memaddr_latch); break; } } @@ -4264,13 +4294,19 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in if (dev->force_busy) { temp |= 0x0200; /*Hardware busy*/ if (mach->accel.cmd_type >= 0) { + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; mono_src = (mach->accel.dp_config >> 5) & 3; switch (mach->accel.cmd_type) { case 2: if (dev->accel.sy >= mach->accel.height) dev->force_busy = 0; - else if (mono_src == 2) + else if ((mono_src == 2) || (frgd_sel == 2) || (bkgd_sel == 2)) dev->force_busy = 0; + else if (!dev->accel.cmd_back) + dev->force_busy = 0; + + mach_log("2Force Busy=%d, frgdsel=%d, bkgdsel=%d, monosrc=%d, read=%d, dpconfig=%04x, back=%d.\n", dev->force_busy, frgd_sel, bkgd_sel, mono_src, mach_pixel_read(mach), mach->accel.dp_config, dev->accel.cmd_back); break; case 5: if (dev->accel.sx >= mach->accel.width) @@ -4727,7 +4763,6 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) } } else { switch (mach->accel.cmd_type) { - case 1: case 2: case 5: if ((dev->subsys_cntl & INT_GE_BSY) && @@ -4738,6 +4773,7 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) (dev->accel.dy <= clip_b)) temp |= INT_GE_BSY; break; + case 1: case 3: case 4: if ((dev->subsys_cntl & INT_GE_BSY) && @@ -6182,6 +6218,7 @@ static void mach32_updatemapping(mach_t *mach, svga_t *svga) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + xga_t *xga = (xga_t *) svga->xga; if (mach->pci_bus && (!(mach->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) { mach_log("No Mapping.\n"); @@ -6202,6 +6239,11 @@ mach32_updatemapping(mach_t *mach, svga_t *svga) case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) { + xga->on = 0; + 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); + } break; case 0x8: /*32k at B0000*/ mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); @@ -6458,6 +6500,7 @@ ati8514_io_set(svga_t *svga) io_sethandler(0xeeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0xf2ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0xf6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); + io_sethandler(0xfaee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0xfeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); } @@ -7035,7 +7078,7 @@ mach8_init(const device_t *info) dev->type = info->flags; dev->local = info->local & 0xff; mach->has_bios = !(info->local & 0xff00); - mach->ramdac_type = mach->pci_bus ? device_get_config_int("ramdac") : 1; + mach->ramdac_type = mach->pci_bus ? device_get_config_int("ramdac") : ATI_68875; dev->vram_amount = device_get_config_int("memory"); dev->vram_512k_8514 = dev->vram_amount == 512; @@ -7086,7 +7129,7 @@ mach8_init(const device_t *info) dev->vram_mask = dev->vram_size - 1; dev->hwcursor.cur_ysize = 64; mach->config1 = 0x20; - if (mach->pci_bus && !mach->ramdac_type) + if (mach->pci_bus && (mach->ramdac_type == ATI_68860)) svga->ramdac = device_add(&ati68860_ramdac_device); else svga->ramdac = device_add(&ati68875_ramdac_device); @@ -7109,10 +7152,10 @@ mach8_init(const device_t *info) } else if (mach->pci_bus) { video_inform(VIDEO_FLAG_TYPE_8514, &timing_mach32_pci); mach->config1 |= 0x0e; - if (mach->ramdac_type) - mach->config1 |= 0x0400; - else + if (mach->ramdac_type == ATI_68860) mach->config1 |= 0x0a00; + else + mach->config1 |= 0x0400; mach->config2 |= 0x2000; svga->clock_gen = device_add(&ati18811_1_device); } else { @@ -7147,6 +7190,7 @@ mach8_init(const device_t *info) dev->on = 0; dev->pitch = 1024; + dev->ext_pitch = 1024; dev->ext_crt_pitch = 0x80; dev->accel_bpp = 8; svga->force_old_addr = 1; @@ -7160,6 +7204,7 @@ mach8_init(const device_t *info) mach_io_set(mach); mach->accel.cmd_type = -2; dev->accel.cmd_back = 1; + dev->mode = IBM_MODE; if (ATI_MACH32) { svga->decode_mask = (4 << 20) - 1; @@ -7209,6 +7254,7 @@ ati8514_init(svga_t *svga, void *ext8514, void *dev8514) /*Init as 1024x768 87hz interlaced first, per 8514/A.*/ dev->on = 0; dev->pitch = 1024; + dev->ext_pitch = 1024; dev->ext_crt_pitch = 0x80; dev->accel_bpp = 8; dev->rowoffset = 0x80; @@ -7219,8 +7265,8 @@ ati8514_init(svga_t *svga, void *ext8514, void *dev8514) dev->v_sync_start = 0x0600; dev->disp_cntl = 0x33; mach->accel.clock_sel = 0x1c; - mach->shadow_set = 0x02; dev->accel.cmd_back = 1; + dev->mode = IBM_MODE; io_sethandler(0x02ea, 4, ati8514_in, NULL, NULL, ati8514_out, NULL, NULL, svga); ati8514_io_set(svga); @@ -7358,12 +7404,12 @@ static const device_config_t mach32_pci_config[] = { .description = "RAMDAC type", .type = CONFIG_SELECTION, .default_string = NULL, - .default_int = 0, + .default_int = ATI_68860, .file_filter = NULL, .spinner = { 0 }, .selection = { - { .description = "ATI 68860", .value = 0 }, - { .description = "ATI 68875", .value = 1 }, + { .description = "ATI 68860", .value = ATI_68860 }, + { .description = "ATI 68875", .value = ATI_68875 }, { .description = "" } }, .bios = { { 0 } } @@ -7393,7 +7439,7 @@ const device_t mach8_vga_isa_device = { .name = "ATI Mach8 (ATI Graphics Ultra) (ISA)", .internal_name = "mach8_vga_isa", .flags = DEVICE_ISA, - .local = 1, + .local = ATI_38800_TYPE, .init = mach8_init, .close = mach_close, .reset = mach_reset, @@ -7407,7 +7453,7 @@ const device_t mach32_isa_device = { .name = "ATI Mach32 (ISA)", .internal_name = "mach32_isa", .flags = DEVICE_ISA, - .local = 2, + .local = ATI_68800_TYPE, .init = mach8_init, .close = mach_close, .reset = mach_reset, @@ -7421,7 +7467,7 @@ const device_t mach32_vlb_device = { .name = "ATI Mach32 (VLB)", .internal_name = "mach32_vlb", .flags = DEVICE_VLB, - .local = 2, + .local = ATI_68800_TYPE, .init = mach8_init, .close = mach_close, .reset = mach_reset, @@ -7435,7 +7481,7 @@ const device_t mach32_mca_device = { .name = "ATI Mach32 (MCA)", .internal_name = "mach32_mca", .flags = DEVICE_MCA, - .local = 2, + .local = ATI_68800_TYPE, .init = mach8_init, .close = mach_close, .reset = mach_reset, @@ -7449,7 +7495,7 @@ const device_t mach32_pci_device = { .name = "ATI Mach32 (PCI)", .internal_name = "mach32_pci", .flags = DEVICE_PCI, - .local = 2, + .local = ATI_68800_TYPE, .init = mach8_init, .close = mach_close, .reset = mach_reset, @@ -7463,7 +7509,7 @@ const device_t mach32_onboard_pci_device = { .name = "ATI Mach32 (PCI) On-Board", .internal_name = "mach32_pci_onboard", .flags = DEVICE_PCI, - .local = 2 | 0x100, + .local = ATI_68800_TYPE | 0x100, .init = mach8_init, .close = mach_close, .reset = mach_reset, diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c index 36185214c..0ea268ef7 100644 --- a/src/video/vid_bochs_vbe.c +++ b/src/video/vid_bochs_vbe.c @@ -336,13 +336,13 @@ bochs_vbe_recalctimings(svga_t* svga) if (svga->bpp == 4) { svga->rowoffset = (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] / 2) >> 3; - svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + + svga->memaddr_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3); svga->fullchange = 3; } else { svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)); - svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + + svga->memaddr_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8))); svga->fullchange = 3; } @@ -470,11 +470,11 @@ bochs_vbe_outw(const uint16_t addr, const uint16_t val, void *priv) svga_t *svga = &dev->svga; if (svga->bpp == 4) { svga->rowoffset = (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] / 2) >> 3; - svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + + svga->memaddr_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3); } else { svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)); - svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + + svga->memaddr_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8))); } @@ -511,7 +511,7 @@ bochs_vbe_outw(const uint16_t addr, const uint16_t val, void *priv) svga_recalctimings(&dev->svga); if (!(val & VBE_DISPI_NOCLEARMEM)) { memset(dev->svga.vram, 0, - dev->vbe_regs[VBE_DISPI_INDEX_YRES] * dev->svga.rowoffset); + (size_t) dev->vbe_regs[VBE_DISPI_INDEX_YRES] * dev->svga.rowoffset); } } else dev->svga.read_bank = dev->svga.write_bank = 0; @@ -575,7 +575,7 @@ bochs_vbe_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -811,22 +811,22 @@ bochs_vbe_init(const device_t *info) dev->vram_size = device_get_config_int("memory") * (1 << 20); rom_init(&dev->bios_rom, "roms/video/bochs/VGABIOS-lgpl-latest.bin", - 0xc0000, 0x10000, 0xffff, 0x0000, + 0xc0000, 0x8000, 0x7fff, 0x0000, MEM_MAPPING_EXTERNAL); if (dev->id5_val == VBE_DISPI_ID4) { /* Patch the BIOS to match the PCI ID. */ dev->bios_rom.rom[0x010c] = 0xee; - dev->bios_rom.rom[0x8dff] -= (0xee - 0x34); + dev->bios_rom.rom[0x7fff] -= (0xee - 0x34); dev->bios_rom.rom[0x010d] = 0x80; - dev->bios_rom.rom[0x8dff] -= (0x80 - 0x12); + dev->bios_rom.rom[0x7fff] -= (0x80 - 0x12); dev->bios_rom.rom[0x010e] = 0xef; - dev->bios_rom.rom[0x8dff] -= (0xef - 0x11); + dev->bios_rom.rom[0x7fff] -= (0xef - 0x11); dev->bios_rom.rom[0x010f] = 0xbe; - dev->bios_rom.rom[0x8dff] -= (0xbe - 0x11); + dev->bios_rom.rom[0x7fff] -= (0xbe - 0x11); } video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_bochs); diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index a24162019..1ca742890 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -8,15 +8,13 @@ * * Emulation of the old and new IBM CGA graphics cards. * - * - * * Authors: Sarah Walker, * Miran Grca, * W. M. Martinez, * * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. - * Copyright 2023 W. M. Martinez + * Copyright 2023 W. M. Martinez */ #include #include @@ -48,8 +46,10 @@ #define DOUBLE_INTERPOLATE_SRGB 2 #define DOUBLE_INTERPOLATE_LINEAR 3 -typedef union -{ +#define DEVICE_VRAM 0x4000 +#define DEVICE_VRAM_MASK 0x3fff + +typedef union { uint32_t color; struct { uint8_t b; @@ -73,10 +73,10 @@ void cga_recalctimings(cga_t *cga); static void cga_update_latch(cga_t *cga) { - uint32_t lp_latch = cga->displine * cga->crtc[1]; + uint32_t lp_latch = cga->displine * cga->crtc[CGA_CRTC_HDISP]; - cga->crtc[0x10] = (lp_latch >> 8) & 0x3f; - cga->crtc[0x11] = lp_latch & 0xff; + cga->crtc[CGA_CRTC_LIGHT_PEN_ADDR_HIGH] = (lp_latch >> 8) & 0x3f; + cga->crtc[CGA_CRTC_LIGHT_PEN_ADDR_LOW] = lp_latch & 0xff; } void @@ -89,20 +89,22 @@ cga_out(uint16_t addr, uint8_t val, void *priv) addr = (addr & 0xff9) | 0x004; switch (addr) { - case 0x3D4: + case CGA_REGISTER_CRTC_INDEX: cga->crtcreg = val & 31; return; - case 0x3D5: + case CGA_REGISTER_CRTC_DATA: old = cga->crtc[cga->crtcreg]; cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; if (old != val) { + // Recalc the timings if we are writing any invalid CRTC register or a valid CRTC register + // except the CURSOR and LIGHT PEN registers if ((cga->crtcreg < 0xe) || (cga->crtcreg > 0x11)) { cga->fullchange = changeframecount; cga_recalctimings(cga); } } return; - case 0x3D8: + case CGA_REGISTER_MODE_CONTROL: old = cga->cgamode; cga->cgamode = val; @@ -113,18 +115,18 @@ cga_out(uint16_t addr, uint8_t val, void *priv) cga_recalctimings(cga); } return; - case 0x3D9: + case CGA_REGISTER_COLOR_SELECT: old = cga->cgacol; cga->cgacol = val; if (old ^ val) cga_recalctimings(cga); return; - case 0x3DB: + case CGA_REGISTER_CLEAR_LIGHT_PEN_LATCH: if (cga->lp_strobe == 1) cga->lp_strobe = 0; return; - case 0x3DC: + case CGA_REGISTER_SET_LIGHT_PEN_LATCH: if (cga->lp_strobe == 0) { cga->lp_strobe = 1; cga_update_latch(cga); @@ -146,21 +148,20 @@ cga_in(uint16_t addr, void *priv) addr = (addr & 0xff9) | 0x004; switch (addr) { - case 0x3D4: + case CGA_REGISTER_CRTC_INDEX: ret = cga->crtcreg; break; - case 0x3D5: + case CGA_REGISTER_CRTC_DATA: ret = cga->crtc[cga->crtcreg]; break; - case 0x3DA: + case CGA_REGISTER_STATUS: ret = cga->cgastat; break; - - case 0x3DB: + case CGA_REGISTER_CLEAR_LIGHT_PEN_LATCH: if (cga->lp_strobe == 1) cga->lp_strobe = 0; break; - case 0x3DC: + case CGA_REGISTER_SET_LIGHT_PEN_LATCH: if (cga->lp_strobe == 0) { cga->lp_strobe = 1; cga_update_latch(cga); @@ -205,11 +206,11 @@ cga_write(uint32_t addr, uint8_t val, void *priv) { cga_t *cga = (cga_t *) priv; - cga->vram[addr & 0x3fff] = val; + cga->vram[addr & DEVICE_VRAM_MASK] = val; if (cga->snow_enabled) { int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc; - cga->charbuffer[offset] = cga->vram[addr & 0x3fff]; - cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff]; + cga->charbuffer[offset] = cga->vram[addr & DEVICE_VRAM_MASK]; + cga->charbuffer[offset | 1] = cga->vram[addr & DEVICE_VRAM_MASK]; } cga_waitstates(cga); } @@ -222,10 +223,10 @@ cga_read(uint32_t addr, void *priv) cga_waitstates(cga); if (cga->snow_enabled) { int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc; - cga->charbuffer[offset] = cga->vram[addr & 0x3fff]; - cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff]; + cga->charbuffer[offset] = cga->vram[addr & DEVICE_VRAM_MASK]; + cga->charbuffer[offset | 1] = cga->vram[addr & DEVICE_VRAM_MASK]; } - return cga->vram[addr & 0x3fff]; + return cga->vram[addr & DEVICE_VRAM_MASK]; } void @@ -235,12 +236,12 @@ cga_recalctimings(cga_t *cga) double _dispontime; double _dispofftime; - if (cga->cgamode & 1) { - disptime = (double) (cga->crtc[0] + 1); - _dispontime = (double) cga->crtc[1]; + if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) { + disptime = (double) (cga->crtc[CGA_CRTC_HTOTAL] + 1); + _dispontime = (double) cga->crtc[CGA_CRTC_HDISP]; } else { - disptime = (double) ((cga->crtc[0] + 1) << 1); - _dispontime = (double) (cga->crtc[1] << 1); + disptime = (double) ((cga->crtc[CGA_CRTC_HTOTAL] + 1) << 1); + _dispontime = (double) (cga->crtc[CGA_CRTC_HDISP] << 1); } _dispofftime = disptime - _dispontime; _dispontime = _dispontime * CGACONST; @@ -252,95 +253,97 @@ cga_recalctimings(cga_t *cga) static void cga_render(cga_t *cga, int line) { - uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; + uint16_t cursoraddr = (cga->crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (cga->crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & DEVICE_VRAM_MASK; int drawcursor; int x; - int c; + int column; uint8_t chr; uint8_t attr; 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; + int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS); + + if (((cga->cgamode & highres_graphics_flag) == highres_graphics_flag)) { + for (column = 0; column < 8; ++column) { + buffer32->line[line][column] = 0; + if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) + buffer32->line[line][column + (cga->crtc[CGA_CRTC_HDISP] << 3) + 8] = 0; else - buffer32->line[line][c + (cga->crtc[1] << 4) + 8] = 0; + buffer32->line[line][column + (cga->crtc[CGA_CRTC_HDISP] << 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; + for (column = 0; column < 8; ++column) { + buffer32->line[line][column] = (cga->cgacol & 15) + 16; + if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) + buffer32->line[line][column + (cga->crtc[CGA_CRTC_HDISP] << 3) + 8] = (cga->cgacol & 15) + 16; else - buffer32->line[line][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16; + buffer32->line[line][column + (cga->crtc[CGA_CRTC_HDISP] << 4) + 8] = (cga->cgacol & 15) + 16; } } - if (cga->cgamode & 1) { - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) { + if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) { /* 80-column text */ + for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) { + if (cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) { chr = cga->charbuffer[x << 1]; attr = cga->charbuffer[(x << 1) + 1]; } else chr = attr = 0; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + drawcursor = ((cga->memaddr == cursoraddr) && cga->cursorvisible && cga->cursoron); cols[1] = (attr & 15) + 16; - if (cga->cgamode & 0x20) { + if (cga->cgamode & CGA_MODE_FLAG_BLINK) { 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; + for (column = 0; column < 8; column++) { + buffer32->line[line][(x << 3) + column + 8] + = cols[(fontdat[chr + cga->fontbase][cga->scanline & 7] & (1 << (column ^ 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]; + for (column = 0; column < 8; column++) { + buffer32->line[line][(x << 3) + column + 8] + = cols[(fontdat[chr + cga->fontbase][cga->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0]; } } - cga->ma++; + cga->memaddr++; } - } 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 if (!(cga->cgamode & CGA_MODE_FLAG_GRAPHICS)) { + for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) { + if (cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) { + chr = cga->vram[(cga->memaddr << 1) & DEVICE_VRAM_MASK]; + attr = cga->vram[((cga->memaddr << 1) + 1) & DEVICE_VRAM_MASK]; } else chr = attr = 0; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + drawcursor = ((cga->memaddr == cursoraddr) && cga->cursorvisible && cga->cursoron); cols[1] = (attr & 15) + 16; - if (cga->cgamode & 0x20) { + if (cga->cgamode & CGA_MODE_FLAG_BLINK) { cols[0] = ((attr >> 4) & 7) + 16; if ((cga->cgablink & 8) && (attr & 0x80)) cols[1] = cols[0]; } else cols[0] = (attr >> 4) + 16; - cga->ma++; + cga->memaddr++; 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; + for (column = 0; column < 8; column++) { + buffer32->line[line][(x << 4) + (column << 1) + 8] + = buffer32->line[line][(x << 4) + (column << 1) + 9] + = cols[(fontdat[chr + cga->fontbase][cga->scanline & 7] & (1 << (column ^ 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]; + for (column = 0; column < 8; column++) { + buffer32->line[line][(x << 4) + (column << 1) + 8] + = buffer32->line[line][(x << 4) + (column << 1) + 9] + = cols[(fontdat[chr + cga->fontbase][cga->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0]; } } } - } else if (!(cga->cgamode & 16)) { + } else if (!(cga->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) { /* not hi-res (but graphics) => 4-color mode */ cols[0] = (cga->cgacol & 15) | 16; col = (cga->cgacol & 16) ? 24 : 16; - if (cga->cgamode & 4) { + if (cga->cgamode & CGA_MODE_FLAG_BW) { cols[1] = col | 3; /* Cyan */ cols[2] = col | 4; /* Red */ cols[3] = col | 7; /* White */ @@ -353,32 +356,32 @@ cga_render(cga_t *cga, int line) 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]; + for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) { + if (cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) + dat = (cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 1) * 0x2000)] << 8) | + cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 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] + cga->memaddr++; + for (column = 0; column < 8; column++) { + buffer32->line[line][(x << 4) + (column << 1) + 8] + = buffer32->line[line][(x << 4) + (column << 1) + 9] = cols[dat >> 14]; dat <<= 2; } } - } else { + } else { /* 2-color hi-res graphics mode */ 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]; + for (x = 0; x < cga->crtc[CGA_CRTC_HDISP]; x++) { + if (cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) + dat = (cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 1) * 0x2000)] << 8) | + cga->vram[((cga->memaddr << 1) & 0x1fff) + ((cga->scanline & 1) * 0x2000) + 1]; else dat = 0; - cga->ma++; - for (c = 0; c < 16; c++) { - buffer32->line[line][(x << 4) + c + 8] = cols[dat >> 15]; + cga->memaddr++; + for (column = 0; column < 16; column++) { + buffer32->line[line][(x << 4) + column + 8] = cols[dat >> 15]; dat <<= 1; } } @@ -388,12 +391,14 @@ cga_render(cga_t *cga, int line) static void cga_render_blank(cga_t *cga, int line) { - int col = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16; + int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS); - if (cga->cgamode & 1) - hline(buffer32, 0, line, (cga->crtc[1] << 3) + 16, col); + int col = ((cga->cgamode & highres_graphics_flag) == highres_graphics_flag) ? 0 : (cga->cgacol & 15) + 16; + + if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) + hline(buffer32, 0, line, (cga->crtc[CGA_CRTC_HDISP] << 3) + 16, col); else - hline(buffer32, 0, line, (cga->crtc[1] << 4) + 16, col); + hline(buffer32, 0, line, (cga->crtc[CGA_CRTC_HDISP] << 4) + 16, col); } static void @@ -401,14 +406,15 @@ cga_render_process(cga_t *cga, int line) { int x; uint8_t border; + int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS); - if (cga->cgamode & 1) - x = (cga->crtc[1] << 3) + 16; + if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) + x = (cga->crtc[CGA_CRTC_HDISP] << 3) + 16; else - x = (cga->crtc[1] << 4) + 16; + x = (cga->crtc[CGA_CRTC_HDISP] << 4) + 16; if (cga->composite) { - border = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15); + border = ((cga->cgamode & highres_graphics_flag) == highres_graphics_flag) ? 0 : (cga->cgacol & 15); Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[line]); } else @@ -492,7 +498,7 @@ cga_interpolate(cga_t *cga, int x, int y, int w, int h) 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); + final = cga_interpolate_lookup(cga, interim_1, interim_2, quotient); buffer32->line[i][j] = final.color; } @@ -513,7 +519,7 @@ cga_poll(void *priv) { cga_t *cga = (cga_t *) priv; int x; - int oldsc; + int scanline_old; int oldvc; int xs_temp; int ys_temp; @@ -523,9 +529,9 @@ cga_poll(void *priv) timer_advance_u64(&cga->timer, cga->dispofftime); cga->cgastat |= 1; cga->linepos = 1; - oldsc = cga->sc; - if ((cga->crtc[8] & 3) == 3) - cga->sc = ((cga->sc << 1) + cga->oddeven) & 7; + scanline_old = cga->scanline; + if ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3) + cga->scanline = ((cga->scanline << 1) + cga->oddeven) & 7; if (cga->cgadispon) { if (cga->displine < cga->firstline) { cga->firstline = cga->displine; @@ -541,9 +547,9 @@ cga_poll(void *priv) cga_render(cga, cga->displine); break; case DOUBLE_SIMPLE: - old_ma = cga->ma; + old_ma = cga->memaddr; cga_render(cga, cga->displine << 1); - cga->ma = old_ma; + cga->memaddr = old_ma; cga_render(cga, (cga->displine << 1) + 1); break; } @@ -572,8 +578,8 @@ cga_poll(void *priv) break; } - cga->sc = oldsc; - if (cga->vc == cga->crtc[7] && !cga->sc) + cga->scanline = scanline_old; + if (cga->vc == cga->crtc[CGA_CRTC_VSYNC] && !cga->scanline) cga->cgastat |= 8; cga->displine++; if (cga->displine >= 360) @@ -586,41 +592,41 @@ 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))) { - cga->con = 0; - cga->coff = 1; + if (cga->scanline == (cga->crtc[CGA_CRTC_CURSOR_END] & 31) || ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && + cga->scanline == ((cga->crtc[CGA_CRTC_CURSOR_END] & 31) >> 1))) { + cga->cursorvisible = 0; } - if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1)) - cga->maback = cga->ma; + if ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && cga->scanline == (cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1)) + cga->memaddr_backup = cga->memaddr; if (cga->vadj) { - cga->sc++; - cga->sc &= 31; - cga->ma = cga->maback; + cga->scanline++; + cga->scanline &= 31; + cga->memaddr = cga->memaddr_backup; cga->vadj--; if (!cga->vadj) { cga->cgadispon = 1; - cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; - cga->sc = 0; + cga->memaddr = cga->memaddr_backup = (cga->crtc[CGA_CRTC_START_ADDR_LOW] | (cga->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & DEVICE_VRAM_MASK; + cga->scanline = 0; } - } else if (cga->sc == cga->crtc[9]) { - cga->maback = cga->ma; - cga->sc = 0; + } else if (cga->scanline == cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR]) { + cga->memaddr_backup = cga->memaddr; + cga->scanline = 0; oldvc = cga->vc; cga->vc++; cga->vc &= 127; - if (cga->vc == cga->crtc[6]) + if (cga->vc == cga->crtc[CGA_CRTC_VDISP]) cga->cgadispon = 0; - if (oldvc == cga->crtc[4]) { + if (oldvc == cga->crtc[CGA_CRTC_VTOTAL]) { cga->vc = 0; - cga->vadj = cga->crtc[5]; + cga->vadj = cga->crtc[CGA_CRTC_VTOTAL_ADJUST]; if (!cga->vadj) { cga->cgadispon = 1; - cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; + cga->memaddr = cga->memaddr_backup = (cga->crtc[CGA_CRTC_START_ADDR_LOW] | (cga->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & DEVICE_VRAM_MASK; } - switch (cga->crtc[10] & 0x60) { + + switch (cga->crtc[CGA_CRTC_CURSOR_START] & 0x60) { case 0x20: cga->cursoron = 0; break; @@ -633,15 +639,15 @@ cga_poll(void *priv) } } - if (cga->vc == cga->crtc[7]) { + if (cga->vc == cga->crtc[CGA_CRTC_VSYNC]) { cga->cgadispon = 0; cga->displine = 0; cga->vsynctime = 16; - if (cga->crtc[7]) { - if (cga->cgamode & 1) - x = (cga->crtc[1] << 3) + 16; + if (cga->crtc[CGA_CRTC_VSYNC]) { + if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) + x = (cga->crtc[CGA_CRTC_HDISP] << 3) + 16; else - x = (cga->crtc[1] << 4) + 16; + x = (cga->crtc[CGA_CRTC_HDISP] << 4) + 16; cga->lastline++; xs_temp = x; @@ -657,7 +663,7 @@ cga_poll(void *priv) if (!enable_overscan) xs_temp -= 16; - if ((cga->cgamode & 8) && ((xs_temp != xsize) || + if ((cga->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { xsize = xs_temp; ysize = ys_temp; @@ -691,15 +697,15 @@ cga_poll(void *priv) video_res_x = xsize; video_res_y = ysize; - if (cga->cgamode & 1) { + if (cga->cgamode & CGA_MODE_FLAG_HIGHRES) { video_res_x /= 8; - video_res_y /= cga->crtc[9] + 1; + video_res_y /= cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1; video_bpp = 0; - } else if (!(cga->cgamode & 2)) { + } else if (!(cga->cgamode & CGA_MODE_FLAG_GRAPHICS)) { video_res_x /= 16; - video_res_y /= cga->crtc[9] + 1; + video_res_y /= cga->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1; video_bpp = 0; - } else if (!(cga->cgamode & 16)) { + } else if (!(cga->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) { video_res_x /= 2; video_bpp = 2; } else @@ -711,18 +717,18 @@ cga_poll(void *priv) cga->oddeven ^= 1; } } else { - cga->sc++; - cga->sc &= 31; - cga->ma = cga->maback; + cga->scanline++; + cga->scanline &= 31; + cga->memaddr = cga->memaddr_backup; } 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))) - cga->con = 1; - if (cga->cgadispon && (cga->cgamode & 1)) { - for (x = 0; x < (cga->crtc[1] << 1); x++) - cga->charbuffer[x] = cga->vram[((cga->ma << 1) + x) & 0x3fff]; + if (cga->scanline == (cga->crtc[CGA_CRTC_CURSOR_START] & 31) || ((cga->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && + cga->scanline == ((cga->crtc[CGA_CRTC_CURSOR_START] & 31) >> 1))) + cga->cursorvisible = 1; + if (cga->cgadispon && (cga->cgamode & CGA_MODE_FLAG_HIGHRES)) { + for (x = 0; x < (cga->crtc[CGA_CRTC_HDISP] << 1); x++) + cga->charbuffer[x] = cga->vram[((cga->memaddr << 1) + x) & DEVICE_VRAM_MASK]; } } } @@ -738,9 +744,8 @@ void * cga_standalone_init(UNUSED(const device_t *info)) { int display_type; - cga_t *cga = malloc(sizeof(cga_t)); + cga_t *cga = calloc(1, sizeof(cga_t)); - memset(cga, 0, sizeof(cga_t)); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_cga); display_type = device_get_config_int("display_type"); @@ -748,7 +753,7 @@ cga_standalone_init(UNUSED(const device_t *info)) cga->revision = device_get_config_int("composite_type"); cga->snow_enabled = device_get_config_int("snow_enabled"); - cga->vram = malloc(0x4000); + cga->vram = malloc(DEVICE_VRAM); cga_comp_init(cga->revision); timer_add(&cga->timer, cga_poll, cga, 1); @@ -771,6 +776,18 @@ cga_standalone_init(UNUSED(const device_t *info)) } } + switch(device_get_config_int("font")) { + case 0: + loadfont(FONT_IBM_MDA_437_PATH, 0); + break; + case 1: + loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0); + break; + case 4: + loadfont(FONT_TULIP_DGA_PATH, 0); + break; + } + return cga; } @@ -874,6 +891,22 @@ const device_config_t cga_config[] = { }, .bios = { { 0 } } }, + { + .name = "font", + .description = "Font", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "US (CP 437)", .value = 0 }, + { .description = "IBM Nordic (CP 437-Nordic)", .value = 1 }, + { .description = "Tulip DGA", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } + }, { .name = "snow_enabled", .description = "Snow emulation", diff --git a/src/video/vid_colorplus.c b/src/video/vid_cga_colorplus.c similarity index 69% rename from src/video/vid_colorplus.c rename to src/video/vid_cga_colorplus.c index 6c66175c1..84d7a2af3 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_cga_colorplus.c @@ -26,10 +26,10 @@ #include "cpu.h" #include <86box/io.h> #include <86box/timer.h> +#include <86box/device.h> #include <86box/lpt.h> #include <86box/pit.h> #include <86box/mem.h> -#include <86box/device.h> #include <86box/video.h> #include <86box/vid_cga.h> #include <86box/vid_colorplus.h> @@ -37,19 +37,19 @@ #include <86box/plat_unused.h> /* Bits in the colorplus control register: */ -#define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */ -#define COLORPLUS_640x200_MODE 0x20 /* 640x200x4 mode active */ -#define COLORPLUS_320x200_MODE 0x10 /* 320x200x16 mode active */ -#define COLORPLUS_EITHER_MODE 0x30 /* Either mode active */ +#define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */ +#define COLORPLUS_640x200_MODE 0x20 /* 640x200x4 mode active */ +#define COLORPLUS_320x200_MODE 0x10 /* 320x200x16 mode active */ +#define COLORPLUS_EITHER_MODE 0x30 /* Either mode active */ -/* Bits in the CGA graphics mode register */ -#define CGA_GRAPHICS_MODE 0x02 /* CGA graphics mode selected? */ +#define CGA_RGB 0 +#define CGA_COMPOSITE 1 -#define CGA_RGB 0 -#define CGA_COMPOSITE 1 +#define COMPOSITE_OLD 0 +#define COMPOSITE_NEW 1 -#define COMPOSITE_OLD 0 -#define COMPOSITE_NEW 1 +// Plantronics specific registers +#define COLORPLUS_CONTROL 0x3DD video_timings_t timing_colorplus = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; @@ -60,7 +60,7 @@ colorplus_out(uint16_t addr, uint8_t val, void *priv) { colorplus_t *colorplus = (colorplus_t *) priv; - if (addr == 0x3DD) { + if (addr == COLORPLUS_CONTROL) { colorplus->control = val & 0x70; } else { cga_out(addr, val, &colorplus->cga); @@ -80,7 +80,7 @@ colorplus_write(uint32_t addr, uint8_t val, void *priv) { colorplus_t *colorplus = (colorplus_t *) priv; - if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) { + if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) { addr ^= 0x4000; } else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) { addr &= 0x3FFF; @@ -99,7 +99,7 @@ colorplus_read(uint32_t addr, void *priv) { colorplus_t *colorplus = (colorplus_t *) priv; - if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) { + if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) { addr ^= 0x4000; } else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) { addr &= 0x3FFF; @@ -130,7 +130,7 @@ colorplus_poll(void *priv) uint16_t dat1; int cols[4]; int col; - int oldsc; + int scanline_old; static const int cols16[16] = { 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x11, 0x13, 0x15, 0x17, @@ -140,7 +140,7 @@ colorplus_poll(void *priv) /* If one of the extra modes is not selected, drop down to the CGA * drawing code. */ - if (!((colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE))) { + if (!((colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_MODE_FLAG_GRAPHICS))) { cga_poll(&colorplus->cga); return; } @@ -149,9 +149,9 @@ colorplus_poll(void *priv) timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispofftime); colorplus->cga.cgastat |= 1; colorplus->cga.linepos = 1; - oldsc = colorplus->cga.sc; - if ((colorplus->cga.crtc[8] & 3) == 3) - colorplus->cga.sc = ((colorplus->cga.sc << 1) + colorplus->cga.oddeven) & 7; + scanline_old = colorplus->cga.scanline; + if ((colorplus->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3) + colorplus->cga.scanline = ((colorplus->cga.scanline << 1) + colorplus->cga.oddeven) & 7; if (colorplus->cga.cgadispon) { if (colorplus->cga.displine < colorplus->cga.firstline) { colorplus->cga.firstline = colorplus->cga.displine; @@ -160,13 +160,13 @@ colorplus_poll(void *priv) colorplus->cga.lastline = colorplus->cga.displine; /* Left / right border */ for (c = 0; c < 8; c++) { - buffer32->line[colorplus->cga.displine][c] = buffer32->line[colorplus->cga.displine][c + (colorplus->cga.crtc[1] << 4) + 8] = (colorplus->cga.cgacol & 15) + 16; + buffer32->line[colorplus->cga.displine][c] = buffer32->line[colorplus->cga.displine][c + (colorplus->cga.crtc[CGA_CRTC_HDISP] << 4) + 8] = (colorplus->cga.cgacol & 15) + 16; } if (colorplus->control & COLORPLUS_320x200_MODE) { - for (x = 0; x < colorplus->cga.crtc[1]; x++) { - dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - colorplus->cga.ma++; + for (x = 0; x < colorplus->cga.crtc[CGA_CRTC_HDISP]; x++) { + dat0 = (plane0[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000)] << 8) | plane0[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000) + 1]; + dat1 = (plane1[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000)] << 8) | plane1[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000) + 1]; + colorplus->cga.memaddr++; for (c = 0; c < 8; c++) { buffer32->line[colorplus->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[colorplus->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols16[(dat0 >> 14) | ((dat1 >> 14) << 2)]; dat0 <<= 2; @@ -176,7 +176,7 @@ colorplus_poll(void *priv) } else if (colorplus->control & COLORPLUS_640x200_MODE) { cols[0] = (colorplus->cga.cgacol & 15) | 16; col = (colorplus->cga.cgacol & 16) ? 24 : 16; - if (colorplus->cga.cgamode & 4) { + if (colorplus->cga.cgamode & CGA_MODE_FLAG_BW) { cols[1] = col | 3; cols[2] = col | 4; cols[3] = col | 7; @@ -189,10 +189,10 @@ colorplus_poll(void *priv) cols[2] = col | 4; cols[3] = col | 6; } - for (x = 0; x < colorplus->cga.crtc[1]; x++) { - dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - colorplus->cga.ma++; + for (x = 0; x < colorplus->cga.crtc[CGA_CRTC_HDISP]; x++) { + dat0 = (plane0[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000)] << 8) | plane0[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000) + 1]; + dat1 = (plane1[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000)] << 8) | plane1[((colorplus->cga.memaddr << 1) & 0x1fff) + ((colorplus->cga.scanline & 1) * 0x2000) + 1]; + colorplus->cga.memaddr++; for (c = 0; c < 16; c++) { buffer32->line[colorplus->cga.displine][(x << 4) + c + 8] = cols[(dat0 >> 15) | ((dat1 >> 15) << 1)]; dat0 <<= 1; @@ -203,18 +203,18 @@ colorplus_poll(void *priv) } else /* Top / bottom border */ { cols[0] = (colorplus->cga.cgacol & 15) + 16; - hline(buffer32, 0, colorplus->cga.displine, (colorplus->cga.crtc[1] << 4) + 16, cols[0]); + hline(buffer32, 0, colorplus->cga.displine, (colorplus->cga.crtc[CGA_CRTC_HDISP] << 4) + 16, cols[0]); } - x = (colorplus->cga.crtc[1] << 4) + 16; + x = (colorplus->cga.crtc[CGA_CRTC_HDISP] << 4) + 16; if (colorplus->cga.composite) Composite_Process(colorplus->cga.cgamode, 0, x >> 2, buffer32->line[colorplus->cga.displine]); else video_process_8(x, colorplus->cga.displine); - colorplus->cga.sc = oldsc; - if (colorplus->cga.vc == colorplus->cga.crtc[7] && !colorplus->cga.sc) + colorplus->cga.scanline = scanline_old; + if (colorplus->cga.vc == colorplus->cga.crtc[CGA_CRTC_VSYNC] && !colorplus->cga.scanline) colorplus->cga.cgastat |= 8; colorplus->cga.displine++; if (colorplus->cga.displine >= 360) @@ -227,54 +227,54 @@ colorplus_poll(void *priv) if (!colorplus->cga.vsynctime) colorplus->cga.cgastat &= ~8; } - if (colorplus->cga.sc == (colorplus->cga.crtc[11] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[11] & 31) >> 1))) { - colorplus->cga.con = 0; - colorplus->cga.coff = 1; + if (colorplus->cga.scanline == (colorplus->cga.crtc[CGA_CRTC_CURSOR_END] & 31) + || ((colorplus->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && colorplus->cga.scanline == ((colorplus->cga.crtc[CGA_CRTC_CURSOR_END] & 31) >> 1))) { + colorplus->cga.cursorvisible = 0; } - if ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == (colorplus->cga.crtc[9] >> 1)) - colorplus->cga.maback = colorplus->cga.ma; + if ((colorplus->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && colorplus->cga.scanline == (colorplus->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1)) + colorplus->cga.memaddr_backup = colorplus->cga.memaddr; if (colorplus->cga.vadj) { - colorplus->cga.sc++; - colorplus->cga.sc &= 31; - colorplus->cga.ma = colorplus->cga.maback; + colorplus->cga.scanline++; + colorplus->cga.scanline &= 31; + colorplus->cga.memaddr = colorplus->cga.memaddr_backup; colorplus->cga.vadj--; if (!colorplus->cga.vadj) { colorplus->cga.cgadispon = 1; - colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff; - colorplus->cga.sc = 0; + colorplus->cga.memaddr = colorplus->cga.memaddr_backup = (colorplus->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (colorplus->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + colorplus->cga.scanline = 0; } - } else if (colorplus->cga.sc == colorplus->cga.crtc[9]) { - colorplus->cga.maback = colorplus->cga.ma; - colorplus->cga.sc = 0; + } else if (colorplus->cga.scanline == colorplus->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR]) { + colorplus->cga.memaddr_backup = colorplus->cga.memaddr; + colorplus->cga.scanline = 0; oldvc = colorplus->cga.vc; colorplus->cga.vc++; colorplus->cga.vc &= 127; - if (colorplus->cga.vc == colorplus->cga.crtc[6]) + if (colorplus->cga.vc == colorplus->cga.crtc[CGA_CRTC_VDISP]) colorplus->cga.cgadispon = 0; - if (oldvc == colorplus->cga.crtc[4]) { + if (oldvc == colorplus->cga.crtc[CGA_CRTC_VTOTAL]) { colorplus->cga.vc = 0; - colorplus->cga.vadj = colorplus->cga.crtc[5]; + colorplus->cga.vadj = colorplus->cga.crtc[CGA_CRTC_VTOTAL_ADJUST]; if (!colorplus->cga.vadj) colorplus->cga.cgadispon = 1; if (!colorplus->cga.vadj) - colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff; - if ((colorplus->cga.crtc[10] & 0x60) == 0x20) + colorplus->cga.memaddr = colorplus->cga.memaddr_backup = (colorplus->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (colorplus->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + if ((colorplus->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) colorplus->cga.cursoron = 0; else colorplus->cga.cursoron = colorplus->cga.cgablink & 8; } - if (colorplus->cga.vc == colorplus->cga.crtc[7]) { + if (colorplus->cga.vc == colorplus->cga.crtc[CGA_CRTC_VSYNC]) { colorplus->cga.cgadispon = 0; colorplus->cga.displine = 0; colorplus->cga.vsynctime = 16; - if (colorplus->cga.crtc[7]) { - if (colorplus->cga.cgamode & 1) - x = (colorplus->cga.crtc[1] << 3) + 16; + if (colorplus->cga.crtc[CGA_CRTC_VSYNC]) { + if (colorplus->cga.cgamode & CGA_MODE_FLAG_HIGHRES) + x = (colorplus->cga.crtc[CGA_CRTC_HDISP] << 3) + 16; else - x = (colorplus->cga.crtc[1] << 4) + 16; + x = (colorplus->cga.crtc[CGA_CRTC_HDISP] << 4) + 16; colorplus->cga.lastline++; if (x != xsize || (colorplus->cga.lastline - colorplus->cga.firstline) != ysize) { xsize = x; @@ -291,15 +291,15 @@ colorplus_poll(void *priv) video_res_x = xsize - 16; video_res_y = ysize; - if (colorplus->cga.cgamode & 1) { + if (colorplus->cga.cgamode & CGA_MODE_FLAG_HIGHRES) { video_res_x /= 8; - video_res_y /= colorplus->cga.crtc[9] + 1; + video_res_y /= colorplus->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1; video_bpp = 0; - } else if (!(colorplus->cga.cgamode & 2)) { + } else if (!(colorplus->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) { video_res_x /= 16; - video_res_y /= colorplus->cga.crtc[9] + 1; + video_res_y /= colorplus->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1; video_bpp = 0; - } else if (!(colorplus->cga.cgamode & 16)) { + } else if (!(colorplus->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) { video_res_x /= 2; video_bpp = 2; } else { @@ -312,17 +312,17 @@ colorplus_poll(void *priv) colorplus->cga.oddeven ^= 1; } } else { - colorplus->cga.sc++; - colorplus->cga.sc &= 31; - colorplus->cga.ma = colorplus->cga.maback; + colorplus->cga.scanline++; + colorplus->cga.scanline &= 31; + colorplus->cga.memaddr = colorplus->cga.memaddr_backup; } if (colorplus->cga.cgadispon) colorplus->cga.cgastat &= ~1; - if (colorplus->cga.sc == (colorplus->cga.crtc[10] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[10] & 31) >> 1))) - colorplus->cga.con = 1; - if (colorplus->cga.cgadispon && (colorplus->cga.cgamode & 1)) { - for (x = 0; x < (colorplus->cga.crtc[1] << 1); x++) - colorplus->cga.charbuffer[x] = colorplus->cga.vram[((colorplus->cga.ma << 1) + x) & 0x3fff]; + if (colorplus->cga.scanline == (colorplus->cga.crtc[CGA_CRTC_CURSOR_START] & 31) || ((colorplus->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && colorplus->cga.scanline == ((colorplus->cga.crtc[CGA_CRTC_CURSOR_START] & 31) >> 1))) + colorplus->cga.cursorvisible = 1; + if (colorplus->cga.cgadispon && (colorplus->cga.cgamode & CGA_MODE_FLAG_HIGHRES)) { + for (x = 0; x < (colorplus->cga.crtc[CGA_CRTC_HDISP] << 1); x++) + colorplus->cga.charbuffer[x] = colorplus->cga.vram[((colorplus->cga.memaddr << 1) + x) & 0x3fff]; } } } @@ -357,7 +357,9 @@ colorplus_standalone_init(UNUSED(const device_t *info)) mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, colorplus); io_sethandler(0x03d0, 0x0010, colorplus_in, NULL, NULL, colorplus_out, NULL, NULL, colorplus); - lpt3_setup(LPT_MDA_ADDR); + colorplus->lpt = device_add_inst(&lpt_port_device, 1); + lpt_port_setup(colorplus->lpt, LPT_MDA_ADDR); + lpt_set_3bc_used(1); return colorplus; } diff --git a/src/video/vid_cga_comp.c b/src/video/vid_cga_comp.c index 6ad6a6b0a..ca9c2c9df 100644 --- a/src/video/vid_cga_comp.c +++ b/src/video/vid_cga_comp.c @@ -135,7 +135,7 @@ update_cga16_color(uint8_t cgamode) int left = (x >> 6) & 15; int rc = right; int lc = left; - if ((cgamode & 4) != 0) { + if ((cgamode & CGA_MODE_FLAG_BW) != 0) { rc = (right & 8) | ((right & 7) != 0 ? 7 : 0); lc = (left & 8) | ((left & 7) != 0 ? 7 : 0); } @@ -240,7 +240,7 @@ Composite_Process(uint8_t cgamode, uint8_t border, uint32_t blocks /*, bool doub for (uint8_t x = 0; x < 5; ++x) OUT(b[x & 3]); - if ((cgamode & 4) != 0) { + if ((cgamode & CGA_MODE_FLAG_BW) != 0) { /* Decode */ i = temp + 5; srgb = TempLine; diff --git a/src/video/vid_cga_compaq.c b/src/video/vid_cga_compaq.c new file mode 100644 index 000000000..1e21d63c1 --- /dev/null +++ b/src/video/vid_cga_compaq.c @@ -0,0 +1,511 @@ +/* + * 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 CGA graphics cards. + * + * + * + * Authors: John Elliott, + * Sarah Walker, + * Miran Grca, + * + * Copyright 2016-2019 John Elliott. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#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/video.h> +#include <86box/vid_cga.h> +#include <86box/vid_cga_comp.h> + +#define CGA_RGB 0 +#define CGA_COMPOSITE 1 + +static uint32_t vflags; +static uint8_t mdaattr[256][2][2]; + +#ifdef ENABLE_COMPAQ_CGA_LOG +int compaq_cga_do_log = ENABLE_COMPAQ_CGA_LOG; + +static void +compaq_cga_log(const char *fmt, ...) +{ + va_list ap; + + if (compaq_cga_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define compaq_cga_log(fmt, ...) +#endif + +static void +compaq_cga_recalctimings(cga_t *dev) +{ + double _dispontime; + double _dispofftime; + double disptime; + disptime = dev->crtc[CGA_CRTC_HTOTAL] + 1; + + _dispontime = dev->crtc[CGA_CRTC_HDISP]; + _dispofftime = disptime - _dispontime; + _dispontime *= MDACONST; + _dispofftime *= MDACONST; + dev->dispontime = (uint64_t) (_dispontime); + dev->dispofftime = (uint64_t) (_dispofftime); +} + +static void +compaq_cga_poll(void *priv) +{ + cga_t *dev = (cga_t *) priv; + uint16_t cursoraddr = (dev->crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (dev->crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 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; + uint8_t cols[4]; + int scanline_old; + int underline = 0; + int blink = 0; + + int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS); + + /* If in graphics mode or character height is not 13, behave as CGA */ + if ((dev->cgamode & highres_graphics_flag) || (dev->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] != 13)) { + overscan_x = overscan_y = 16; + cga_poll(dev); + return; + } else + overscan_x = overscan_y = 0; + + /* We are in Compaq 350-line CGA territory */ + if (!dev->linepos) { + timer_advance_u64(&dev->timer, dev->dispofftime); + dev->cgastat |= 1; + dev->linepos = 1; + scanline_old = dev->scanline; + if ((dev->crtc[CGA_CRTC_INTERLACE] & 3) == 3) + dev->scanline = ((dev->scanline << 1) + dev->oddeven) & 7; + if (dev->cgadispon) { + if (dev->displine < dev->firstline) { + dev->firstline = dev->displine; + video_wait_for_buffer(); + compaq_cga_log("Firstline %i\n", dev->firstline); + } + dev->lastline = dev->displine; + + cols[0] = (dev->cgacol & 15) + 16; + + for (c = 0; c < 8; c++) { + buffer32->line[dev->displine][c] = cols[0]; + if (dev->cgamode & CGA_MODE_FLAG_HIGHRES) + buffer32->line[dev->displine][c + (dev->crtc[CGA_CRTC_HDISP] << 3) + 8] = cols[0]; + else + buffer32->line[dev->displine][c + (dev->crtc[CGA_CRTC_HDISP] << 4) + 8] = cols[0]; + } + + if (dev->cgamode & CGA_MODE_FLAG_HIGHRES) { + for (x = 0; x < dev->crtc[CGA_CRTC_HDISP]; x++) { + chr = dev->charbuffer[x << 1]; + attr = dev->charbuffer[(x << 1) + 1]; + drawcursor = ((dev->memaddr == cursoraddr) && dev->cursorvisible && dev->cursoron); + + if (vflags) { + underline = 0; + blink = ((dev->cgablink & 8) && (dev->cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor); + } + + if (vflags && (dev->cgamode & 0x80)) { + cols[0] = mdaattr[attr][blink][0]; + cols[1] = mdaattr[attr][blink][1]; + + if ((dev->scanline == 12) && ((attr & 7) == 1)) + underline = 1; + } else if (dev->cgamode & CGA_MODE_FLAG_BLINK) { + cols[1] = (attr & 15) + 16; + cols[0] = ((attr >> 4) & 7) + 16; + + if (vflags) { + if (blink) + cols[1] = cols[0]; + } else { + if ((dev->cgablink & 8) && (attr & 0x80) && !dev->drawcursor) + cols[1] = cols[0]; + } + } else { + cols[1] = (attr & 15) + 16; + cols[0] = (attr >> 4) + 16; + } + + if (vflags && underline) { + for (c = 0; c < 8; c++) + buffer32->line[dev->displine][(x << 3) + c + 8] = mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (c = 0; c < 8; c++) + buffer32->line[dev->displine][(x << 3) + c + 8] = + cols[(fontdatm[chr + dev->fontbase][dev->scanline & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } else { + for (c = 0; c < 8; c++) + buffer32->line[dev->displine][(x << 3) + c + 8] = + cols[(fontdatm[chr + dev->fontbase][dev->scanline & 15] & (1 << (c ^ 7))) ? 1 : 0]; + } + dev->memaddr++; + } + } else { + for (x = 0; x < dev->crtc[CGA_CRTC_HDISP]; x++) { + chr = dev->vram[(dev->memaddr << 1) & 0x3fff]; + attr = dev->vram[((dev->memaddr << 1) + 1) & 0x3fff]; + drawcursor = ((dev->memaddr == cursoraddr) && dev->cursorvisible && dev->cursoron); + + if (vflags) { + underline = 0; + blink = ((dev->cgablink & 8) && (dev->cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor); + } + + if (vflags && (dev->cgamode & 0x80)) { + cols[0] = mdaattr[attr][blink][0]; + cols[1] = mdaattr[attr][blink][1]; + if (dev->scanline == 12 && (attr & 7) == 1) + underline = 1; + } else if (dev->cgamode & CGA_MODE_FLAG_BLINK) { + cols[1] = (attr & 15) + 16; + cols[0] = ((attr >> 4) & 7) + 16; + + if (vflags) { + if (blink) + cols[1] = cols[0]; + } else { + if ((dev->cgablink & 8) && (attr & 0x80) && !dev->drawcursor) + cols[1] = cols[0]; + } + } else { + cols[1] = (attr & 15) + 16; + cols[0] = (attr >> 4) + 16; + } + dev->memaddr++; + + if (vflags && underline) { + for (c = 0; c < 8; c++) + buffer32->line[dev->displine][(x << 4) + (c << 1) + 8] = + buffer32->line[dev->displine][(x << 4) + (c << 1) + 9] = mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (c = 0; c < 8; c++) + buffer32->line[dev->displine][(x << 4) + (c << 1) + 8] = + buffer32->line[dev->displine][(x << 4) + (c << 1) + 1 + 8] = + cols[(fontdatm[chr + dev->fontbase][dev->scanline & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } else { + for (c = 0; c < 8; c++) + buffer32->line[dev->displine][(x << 4) + (c << 1) + 8] = + buffer32->line[dev->displine][(x << 4) + (c << 1) + 1 + 8] = + cols[(fontdatm[chr + dev->fontbase][dev->scanline & 15] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + } + } else { + cols[0] = (dev->cgacol & 15) + 16; + + if (dev->cgamode & CGA_MODE_FLAG_HIGHRES) + hline(buffer32, 0, dev->displine, (dev->crtc[CGA_CRTC_HDISP] << 3) + 16, cols[0]); + else + hline(buffer32, 0, dev->displine, (dev->crtc[CGA_CRTC_HDISP] << 4) + 16, cols[0]); + } + + if (dev->cgamode & CGA_MODE_FLAG_HIGHRES) + x = (dev->crtc[CGA_CRTC_HDISP] << 3) + 16; + else + x = (dev->crtc[CGA_CRTC_HDISP] << 4) + 16; + + if (dev->composite) { + if (dev->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS) + border = 0x00; + else + border = dev->cgacol & 0x0f; + + if (vflags) + Composite_Process(dev->cgamode & 0x7f, border, x >> 2, buffer32->line[dev->displine]); + else + Composite_Process(dev->cgamode, border, x >> 2, buffer32->line[dev->displine]); + } else + video_process_8(x, dev->displine); + + dev->scanline = scanline_old; + if (dev->vc == dev->crtc[CGA_CRTC_VSYNC] && !dev->scanline) + dev->cgastat |= 8; + dev->displine++; + if (dev->displine >= 500) + dev->displine = 0; + } else { + timer_advance_u64(&dev->timer, dev->dispontime); + dev->linepos = 0; + if (dev->vsynctime) { + dev->vsynctime--; + if (!dev->vsynctime) + dev->cgastat &= ~8; + } + + if (dev->scanline == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[11] & 31) >> 1))) { + dev->cursorvisible = 0; + } + if ((dev->crtc[8] & 3) == 3 && dev->scanline == (dev->crtc[9] >> 1)) + dev->memaddr_backup = dev->memaddr; + if (dev->vadj) { + dev->scanline++; + dev->scanline &= 31; + dev->memaddr = dev->memaddr_backup; + dev->vadj--; + if (!dev->vadj) { + dev->cgadispon = 1; + dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + dev->scanline = 0; + } + } else if (dev->scanline == dev->crtc[9]) { + dev->memaddr_backup = dev->memaddr; + dev->scanline = 0; + oldvc = dev->vc; + dev->vc++; + dev->vc &= 127; + + if (dev->vc == dev->crtc[6]) + dev->cgadispon = 0; + + if (oldvc == dev->crtc[4]) { + dev->vc = 0; + dev->vadj = dev->crtc[5]; + + if (!dev->vadj) + dev->cgadispon = 1; + + if (!dev->vadj) + dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + + if ((dev->crtc[10] & 0x60) == 0x20) + dev->cursoron = 0; + else + dev->cursoron = dev->cgablink & 8; + } + + if (dev->vc == dev->crtc[7]) { + dev->cgadispon = 0; + dev->displine = 0; + dev->vsynctime = 16; + + if (dev->crtc[7]) { + compaq_cga_log("Lastline %i Firstline %i %i\n", dev->lastline, + dev->firstline, dev->lastline - dev->firstline); + + if (dev->cgamode & CGA_MODE_FLAG_HIGHRES) + x = (dev->crtc[CGA_CRTC_HDISP] << 3) + 16; + else + x = (dev->crtc[CGA_CRTC_HDISP] << 4) + 16; + + dev->lastline++; + + xs_temp = x; + ys_temp = (dev->lastline - dev->firstline); + + if ((xs_temp > 0) && (ys_temp > 0)) { + if (xs_temp < 64) + xs_temp = 656; + if (ys_temp < 32) + ys_temp = 400; + if (!enable_overscan) + xs_temp -= 16; + + if ((dev->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 (video_force_resize_get()) + video_force_resize_set(0); + } + + if (enable_overscan) + video_blit_memtoscreen(0, dev->firstline - 8, xsize, (dev->lastline - dev->firstline) + 16); + else + video_blit_memtoscreen(8, dev->firstline, xsize, dev->lastline - dev->firstline); + } + + frames++; + + video_res_x = xsize; + if (enable_overscan) + xsize -= 16; + video_res_y = ysize; + if (dev->cgamode & CGA_MODE_FLAG_HIGHRES) { + video_res_x /= 8; + video_res_y /= dev->crtc[9] + 1; + video_bpp = 0; + } else if (!(dev->cgamode & 2)) { + video_res_x /= 16; + video_res_y /= dev->crtc[9] + 1; + video_bpp = 0; + } else if (!(dev->cgamode & 16)) { + video_res_x /= 2; + video_bpp = 2; + } else + video_bpp = 1; + } + + dev->firstline = 1000; + dev->lastline = 0; + dev->cgablink++; + dev->oddeven ^= 1; + } + } else { + dev->scanline++; + dev->scanline &= 31; + dev->memaddr = dev->memaddr_backup; + } + + if (dev->cgadispon) + dev->cgastat &= ~1; + + if (dev->scanline == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[10] & 31) >> 1))) + dev->cursorvisible = 1; + + if (dev->cgadispon && (dev->cgamode & CGA_MODE_FLAG_HIGHRES)) { + for (x = 0; x < (dev->crtc[CGA_CRTC_HDISP] << 1); x++) + dev->charbuffer[x] = dev->vram[((dev->memaddr << 1) + x) & 0x3fff]; + } + } +} + +static void * +compaq_cga_init(const device_t *info) +{ + int display_type; + cga_t *dev = calloc(1, sizeof(cga_t)); + + display_type = device_get_config_int("display_type"); + dev->composite = (display_type != CGA_RGB); + dev->revision = device_get_config_int("composite_type"); + dev->snow_enabled = device_get_config_int("snow_enabled"); + + dev->vram = malloc(0x4000); + + cga_comp_init(dev->revision); + timer_add(&dev->timer, compaq_cga_poll, dev, 1); + mem_mapping_add(&dev->mapping, 0xb8000, 0x08000, + cga_read, NULL, NULL, + cga_write, NULL, NULL, + NULL, MEM_MAPPING_EXTERNAL, dev); + io_sethandler(0x03d0, 0x0010, + cga_in, NULL, NULL, + cga_out, NULL, NULL, + dev); + + if (info->local) { + for (uint16_t c = 0; c < 256; c++) { + mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16; + if (c & 8) + mdaattr[c][0][1] = 15 + 16; + else + mdaattr[c][0][1] = 7 + 16; + } + + mdaattr[0x70][0][1] = 16; + mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15; + mdaattr[0xF0][0][1] = 16; + mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15; + mdaattr[0x78][0][1] = 16 + 7; + mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15; + mdaattr[0xF8][0][1] = 16 + 7; + mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15; + mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16; + mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16; + mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16; + mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16; + } + + vflags = info->local; + + overscan_x = overscan_y = 16; + + dev->rgb_type = device_get_config_int("rgb_type"); + cga_palette = (dev->rgb_type << 1); + cgapal_rebuild(); + + dev->crtc[9] = 13; + + return dev; +} + +static void +compaq_cga_close(void *priv) +{ + cga_t *dev = (cga_t *) priv; + + free(dev->vram); + free(dev); +} + +static void +compaq_cga_speed_changed(void *priv) +{ + cga_t *dev = (cga_t *) priv; + + if (dev->crtc[9] == 13) /* Character height */ + compaq_cga_recalctimings(dev); + else + cga_recalctimings(dev); +} + +extern const device_config_t cga_config[]; + +const device_t compaq_cga_device = { + .name = "Compaq CGA", + .internal_name = "compaq_cga", + .flags = DEVICE_ISA, + .local = 0, + .init = compaq_cga_init, + .close = compaq_cga_close, + .reset = NULL, + .available = NULL, + .speed_changed = compaq_cga_speed_changed, + .force_redraw = NULL, + .config = cga_config +}; + +const device_t compaq_cga_2_device = { + .name = "Compaq CGA 2", + .internal_name = "compaq_cga_2", + .flags = DEVICE_ISA, + .local = 1, + .init = compaq_cga_init, + .close = compaq_cga_close, + .reset = NULL, + .available = NULL, + .speed_changed = compaq_cga_speed_changed, + .force_redraw = NULL, + .config = cga_config +}; diff --git a/src/video/vid_cga_compaq_plasma.c b/src/video/vid_cga_compaq_plasma.c new file mode 100644 index 000000000..b281cf93f --- /dev/null +++ b/src/video/vid_cga_compaq_plasma.c @@ -0,0 +1,843 @@ +/* + * 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 plasma displays on early Compaq Portables and laptops. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2025 starfrost + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#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/video.h> +#include <86box/vid_cga.h> +#include <86box/vid_cga_comp.h> +#include <86box/plat_unused.h> + +static video_timings_t timing_compaq_plasma = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; + +#define CGA_RGB 0 +#define CGA_COMPOSITE 1 + +/*Very rough estimate*/ +#define VID_CLOCK (double) (651 * 416 * 60) + +/* Mapping of attributes to colours */ +static uint32_t amber; +static uint32_t black; +static uint32_t blinkcols[256][2]; +static uint32_t normcols[256][2]; + +/* Video options set by the motherboard; they will be picked up by the card + * on the next poll. + * + * Bit 3: Disable built-in video (for add-on card) + * Bit 2: Thin font + * Bits 0,1: Font set (not currently implemented) + */ +static int8_t cpq_st_display_internal = -1; + +static uint8_t mdaattr[256][2][2]; + +static void +compaq_plasma_display_set(uint8_t internal) +{ + cpq_st_display_internal = internal; +} + +typedef struct compaq_plasma_t { + cga_t cga; + mem_mapping_t font_ram_mapping; + uint8_t *font_ram; + uint8_t port_13c6; + uint8_t port_23c6; + uint8_t port_27c6; + uint8_t internal_monitor; +} compaq_plasma_t; + + +static void compaq_plasma_recalcattrs(compaq_plasma_t *self); + +static void +compaq_plasma_recalctimings(compaq_plasma_t *self) +{ + double _dispontime; + double _dispofftime; + double disptime; + + if (!self->internal_monitor && !(self->port_23c6 & 0x01)) { + cga_recalctimings(&self->cga); + return; + } + + disptime = 651; + _dispontime = 640; + _dispofftime = disptime - _dispontime; + self->cga.dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32)); + self->cga.dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32)); +} + +static void +compaq_plasma_waitstates(UNUSED(void *priv)) +{ + int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; + int ws; + + ws = ws_array[cycles & 0xf]; + sub_cycles(ws); +} + +static void +compaq_plasma_write(uint32_t addr, uint8_t val, void *priv) +{ + compaq_plasma_t *self = (compaq_plasma_t *) priv; + + if (self->port_23c6 & 0x08) + self->font_ram[addr & 0x1fff] = val; + else + self->cga.vram[addr & 0x7fff] = val; + + compaq_plasma_waitstates(&self->cga); +} +static uint8_t +compaq_plasma_read(uint32_t addr, void *priv) +{ + compaq_plasma_t *self = (compaq_plasma_t *) priv; + uint8_t ret; + + compaq_plasma_waitstates(&self->cga); + + if (self->port_23c6 & 0x08) + ret = (self->font_ram[addr & 0x1fff]); + else + ret = (self->cga.vram[addr & 0x7fff]); + + return ret; +} + +static void +compaq_plasma_out(uint16_t addr, uint8_t val, void *priv) +{ + compaq_plasma_t *self = (compaq_plasma_t *) priv; + + switch (addr) { + /* Emulated CRTC, register select */ + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + cga_out(addr, val, &self->cga); + break; + + /* Emulated CRTC, value */ + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + cga_out(addr, val, &self->cga); + compaq_plasma_recalctimings(self); + break; + case 0x3d8: + case 0x3d9: + cga_out(addr, val, &self->cga); + break; + + case 0x13c6: + self->port_13c6 = val; + compaq_plasma_display_set((self->port_13c6 & 0x08) ? 1 : 0); + /* + For bits 2-0, John gives 0 = CGA, 1 = EGA, 3 = MDA; + Another source (Ralf Brown?) gives 4 = CGA, 5 = EGA, 7 = MDA; + This leads me to believe bit 2 is not relevant to the mode. + */ + if ((val & 0x07) == 0x03) + mem_mapping_set_addr(&self->cga.mapping, 0xb0000, 0x08000); + else + mem_mapping_set_addr(&self->cga.mapping, 0xb8000, 0x08000); + break; + + case 0x23c6: + self->port_23c6 = val; + break; + + case 0x27c6: + self->port_27c6 = val; + break; + + default: + break; + } +} + +static uint8_t +compaq_plasma_in(uint16_t addr, void *priv) +{ + compaq_plasma_t *self = (compaq_plasma_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + case 0x3d4: + case 0x3da: + case 0x3db: + case 0x3dc: + ret = cga_in(addr, &self->cga); + break; + + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + ret = cga_in(addr, &self->cga); + break; + + case 0x3d8: + ret = self->cga.cgamode; + break; + + case 0x13c6: + ret = self->port_13c6; + break; + + case 0x17c6: + ret = 0xe6; + break; + + case 0x1bc6: + ret = 0x40; + break; + + case 0x23c6: + ret = self->port_23c6; + break; + + case 0x27c6: + ret = self->port_27c6 & 0x3f; + break; + + default: + break; + } + + return ret; +} + +static void +compaq_plasma_poll(void *priv) +{ + compaq_plasma_t *self = (compaq_plasma_t *) priv; + uint8_t chr; + uint8_t attr; + uint8_t scanline; + uint16_t memaddr = (self->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (self->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff; + uint16_t cursoraddr = (self->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (self->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x7fff; + uint16_t addr; + int drawcursor; + int cursorline; + int blink = 0; + int underline = 0; + int cursorvisible = 0; + int cursorinvisible = 0; + int c; + int x; + uint32_t ink = 0; + uint32_t fg = (self->cga.cgacol & 0x0f) ? amber : black; + uint32_t bg = black; + uint32_t black_half = black; + uint32_t amber_half = amber; + uint32_t cols[2]; + uint8_t dat; + uint8_t pattern; + uint32_t ink0 = 0; + uint32_t ink1 = 0; + + /* Switch between internal plasma and external CRT display. */ + if ((cpq_st_display_internal != -1) && (cpq_st_display_internal != self->internal_monitor)) { + self->internal_monitor = cpq_st_display_internal; + compaq_plasma_recalctimings(self); + } + + /* graphic mode and not mode 40h */ + if (!self->internal_monitor && !(self->port_23c6 & 0x01)) { + /* standard cga mode */ + cga_poll(&self->cga); + return; + } else { + /* mode 40h or text mode */ + if (!self->cga.linepos) { + timer_advance_u64(&self->cga.timer, self->cga.dispofftime); + self->cga.cgastat |= 1; + self->cga.linepos = 1; + if (self->cga.cgadispon) { + if (self->cga.displine == 0) + video_wait_for_buffer(); + + /* 80-col */ + if (self->cga.cgamode & 0x01) { + scanline = self->cga.displine & 0x0f; + addr = ((memaddr & ~1) + (self->cga.displine >> 4) * 80) << 1; + memaddr += (self->cga.displine >> 4) * 80; + + if ((self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) + cursorline = 0; + else { + if ((self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0f) > 0x07) + cursorvisible = (self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0f) + 1; + else + cursorvisible = ((self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0f) << 1); + + if ((self->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0f) > 0x07) + cursorinvisible = (self->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0f) + 2; + else + cursorinvisible = ((self->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0f) << 1); + + cursorline = (cursorvisible <= scanline) && (cursorinvisible >= scanline); + } + + /* for each text column */ + for (x = 0; x < 80; x++) { + /* video output enabled */ + if (self->cga.cgamode & 0x08) { + /* character */ + chr = self->cga.vram[(addr + (x << 1)) & 0x7fff]; + /* text attributes */ + attr = self->cga.vram[(addr + ((x << 1) + 1)) & 0x7fff]; + } else { + chr = 0x00; + attr = 0x00; + } + + uint8_t hi_bit = attr & 0x08; + /* check if cursor has to be drawn */ + drawcursor = ((memaddr == cursoraddr) && cursorline && (self->cga.cgamode & 0x08) && (self->cga.cgablink & 0x10)); + /* check if character underline mode should be set */ + underline = ((attr & 0x07) == 0x01); + underline = underline || (((self->port_23c6 >> 5) == 1) && hi_bit); + if (underline) { + /* set forecolor to white */ + attr = attr | 0x7; + } + blink = 0; + /* set foreground */ + cols[1] = blinkcols[attr][1]; + /* blink active */ + if (self->cga.cgamode & CGA_MODE_FLAG_BLINK) { + cols[0] = blinkcols[attr][0]; + /* attribute 7 active and not cursor */ + if ((self->cga.cgablink & 0x08) && (attr & 0x80) && !drawcursor) { + /* set blinking */ + cols[1] = cols[0]; + blink = 1; + } + } else { + /* Set intensity bit */ + cols[1] = normcols[attr][1]; + cols[0] = normcols[attr][0]; + } + + /* character address */ + uint16_t chr_addr = ((chr * 16) + scanline) & 0x0fff; + if (((self->port_23c6 >> 5) == 3) && hi_bit) + chr_addr |= 0x1000; + + /* character underline active and 7th row of pixels in character height being drawn */ + if (underline) { + /* for each pixel in character width */ + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c] = mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + } else { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0]; + } + + if (hi_bit) { + if ((self->port_23c6 >> 5) == 4) { + uint8_t b = (cols[1] & 0xff) >> 1; + uint8_t g = ((cols[1] >> 8) & 0xff) >> 1; + uint8_t r = ((cols[1] >> 16) & 0xff) >> 1; + cols[1] = b | (g << 8) | (r << 16); + b = (cols[0] & 0xff) >> 1; + g = ((cols[0] >> 8) & 0xff) >> 1; + r = ((cols[0] >> 16) & 0xff) >> 1; + cols[0] = b | (g << 8) | (r << 16); + if (drawcursor) { + black_half = black; + amber_half = amber; + uint8_t bB = (black & 0xff) >> 1; + uint8_t gB = ((black >> 8) & 0xff) >> 1; + uint8_t rB = ((black >> 16) & 0xff) >> 1; + black_half = bB | (gB << 8) | (rB << 16); + uint8_t bA = (amber & 0xff) >> 1; + uint8_t gA = ((amber >> 8) & 0xff) >> 1; + uint8_t rA = ((amber >> 16) & 0xff) >> 1; + amber_half = bA | (gA << 8) | (rA << 16); + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber_half ^ black_half); + } else { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0]; + } + } else if ((self->port_23c6 >> 5) == 2) { + if (drawcursor) { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 0 : 1] ^ (amber ^ black); + } else { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 0 : 1]; + } + } + } + memaddr++; + } + } + /* 40-col */ + else if (!(self->cga.cgamode & 0x02)) { + scanline = self->cga.displine & 0x0f; + addr = ((memaddr & ~1) + (self->cga.displine >> 4) * 40) << 1; + memaddr += (self->cga.displine >> 4) * 40; + + if ((self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) + cursorline = 0; + else { + if ((self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0f) > 0x07) + cursorvisible = (self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0f) + 1; + else + cursorvisible = ((self->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0f) << 1); + + if ((self->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0f) > 0x07) + cursorinvisible = (self->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0f) + 2; + else + cursorinvisible = ((self->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0f) << 1); + + cursorline = (cursorvisible <= scanline) && (cursorinvisible >= scanline); + } + + for (x = 0; x < 40; x++) { + /* video output enabled */ + if (self->cga.cgamode & 0x08) { + /* character */ + chr = self->cga.vram[(addr + (x << 1)) & 0x7fff]; + /* text attributes */ + attr = self->cga.vram[(addr + ((x << 1) + 1)) & 0x7fff]; + } else { + chr = 0x00; + attr = 0x00; + } + + uint8_t hi_bit = attr & 0x08; + /* check if cursor has to be drawn */ + drawcursor = ((memaddr == cursoraddr) && cursorline && (self->cga.cgamode & 0x08) && (self->cga.cgablink & 0x10)); + /* check if character underline mode should be set */ + underline = ((attr & 0x07) == 0x01); + underline = underline || (((self->port_23c6 >> 5) == 1) && hi_bit); + if (underline) { + /* set forecolor to white */ + attr = attr | 0x7; + } + blink = 0; + /* set foreground */ + cols[1] = blinkcols[attr][1]; + /* blink active */ + if (self->cga.cgamode & CGA_MODE_FLAG_BLINK) { + cols[0] = blinkcols[attr][0]; + /* attribute 7 active and not cursor */ + if ((self->cga.cgablink & 0x08) && (attr & 0x80) && !drawcursor) { + /* set blinking */ + cols[1] = cols[0]; + blink = 1; + } + } else { + /* Set intensity bit */ + cols[1] = normcols[attr][1]; + cols[0] = normcols[attr][0]; + } + + /* character address */ + uint16_t chr_addr = ((chr * 16) + scanline) & 0x0fff; + if (((self->port_23c6 >> 5) == 3) && hi_bit) + chr_addr |= 0x1000; + + /* character underline active and 7th row of pixels in character height being drawn */ + if (underline && (scanline == 7)) { + /* for each pixel in character width */ + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + } else { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0]; + } + + if (hi_bit) { + if ((self->port_23c6 >> 5) == 4) { + uint8_t b = (cols[1] & 0xff) >> 1; + uint8_t g = ((cols[1] >> 8) & 0xff) >> 1; + uint8_t r = ((cols[1] >> 16) & 0xff) >> 1; + cols[1] = b | (g << 8) | (r << 16); + b = (cols[0] & 0xff) >> 1; + g = ((cols[0] >> 8) & 0xff) >> 1; + r = ((cols[0] >> 16) & 0xff) >> 1; + cols[0] = b | (g << 8) | (r << 16); + if (drawcursor) { + black_half = black; + amber_half = amber; + uint8_t bB = (black & 0xff) >> 1; + uint8_t gB = ((black >> 8) & 0xff) >> 1; + uint8_t rB = ((black >> 16) & 0xff) >> 1; + black_half = bB | (gB << 8) | (rB << 16); + uint8_t bA = (amber & 0xff) >> 1; + uint8_t gA = ((amber >> 8) & 0xff) >> 1; + uint8_t rA = ((amber >> 16) & 0xff) >> 1; + amber_half = bA | (gA << 8) | (rA << 16); + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber_half ^ black_half); + } else { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 1 : 0]; + } + } else if ((self->port_23c6 >> 5) == 2) { + if (drawcursor) { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 0 : 1] ^ (amber ^ black); + } else { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + (c << 1)] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1] = cols[(self->font_ram[chr_addr] & (1 << (c ^ 7))) ? 0 : 1]; + } + } + } + memaddr++; + } + } else { + if (self->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS) { + /* 640x400 mode */ + if (self->port_23c6 & 0x01) /* 640*400 */ { + addr = ((self->cga.displine) & 1) * 0x2000 + ((self->cga.displine >> 1) & 1) * 0x4000 + (self->cga.displine >> 2) * 80 + ((memaddr & ~1) << 1); + } else { + addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((memaddr & ~1) << 1); + } + for (uint8_t x = 0; x < 80; x++) { + dat = self->cga.vram[addr & 0x7fff]; + addr++; + + for (uint8_t c = 0; c < 8; c++) { + ink = (dat & 0x80) ? fg : bg; + if (!(self->cga.cgamode & 0x08)) + ink = black; + buffer32->line[self->cga.displine][(x << 3) + c] = ink; + dat <<= 1; + } + } + } else { + addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((memaddr & ~1) << 1); + for (uint8_t x = 0; x < 80; x++) { + dat = self->cga.vram[addr & 0x7fff]; + addr++; + + for (uint8_t c = 0; c < 4; c++) { + pattern = (dat & 0xC0) >> 6; + if (!(self->cga.cgamode & 0x08)) + pattern = 0; + + switch (pattern & 3) { + case 0: + ink0 = ink1 = black; + break; + case 1: + if (self->cga.displine & 0x01) { + ink0 = black; + ink1 = black; + } else { + ink0 = amber; + ink1 = black; + } + break; + case 2: + if (self->cga.displine & 0x01) { + ink0 = black; + ink1 = amber; + } else { + ink0 = amber; + ink1 = black; + } + break; + case 3: + ink0 = ink1 = amber; + break; + + default: + break; + } + buffer32->line[self->cga.displine][(x << 3) + (c << 1)] = ink0; + buffer32->line[self->cga.displine][(x << 3) + (c << 1) + 1] = ink1; + dat <<= 2; + } + } + } + } + } + self->cga.displine++; + /* Hardcode a fixed refresh rate and VSYNC timing */ + if (self->cga.displine == 400) { /* Start of VSYNC */ + self->cga.cgastat |= 8; + self->cga.cgadispon = 0; + } + if (self->cga.displine == 416) { /* End of VSYNC */ + self->cga.displine = 0; + self->cga.cgastat &= ~8; + self->cga.cgadispon = 1; + } + } else { + timer_advance_u64(&self->cga.timer, self->cga.dispontime); + if (self->cga.cgadispon) + self->cga.cgastat &= ~1; + + self->cga.linepos = 0; + + if (self->cga.displine == 400) { + xsize = 640; + ysize = 400; + + if ((self->cga.cgamode & 0x08) || video_force_resize_get()) { + set_screen_size(xsize, ysize); + + if (video_force_resize_get()) + video_force_resize_set(0); + } + /* Plasma specific */ + video_blit_memtoscreen(0, 0, xsize, ysize); + frames++; + + /* Fixed 640x400 resolution */ + video_res_x = 640; + video_res_y = 400; + + if (self->cga.cgamode & 0x02) { + if (self->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS) + video_bpp = 1; + else + video_bpp = 2; + } else + video_bpp = 0; + + self->cga.cgablink++; + } + } + } +} + +static void +compaq_plasma_mdaattr_rebuild(void) +{ + for (uint16_t c = 0; c < 256; c++) { + mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16; + if (c & 8) + mdaattr[c][0][1] = 15 + 16; + else + mdaattr[c][0][1] = 7 + 16; + } + + mdaattr[0x70][0][1] = 16; + mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15; + mdaattr[0xF0][0][1] = 16; + mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15; + mdaattr[0x78][0][1] = 16 + 7; + mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15; + mdaattr[0xF8][0][1] = 16 + 7; + mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15; + mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16; + mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16; + mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16; + mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16; +} + +static void +compaq_plasma_recalcattrs(compaq_plasma_t *self) +{ + int n; + + /* val behaves as follows: + * Bit 0: Attributes 01-06, 08-0E are inverse video + * Bit 1: Attributes 01-06, 08-0E are bold + * Bit 2: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF + * are inverse video + * Bit 3: Attributes 11-16, 18-1F, 21-26, 28-2F ... F1-F6, F8-FF + * are bold */ + + /* Set up colours */ + amber = makecol(0xff, 0x7d, 0x00); + black = makecol(0x64, 0x19, 0x00); + + /* Initialize the attribute mapping. Start by defaulting everything + * to black on amber, and with bold set by bit 3 */ + for (n = 0; n < 256; n++) { + blinkcols[n][0] = normcols[n][0] = amber; + blinkcols[n][1] = normcols[n][1] = black; + } + + /* Colours 0x11-0xFF are controlled by bits 2 and 3 of the + * passed value. Exclude x0 and x8, which are always black on + * amber. */ + for (n = 0x11; n <= 0xFF; n++) { + if ((n & 7) == 0) + continue; + blinkcols[n][0] = normcols[n][0] = black; + blinkcols[n][1] = normcols[n][1] = amber; + } + /* Set up the 01-0E range, controlled by bits 0 and 1 of the + * passed value. When blinking is enabled this also affects 81-8E. */ + for (n = 0x01; n <= 0x0E; n++) { + if (n == 7) + continue; + blinkcols[n][0] = normcols[n][0] = black; + blinkcols[n][1] = normcols[n][1] = amber; + blinkcols[n + 128][0] = black; + blinkcols[n + 128][1] = amber; + } + /* Colours 07 and 0F are always amber on black. If blinking is + * enabled so are 87 and 8F. */ + for (n = 0x07; n <= 0x0F; n += 8) { + blinkcols[n][0] = normcols[n][0] = black; + blinkcols[n][1] = normcols[n][1] = amber; + blinkcols[n + 128][0] = black; + blinkcols[n + 128][1] = amber; + } + /* When not blinking, colours 81-8F are always amber on black. */ + for (n = 0x81; n <= 0x8F; n++) { + normcols[n][0] = black; + normcols[n][1] = amber; + } + + /* Finally do the ones which are solid black. These differ between + * the normal and blinking mappings */ + for (n = 0; n <= 0xFF; n += 0x11) + normcols[n][0] = normcols[n][1] = black; + + /* In the blinking range, 00 11 22 .. 77 and 80 91 A2 .. F7 are black */ + for (n = 0; n <= 0x77; n += 0x11) { + blinkcols[n][0] = blinkcols[n][1] = black; + blinkcols[n + 128][0] = blinkcols[n + 128][1] = black; + } +} + +static void * +compaq_plasma_init(UNUSED(const device_t *info)) +{ + compaq_plasma_t *self = calloc(1, sizeof(compaq_plasma_t)); + + cga_init(&self->cga); + video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma); + + self->cga.composite = 0; + self->cga.revision = 0; + + self->cga.vram = malloc(0x8000); + self->internal_monitor = 1; + self->font_ram = malloc(0x2000); + + cga_comp_init(self->cga.revision); + timer_set_callback(&self->cga.timer, compaq_plasma_poll); + timer_set_p(&self->cga.timer, self); + + mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, + compaq_plasma_read, NULL, NULL, + compaq_plasma_write, NULL, NULL, + NULL, MEM_MAPPING_EXTERNAL, self); + for (int i = 1; i <= 2; i++) { + io_sethandler(0x03c6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); + io_sethandler(0x07c6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); + io_sethandler(0x0bc6 + (i << 12), 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); + } + io_sethandler(0x03d0, 0x0010, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); + + overscan_x = overscan_y = 16; + compaq_plasma_recalcattrs(self); + + self->cga.rgb_type = device_get_config_int("rgb_type"); + cga_palette = (self->cga.rgb_type << 1); + cgapal_rebuild(); + compaq_plasma_mdaattr_rebuild(); + + return self; +} + +static void +compaq_plasma_close(void *priv) +{ + compaq_plasma_t *self = (compaq_plasma_t *) priv; + + free(self->cga.vram); + free(self->font_ram); + free(self); +} + +static void +compaq_plasma_speed_changed(void *priv) +{ + compaq_plasma_t *self = (compaq_plasma_t *) priv; + + compaq_plasma_recalctimings(self); +} + +const device_config_t compaq_plasma_config[] = { + // clang-format off + { + .name = "rgb_type", + .description = "RGB type", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Color", .value = 0 }, + { .description = "Green Monochrome", .value = 1 }, + { .description = "Amber Monochrome", .value = 2 }, + { .description = "Gray Monochrome", .value = 3 }, + { .description = "" } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t compaq_plasma_device = { + .name = "Compaq Plasma", + .internal_name = "compaq_plasma", + .flags = 0, + .local = 0, + .init = compaq_plasma_init, + .close = compaq_plasma_close, + .reset = NULL, + .available = NULL, + .speed_changed = compaq_plasma_speed_changed, + .force_redraw = NULL, + .config = compaq_plasma_config +}; diff --git a/src/video/vid_nga.c b/src/video/vid_cga_ncr.c similarity index 74% rename from src/video/vid_nga.c rename to src/video/vid_cga_ncr.c index ef1c6cd40..eb4474a40 100644 --- a/src/video/vid_nga.c +++ b/src/video/vid_cga_ncr.c @@ -56,12 +56,12 @@ nga_recalctimings(nga_t *nga) double _dispofftime; double disptime; - if (nga->cga.cgamode & 1) { - disptime = nga->cga.crtc[0] + 1; - _dispontime = nga->cga.crtc[1]; + if (nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES) { + disptime = nga->cga.crtc[CGA_CRTC_HTOTAL] + 1; + _dispontime = nga->cga.crtc[CGA_CRTC_HDISP]; } else { - disptime = (nga->cga.crtc[0] + 1) << 1; - _dispontime = nga->cga.crtc[1] << 1; + disptime = (nga->cga.crtc[CGA_CRTC_HTOTAL] + 1) << 1; + _dispontime = nga->cga.crtc[CGA_CRTC_HDISP] << 1; } _dispofftime = disptime - _dispontime; @@ -148,7 +148,7 @@ nga_poll(void *priv) { nga_t *nga = (nga_t *) priv; /* set cursor position in memory */ - uint16_t ca = (nga->cga.crtc[15] | (nga->cga.crtc[14] << 8)) & 0x3fff; + uint16_t cursoraddr = (nga->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (nga->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff; int drawcursor; int x; int c; @@ -161,10 +161,10 @@ nga_poll(void *priv) uint16_t dat2; int cols[4]; int col; - int oldsc; + int scanline_old; /* graphic mode and not high-res modes */ - if ((nga->cga.cgamode & 2) && !(nga->cga.cgamode & 0x40)) { + if ((nga->cga.cgamode & CGA_MODE_FLAG_GRAPHICS) && !(nga->cga.cgamode & 0x40)) { /* standard cga mode */ cga_poll(&nga->cga); return; @@ -174,10 +174,10 @@ nga_poll(void *priv) timer_advance_u64(&nga->cga.timer, nga->cga.dispofftime); nga->cga.cgastat |= 1; nga->cga.linepos = 1; - oldsc = nga->cga.sc; + scanline_old = nga->cga.scanline; /* if interlaced */ - if ((nga->cga.crtc[8] & 3) == 3) - nga->cga.sc = ((nga->cga.sc << 1) + nga->cga.oddeven) & 7; + if ((nga->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3) + nga->cga.scanline = ((nga->cga.scanline << 1) + nga->cga.oddeven) & 7; if (nga->cga.cgadispon) { if (nga->cga.displine < nga->cga.firstline) { nga->cga.firstline = nga->cga.displine; @@ -185,11 +185,11 @@ nga_poll(void *priv) } nga->cga.lastline = nga->cga.displine; /* 80-col */ - if ((nga->cga.cgamode & 1) && !(nga->cga.cgamode & 2)) { + if ((nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES) && !(nga->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) { /* for each text column */ - for (x = 0; x < nga->cga.crtc[1]; x++) { + for (x = 0; x < nga->cga.crtc[CGA_CRTC_HDISP]; x++) { /* video output enabled */ - if (nga->cga.cgamode & 8) { + if (nga->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) { /* character */ chr = nga->cga.charbuffer[x << 1]; /* text attributes */ @@ -197,11 +197,11 @@ nga_poll(void *priv) } else chr = attr = 0; /* check if cursor has to be drawn */ - drawcursor = ((nga->cga.ma == ca) && nga->cga.con && nga->cga.cursoron); + drawcursor = ((nga->cga.memaddr == cursoraddr) && nga->cga.cursorvisible && nga->cga.cursoron); /* set foreground */ cols[1] = (attr & 15) + 16; /* blink active */ - if (nga->cga.cgamode & 0x20) { + if (nga->cga.cgamode & CGA_MODE_FLAG_BLINK) { cols[0] = ((attr >> 4) & 7) + 16; /* attribute 7 active and not cursor */ if ((nga->cga.cgablink & 8) && (attr & 0x80) && !nga->cga.drawcursor) { @@ -214,30 +214,30 @@ nga_poll(void *priv) } if (drawcursor) { for (c = 0; c < 8; c++) - buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((nga->cga.scanline & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } else { for (c = 0; c < 8; c++) - buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((nga->cga.scanline & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0]; } - nga->cga.ma++; + nga->cga.memaddr++; } } /* 40-col */ - else if (!(nga->cga.cgamode & 2)) { + else if (!(nga->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) { /* for each text column */ - for (x = 0; x < nga->cga.crtc[1]; x++) { - if (nga->cga.cgamode & 8) { - chr = nga->cga.vram[((nga->cga.ma << 1) & 0x3fff) + nga->base]; - attr = nga->cga.vram[(((nga->cga.ma << 1) + 1) & 0x3fff) + nga->base]; + for (x = 0; x < nga->cga.crtc[CGA_CRTC_HDISP]; x++) { + if (nga->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) { + chr = nga->cga.vram[((nga->cga.memaddr << 1) & 0x3fff) + nga->base]; + attr = nga->cga.vram[(((nga->cga.memaddr << 1) + 1) & 0x3fff) + nga->base]; } else { chr = attr = 0; } - drawcursor = ((nga->cga.ma == ca) && nga->cga.con && nga->cga.cursoron); + drawcursor = ((nga->cga.memaddr == cursoraddr) && nga->cga.cursorvisible && nga->cga.cursoron); /* set foreground */ cols[1] = (attr & 15) + 16; /* blink active */ - if (nga->cga.cgamode & 0x20) { + if (nga->cga.cgamode & CGA_MODE_FLAG_BLINK) { cols[0] = ((attr >> 4) & 7) + 16; if ((nga->cga.cgablink & 8) && (attr & 0x80) && !nga->cga.drawcursor) { /* set blinking */ @@ -250,19 +250,19 @@ nga_poll(void *priv) if (drawcursor) { for (c = 0; c < 8; c++) - buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((nga->cga.scanline & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } else { for (c = 0; c < 8; c++) - buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((nga->cga.scanline & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0]; } - nga->cga.ma++; + nga->cga.memaddr++; } } else { /* high res modes */ if (nga->cga.cgamode & 0x40) { /* 640x400x2 mode */ - if (nga->cga.cgamode & 0x4 || nga->cga.cgamode & 0x10) { + if (nga->cga.cgamode & 0x4 || nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS) { /* * Scanlines are read in the following order: * 0b8000-0b9f3f even scans (0,4,...) @@ -270,14 +270,14 @@ nga_poll(void *priv) * 0bc000-0bdf3f even scans (1,5,...) * 0be000-0bff3f odd scans (3,7,...) */ - dat2 = ((nga->cga.sc & 1) * 0x2000) | (nga->lineff * 0x4000); + dat2 = ((nga->cga.scanline & 1) * 0x2000) | (nga->lineff * 0x4000); cols[0] = 0; cols[1] = 15 + 16; /* 640x400x4 mode */ } else { cols[0] = (nga->cga.cgacol & 15) | 16; col = (nga->cga.cgacol & 16) ? 24 : 16; - if (nga->cga.cgamode & 4) { + if (nga->cga.cgamode & CGA_MODE_FLAG_BW) { cols[1] = col | 3; /* Cyan */ cols[2] = col | 4; /* Red */ cols[3] = col | 7; /* White */ @@ -297,22 +297,22 @@ nga_poll(void *priv) * 0a8000-0abf3f even scans (2,6,...) * 0ac000-0aff3f odd scans (3,7,...) */ - dat2 = (nga->cga.sc & 1) * 0x4000; + dat2 = (nga->cga.scanline & 1) * 0x4000; } } else { - dat2 = (nga->cga.sc & 1) * 0x2000; + dat2 = (nga->cga.scanline & 1) * 0x2000; cols[0] = 0; cols[1] = (nga->cga.cgacol & 15) + 16; } /* for each text column */ - for (x = 0; x < nga->cga.crtc[1]; x++) { + for (x = 0; x < nga->cga.crtc[CGA_CRTC_HDISP]; x++) { /* video out */ - if (nga->cga.cgamode & 8) { + if (nga->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) { /* 640x400x2 */ - if (nga->cga.cgamode & 0x4 || nga->cga.cgamode & 0x10) { + if (nga->cga.cgamode & 0x4 || nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS) { /* read two bytes at a time */ - dat = (nga->cga.vram[((nga->cga.ma << 1) & 0x1fff) + dat2] << 8) | nga->cga.vram[((nga->cga.ma << 1) & 0x1fff) + dat2 + 1]; + dat = (nga->cga.vram[((nga->cga.memaddr << 1) & 0x1fff) + dat2] << 8) | nga->cga.vram[((nga->cga.memaddr << 1) & 0x1fff) + dat2 + 1]; /* each pixel is represented by one bit, so draw 16 pixels at a time */ /* crtc[1] is 40 column, so 40x16=640 pixels */ for (c = 0; c < 16; c++) { @@ -322,13 +322,13 @@ nga_poll(void *priv) /* 640x400x4 */ } else { /* lines 2,3,6,7,etc. */ - if (nga->cga.sc & 2) + if (nga->cga.scanline & 2) /* read two bytes at a time */ - dat = (nga->vram_64k[((nga->cga.ma << 1) & 0x7fff) + dat2] << 8) | nga->vram_64k[((nga->cga.ma << 1) & 0x7fff) + dat2 + 1]; + dat = (nga->vram_64k[((nga->cga.memaddr << 1) & 0x7fff) + dat2] << 8) | nga->vram_64k[((nga->cga.memaddr << 1) & 0x7fff) + dat2 + 1]; /* lines 0,1,4,5,etc. */ else /* read two bytes at a time */ - dat = (nga->cga.vram[((nga->cga.ma << 1) & 0x7fff) + dat2] << 8) | nga->cga.vram[((nga->cga.ma << 1) & 0x7fff) + dat2 + 1]; + dat = (nga->cga.vram[((nga->cga.memaddr << 1) & 0x7fff) + dat2] << 8) | nga->cga.vram[((nga->cga.memaddr << 1) & 0x7fff) + dat2 + 1]; /* each pixel is represented by two bits, so draw 8 pixels at a time */ /* crtc[1] is 80 column, so 80x8=640 pixels */ for (c = 0; c < 8; c++) { @@ -339,7 +339,7 @@ nga_poll(void *priv) } else { dat = 0; } - nga->cga.ma++; + nga->cga.memaddr++; } } } else { @@ -347,26 +347,26 @@ nga_poll(void *priv) /* nga specific */ cols[0] = ((nga->cga.cgamode & 0x12) == 0x12) ? 0 : (nga->cga.cgacol & 15) + 16; /* 80-col */ - if (nga->cga.cgamode & 1) { - hline(buffer32, 0, (nga->cga.displine << 1), ((nga->cga.crtc[1] << 3) + 16) << 2, cols[0]); - hline(buffer32, 0, (nga->cga.displine << 1) + 1, ((nga->cga.crtc[1] << 3) + 16) << 2, cols[0]); + if (nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES) { + hline(buffer32, 0, (nga->cga.displine << 1), ((nga->cga.crtc[CGA_CRTC_HDISP] << 3) + 16) << 2, cols[0]); + hline(buffer32, 0, (nga->cga.displine << 1) + 1, ((nga->cga.crtc[CGA_CRTC_HDISP] << 3) + 16) << 2, cols[0]); } else { - hline(buffer32, 0, (nga->cga.displine << 1), ((nga->cga.crtc[1] << 4) + 16) << 2, cols[0]); - hline(buffer32, 0, (nga->cga.displine << 1) + 1, ((nga->cga.crtc[1] << 4) + 16) << 2, cols[0]); + hline(buffer32, 0, (nga->cga.displine << 1), ((nga->cga.crtc[CGA_CRTC_HDISP] << 4) + 16) << 2, cols[0]); + hline(buffer32, 0, (nga->cga.displine << 1) + 1, ((nga->cga.crtc[CGA_CRTC_HDISP] << 4) + 16) << 2, cols[0]); } } - if (nga->cga.cgamode & 1) + if (nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES) /* set screen width */ - x = (nga->cga.crtc[1] << 3) + 16; + x = (nga->cga.crtc[CGA_CRTC_HDISP] << 3) + 16; else - x = (nga->cga.crtc[1] << 4) + 16; + x = (nga->cga.crtc[CGA_CRTC_HDISP] << 4) + 16; video_process_8(x, nga->cga.displine); - nga->cga.sc = oldsc; + nga->cga.scanline = scanline_old; /* vertical sync */ - if (nga->cga.vc == nga->cga.crtc[7] && !nga->cga.sc) + if (nga->cga.vc == nga->cga.crtc[CGA_CRTC_VSYNC] && !nga->cga.scanline) nga->cga.cgastat |= 8; nga->cga.displine++; if (nga->cga.displine >= 720) @@ -380,8 +380,8 @@ nga_poll(void *priv) nga->lineff ^= 1; /* text mode or 640x400x2 */ - if (nga->lineff && !((nga->cga.cgamode & 1) && (nga->cga.cgamode & 0x40))) { - nga->cga.ma = nga->cga.maback; + if (nga->lineff && !((nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES) && (nga->cga.cgamode & 0x40))) { + nga->cga.memaddr = nga->cga.memaddr_backup; /* 640x400x4 */ } else { if (nga->cga.vsynctime) { @@ -390,50 +390,49 @@ nga_poll(void *priv) nga->cga.cgastat &= ~8; } /* cursor stop scanline */ - if (nga->cga.sc == (nga->cga.crtc[11] & 31) || ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == ((nga->cga.crtc[11] & 31) >> 1))) { - nga->cga.con = 0; - nga->cga.coff = 1; + if (nga->cga.scanline == (nga->cga.crtc[CGA_CRTC_CURSOR_END] & 31) || ((nga->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && nga->cga.scanline == ((nga->cga.crtc[CGA_CRTC_CURSOR_END] & 31) >> 1))) { + nga->cga.cursorvisible = 0; } /* interlaced and max scanline per char reached */ - if ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == (nga->cga.crtc[9] >> 1)) - nga->cga.maback = nga->cga.ma; + if ((nga->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && nga->cga.scanline == (nga->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1)) + nga->cga.memaddr_backup = nga->cga.memaddr; if (nga->cga.vadj) { - nga->cga.sc++; - nga->cga.sc &= 31; - nga->cga.ma = nga->cga.maback; + nga->cga.scanline++; + nga->cga.scanline &= 31; + nga->cga.memaddr = nga->cga.memaddr_backup; nga->cga.vadj--; if (!nga->cga.vadj) { nga->cga.cgadispon = 1; /* change start of displayed page (crtc 12-13) */ - nga->cga.ma = nga->cga.maback = (nga->cga.crtc[13] | (nga->cga.crtc[12] << 8)) & 0x7fff; - nga->cga.sc = 0; + nga->cga.memaddr = nga->cga.memaddr_backup = (nga->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (nga->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff; + nga->cga.scanline = 0; } /* nga specific */ /* end of character line reached */ - } else if (nga->cga.sc == nga->cga.crtc[9] || ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == (nga->cga.crtc[9] >> 1))) { - nga->cga.maback = nga->cga.ma; - nga->cga.sc = 0; + } else if (nga->cga.scanline == nga->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] || ((nga->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && nga->cga.scanline == (nga->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1))) { + nga->cga.memaddr_backup = nga->cga.memaddr; + nga->cga.scanline = 0; oldvc = nga->cga.vc; nga->cga.vc++; nga->cga.vc &= 127; /* lines of character displayed */ - if (nga->cga.vc == nga->cga.crtc[6]) + if (nga->cga.vc == nga->cga.crtc[CGA_CRTC_VDISP]) nga->cga.cgadispon = 0; /* total vertical lines */ - if (oldvc == nga->cga.crtc[4]) { + if (oldvc == nga->cga.crtc[CGA_CRTC_VTOTAL]) { nga->cga.vc = 0; /* adjust vertical lines */ - nga->cga.vadj = nga->cga.crtc[5]; + nga->cga.vadj = nga->cga.crtc[CGA_CRTC_VTOTAL_ADJUST]; if (!nga->cga.vadj) { nga->cga.cgadispon = 1; /* change start of displayed page (crtc 12-13) */ - nga->cga.ma = nga->cga.maback = (nga->cga.crtc[13] | (nga->cga.crtc[12] << 8)) & 0x7fff; + nga->cga.memaddr = nga->cga.memaddr_backup = (nga->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (nga->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff; } /* cursor start */ - switch (nga->cga.crtc[10] & 0x60) { + switch (nga->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) { case 0x20: nga->cga.cursoron = 0; break; @@ -446,18 +445,18 @@ nga_poll(void *priv) } } /* vertical line position */ - if (nga->cga.vc == nga->cga.crtc[7]) { + if (nga->cga.vc == nga->cga.crtc[CGA_CRTC_VSYNC]) { nga->cga.cgadispon = 0; nga->cga.displine = 0; /* nga specific */ nga->cga.vsynctime = 16; /* vsync pos */ - if (nga->cga.crtc[7]) { - if (nga->cga.cgamode & 1) + if (nga->cga.crtc[CGA_CRTC_VSYNC]) { + if (nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES) /* set screen width */ - x = (nga->cga.crtc[1] << 3) + 16; + x = (nga->cga.crtc[CGA_CRTC_HDISP] << 3) + 16; else - x = (nga->cga.crtc[1] << 4) + 16; + x = (nga->cga.crtc[CGA_CRTC_HDISP] << 4) + 16; nga->cga.lastline++; xs_temp = x; @@ -472,7 +471,7 @@ nga_poll(void *priv) if (!enable_overscan) xs_temp -= 16; - if ((nga->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { + if ((nga->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && ((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)); @@ -494,14 +493,14 @@ nga_poll(void *priv) video_res_x = xsize; video_res_y = ysize; /* 80-col */ - if ((nga->cga.cgamode & 1) && !(nga->cga.cgamode & 0x40)) { + if ((nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES) && !(nga->cga.cgamode & 0x40)) { video_res_x /= 8; - video_res_y /= (nga->cga.crtc[9] + 1) * 2; + video_res_y /= (nga->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1) * 2; video_bpp = 0; /* 40-col */ - } else if (!(nga->cga.cgamode & 2)) { + } else if (!(nga->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) { video_res_x /= 16; - video_res_y /= (nga->cga.crtc[9] + 1) * 2; + video_res_y /= (nga->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1) * 2; video_bpp = 0; } else if (nga->cga.cgamode & 0x40) { video_res_x /= 8; @@ -515,23 +514,23 @@ nga_poll(void *priv) nga->cga.oddeven ^= 1; } } else { - nga->cga.sc++; - nga->cga.sc &= 31; - nga->cga.ma = nga->cga.maback; + nga->cga.scanline++; + nga->cga.scanline &= 31; + nga->cga.memaddr = nga->cga.memaddr_backup; } if (nga->cga.cgadispon) nga->cga.cgastat &= ~1; /* enable cursor if its scanline was reached */ - if (nga->cga.sc == (nga->cga.crtc[10] & 31) || ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == ((nga->cga.crtc[10] & 31) >> 1))) - nga->cga.con = 1; + if (nga->cga.scanline == (nga->cga.crtc[CGA_CRTC_CURSOR_START] & 31) || ((nga->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && nga->cga.scanline == ((nga->cga.crtc[CGA_CRTC_CURSOR_START] & 31) >> 1))) + nga->cga.cursorvisible = 1; } /* 80-columns */ - if (nga->cga.cgadispon && (nga->cga.cgamode & 1)) { + if (nga->cga.cgadispon && (nga->cga.cgamode & CGA_MODE_FLAG_HIGHRES)) { /* for each character per line */ - for (x = 0; x < (nga->cga.crtc[1] << 1); x++) - nga->cga.charbuffer[x] = nga->cga.vram[(((nga->cga.ma << 1) + x) & 0x3fff) + nga->base]; + for (x = 0; x < (nga->cga.crtc[CGA_CRTC_HDISP] << 1); x++) + nga->cga.charbuffer[x] = nga->cga.vram[(((nga->cga.memaddr << 1) + x) & 0x3fff) + nga->base]; } } } diff --git a/src/video/vid_ogc.c b/src/video/vid_cga_olivetti.c similarity index 75% rename from src/video/vid_ogc.c rename to src/video/vid_cga_olivetti.c index a49cd8a22..147529f6e 100644 --- a/src/video/vid_ogc.c +++ b/src/video/vid_cga_olivetti.c @@ -38,6 +38,7 @@ #include <86box/rom.h> #include <86box/device.h> #include <86box/vid_cga.h> +extern const device_config_t cga_config[]; /* defined in vid_cga.c */ #include <86box/vid_ogc.h> #include <86box/vid_cga_comp.h> #include <86box/plat_unused.h> @@ -65,12 +66,12 @@ ogc_recalctimings(ogc_t *ogc) double _dispofftime; double disptime; - if (ogc->cga.cgamode & 1) { - disptime = ogc->cga.crtc[0] + 1; - _dispontime = ogc->cga.crtc[1]; + if (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES) { + disptime = ogc->cga.crtc[CGA_CRTC_HTOTAL] + 1; + _dispontime = ogc->cga.crtc[CGA_CRTC_HDISP]; } else { - disptime = (ogc->cga.crtc[0] + 1) << 1; - _dispontime = ogc->cga.crtc[1] << 1; + disptime = (ogc->cga.crtc[CGA_CRTC_HTOTAL] + 1) << 1; + _dispontime = ogc->cga.crtc[CGA_CRTC_HDISP] << 1; } _dispofftime = disptime - _dispontime; @@ -201,7 +202,7 @@ void ogc_poll(void *priv) { ogc_t *ogc = (ogc_t *) priv; - uint16_t ca = (ogc->cga.crtc[15] | (ogc->cga.crtc[14] << 8)) & 0x3fff; + uint16_t cursoraddr = (ogc->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (ogc->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff; int drawcursor; int x; int c; @@ -213,14 +214,14 @@ ogc_poll(void *priv) uint16_t dat; uint16_t dat2; int cols[4]; - int oldsc; + int scanline_old; int blink = 0; int underline = 0; - // composito colore appare blu scuro + // Composite color appears dark blue /* graphic mode and not mode 40h */ - if (!(ogc->ctrl_3de & 0x1 || !(ogc->cga.cgamode & 2))) { + if (!(ogc->ctrl_3de & 0x1 || !(ogc->cga.cgamode & CGA_MODE_FLAG_GRAPHICS))) { /* standard cga mode */ cga_poll(&ogc->cga); return; @@ -230,9 +231,9 @@ ogc_poll(void *priv) timer_advance_u64(&ogc->cga.timer, ogc->cga.dispofftime); ogc->cga.cgastat |= 1; ogc->cga.linepos = 1; - oldsc = ogc->cga.sc; - if ((ogc->cga.crtc[8] & 3) == 3) - ogc->cga.sc = ((ogc->cga.sc << 1) + ogc->cga.oddeven) & 7; + scanline_old = ogc->cga.scanline; + if ((ogc->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3) + ogc->cga.scanline = ((ogc->cga.scanline << 1) + ogc->cga.oddeven) & 7; if (ogc->cga.cgadispon) { if (ogc->cga.displine < ogc->cga.firstline) { ogc->cga.firstline = ogc->cga.displine; @@ -240,11 +241,11 @@ ogc_poll(void *priv) } ogc->cga.lastline = ogc->cga.displine; /* 80-col */ - if (ogc->cga.cgamode & 1) { + if (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES) { /* for each text column */ - for (x = 0; x < ogc->cga.crtc[1]; x++) { + for (x = 0; x < ogc->cga.crtc[CGA_CRTC_HDISP]; x++) { /* video output enabled */ - if (ogc->cga.cgamode & 8) { + if (ogc->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) { /* character */ chr = ogc->cga.charbuffer[x << 1]; /* text attributes */ @@ -252,7 +253,7 @@ ogc_poll(void *priv) } else chr = attr = 0; /* check if cursor has to be drawn */ - drawcursor = ((ogc->cga.ma == ca) && ogc->cga.con && ogc->cga.cursoron); + drawcursor = ((ogc->cga.memaddr == cursoraddr) && ogc->cga.cursorvisible && ogc->cga.cursoron); /* check if character underline mode should be set */ underline = ((ogc->ctrl_3de & 0x40) && (attr & 0x1) && !(attr & 0x6)); if (underline) { @@ -263,7 +264,7 @@ ogc_poll(void *priv) /* set foreground */ cols[1] = (attr & 15) + 16; /* blink active */ - if (ogc->cga.cgamode & 0x20) { + if (ogc->cga.cgamode & CGA_MODE_FLAG_BLINK) { cols[0] = ((attr >> 4) & 7) + 16; /* attribute 7 active and not cursor */ if ((ogc->cga.cgablink & 8) && (attr & 0x80) && !ogc->cga.drawcursor) { @@ -277,31 +278,31 @@ ogc_poll(void *priv) blink = (attr & 0x80) * 8 + 7 + 16; } /* character underline active and 7th row of pixels in character height being drawn */ - if (underline && (ogc->cga.sc == 7)) { + if (underline && (ogc->cga.scanline == 7)) { /* for each pixel in character width */ for (c = 0; c < 8; c++) buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = mdaattr[attr][blink][1]; } else if (drawcursor) { for (c = 0; c < 8; c++) - buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((ogc->cga.scanline & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } else { for (c = 0; c < 8; c++) - buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((ogc->cga.scanline & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0]; } - ogc->cga.ma++; + ogc->cga.memaddr++; } } /* 40-col */ - else if (!(ogc->cga.cgamode & 2)) { - for (x = 0; x < ogc->cga.crtc[1]; x++) { - if (ogc->cga.cgamode & 8) { - chr = ogc->cga.vram[((ogc->cga.ma << 1) & 0x3fff) + ogc->base]; - attr = ogc->cga.vram[(((ogc->cga.ma << 1) + 1) & 0x3fff) + ogc->base]; + else if (!(ogc->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) { + for (x = 0; x < ogc->cga.crtc[CGA_CRTC_HDISP]; x++) { + if (ogc->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) { + chr = ogc->cga.vram[((ogc->cga.memaddr << 1) & 0x3fff) + ogc->base]; + attr = ogc->cga.vram[(((ogc->cga.memaddr << 1) + 1) & 0x3fff) + ogc->base]; } else { chr = attr = 0; } - drawcursor = ((ogc->cga.ma == ca) && ogc->cga.con && ogc->cga.cursoron); + drawcursor = ((ogc->cga.memaddr == cursoraddr) && ogc->cga.cursorvisible && ogc->cga.cursoron); /* check if character underline mode should be set */ underline = ((ogc->ctrl_3de & 0x40) && (attr & 0x1) && !(attr & 0x6)); if (underline) { @@ -312,7 +313,7 @@ ogc_poll(void *priv) /* set foreground */ cols[1] = (attr & 15) + 16; /* blink active */ - if (ogc->cga.cgamode & 0x20) { + if (ogc->cga.cgamode & CGA_MODE_FLAG_BLINK) { cols[0] = ((attr >> 4) & 7) + 16; if ((ogc->cga.cgablink & 8) && (attr & 0x80) && !ogc->cga.drawcursor) { /* set blinking */ @@ -326,40 +327,40 @@ ogc_poll(void *priv) } /* character underline active and 7th row of pixels in character height being drawn */ - if (underline && (ogc->cga.sc == 7)) { + if (underline && (ogc->cga.scanline == 7)) { /* for each pixel in character width */ for (c = 0; c < 8; c++) buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = mdaattr[attr][blink][1]; } else if (drawcursor) { for (c = 0; c < 8; c++) - buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((ogc->cga.scanline & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; } else { for (c = 0; c < 8; c++) - buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((ogc->cga.scanline & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0]; } - ogc->cga.ma++; + ogc->cga.memaddr++; } } else { /* 640x400 mode */ if (ogc->ctrl_3de & 1) { - dat2 = ((ogc->cga.sc & 1) * 0x4000) | (ogc->lineff * 0x2000); + dat2 = ((ogc->cga.scanline & 1) * 0x4000) | (ogc->lineff * 0x2000); cols[0] = 0; cols[1] = 15 + 16; } else { - dat2 = (ogc->cga.sc & 1) * 0x2000; + dat2 = (ogc->cga.scanline & 1) * 0x2000; cols[0] = 0; cols[1] = (ogc->cga.cgacol & 15) + 16; } - for (x = 0; x < ogc->cga.crtc[1]; x++) { + for (x = 0; x < ogc->cga.crtc[CGA_CRTC_HDISP]; x++) { /* video out */ - if (ogc->cga.cgamode & 8) { - dat = (ogc->cga.vram[((ogc->cga.ma << 1) & 0x1fff) + dat2] << 8) | ogc->cga.vram[((ogc->cga.ma << 1) & 0x1fff) + dat2 + 1]; + if (ogc->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) { + dat = (ogc->cga.vram[((ogc->cga.memaddr << 1) & 0x1fff) + dat2] << 8) | ogc->cga.vram[((ogc->cga.memaddr << 1) & 0x1fff) + dat2 + 1]; } else { dat = 0; } - ogc->cga.ma++; + ogc->cga.memaddr++; for (c = 0; c < 16; c++) { buffer32->line[ogc->cga.displine][(x << 4) + c + 8] = cols[dat >> 15]; @@ -370,22 +371,22 @@ ogc_poll(void *priv) } else { /* ogc specific */ cols[0] = ((ogc->cga.cgamode & 0x12) == 0x12) ? 0 : (ogc->cga.cgacol & 15) + 16; - if (ogc->cga.cgamode & 1) - hline(buffer32, 0, ogc->cga.displine, ((ogc->cga.crtc[1] << 3) + 16) << 2, cols[0]); + if (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES) + hline(buffer32, 0, ogc->cga.displine, ((ogc->cga.crtc[CGA_CRTC_HDISP] << 3) + 16) << 2, cols[0]); else - hline(buffer32, 0, ogc->cga.displine, ((ogc->cga.crtc[1] << 4) + 16) << 2, cols[0]); + hline(buffer32, 0, ogc->cga.displine, ((ogc->cga.crtc[CGA_CRTC_HDISP] << 4) + 16) << 2, cols[0]); } /* 80 columns */ - if (ogc->cga.cgamode & 1) - x = (ogc->cga.crtc[1] << 3) + 16; + if (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES) + x = (ogc->cga.crtc[CGA_CRTC_HDISP] << 3) + 16; else - x = (ogc->cga.crtc[1] << 4) + 16; + x = (ogc->cga.crtc[CGA_CRTC_HDISP] << 4) + 16; video_process_8(x, ogc->cga.displine); - ogc->cga.sc = oldsc; - if (ogc->cga.vc == ogc->cga.crtc[7] && !ogc->cga.sc) + ogc->cga.scanline = scanline_old; + if (ogc->cga.vc == ogc->cga.crtc[CGA_CRTC_VSYNC] && !ogc->cga.scanline) ogc->cga.cgastat |= 8; ogc->cga.displine++; if (ogc->cga.displine >= 720) @@ -398,48 +399,47 @@ ogc_poll(void *priv) /* ogc specific */ ogc->lineff ^= 1; if (ogc->lineff) { - ogc->cga.ma = ogc->cga.maback; + ogc->cga.memaddr = ogc->cga.memaddr_backup; } else { if (ogc->cga.vsynctime) { ogc->cga.vsynctime--; if (!ogc->cga.vsynctime) ogc->cga.cgastat &= ~8; } - if (ogc->cga.sc == (ogc->cga.crtc[11] & 31) || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == ((ogc->cga.crtc[11] & 31) >> 1))) { - ogc->cga.con = 0; - ogc->cga.coff = 1; + if (ogc->cga.scanline == (ogc->cga.crtc[CGA_CRTC_CURSOR_END] & 31) || ((ogc->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && ogc->cga.scanline == ((ogc->cga.crtc[CGA_CRTC_CURSOR_END] & 31) >> 1))) { + ogc->cga.cursorvisible = 0; } - if ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == (ogc->cga.crtc[9] >> 1)) - ogc->cga.maback = ogc->cga.ma; + if ((ogc->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && ogc->cga.scanline == (ogc->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1)) + ogc->cga.memaddr_backup = ogc->cga.memaddr; if (ogc->cga.vadj) { - ogc->cga.sc++; - ogc->cga.sc &= 31; - ogc->cga.ma = ogc->cga.maback; + ogc->cga.scanline++; + ogc->cga.scanline &= 31; + ogc->cga.memaddr = ogc->cga.memaddr_backup; ogc->cga.vadj--; if (!ogc->cga.vadj) { ogc->cga.cgadispon = 1; - ogc->cga.ma = ogc->cga.maback = (ogc->cga.crtc[13] | (ogc->cga.crtc[12] << 8)) & 0x3fff; - ogc->cga.sc = 0; + ogc->cga.memaddr = ogc->cga.memaddr_backup = (ogc->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (ogc->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + ogc->cga.scanline = 0; } - // potrebbe dare problemi con composito - } else if (ogc->cga.sc == ogc->cga.crtc[9] || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == (ogc->cga.crtc[9] >> 1))) { - ogc->cga.maback = ogc->cga.ma; - ogc->cga.sc = 0; + // may cause problems with composite + } else if (ogc->cga.scanline == ogc->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] || ((ogc->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && ogc->cga.scanline == (ogc->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1))) { + ogc->cga.memaddr_backup = ogc->cga.memaddr; + ogc->cga.scanline = 0; oldvc = ogc->cga.vc; ogc->cga.vc++; ogc->cga.vc &= 127; - if (ogc->cga.vc == ogc->cga.crtc[6]) + if (ogc->cga.vc == ogc->cga.crtc[CGA_CRTC_VDISP]) ogc->cga.cgadispon = 0; - if (oldvc == ogc->cga.crtc[4]) { + if (oldvc == ogc->cga.crtc[CGA_CRTC_VTOTAL]) { ogc->cga.vc = 0; - ogc->cga.vadj = ogc->cga.crtc[5]; + ogc->cga.vadj = ogc->cga.crtc[CGA_CRTC_VTOTAL_ADJUST]; if (!ogc->cga.vadj) { ogc->cga.cgadispon = 1; - ogc->cga.ma = ogc->cga.maback = (ogc->cga.crtc[13] | (ogc->cga.crtc[12] << 8)) & 0x3fff; + ogc->cga.memaddr = ogc->cga.memaddr_backup = (ogc->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (ogc->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; } - switch (ogc->cga.crtc[10] & 0x60) { + switch (ogc->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) { case 0x20: ogc->cga.cursoron = 0; break; @@ -451,16 +451,16 @@ ogc_poll(void *priv) break; } } - if (ogc->cga.vc == ogc->cga.crtc[7]) { + if (ogc->cga.vc == ogc->cga.crtc[CGA_CRTC_VSYNC]) { ogc->cga.cgadispon = 0; ogc->cga.displine = 0; /* ogc specific */ - ogc->cga.vsynctime = (ogc->cga.crtc[3] >> 4) + 1; - if (ogc->cga.crtc[7]) { - if (ogc->cga.cgamode & 1) - x = (ogc->cga.crtc[1] << 3) + 16; + ogc->cga.vsynctime = (ogc->cga.crtc[CGA_CRTC_HSYNC_WIDTH] >> 4) + 1; + if (ogc->cga.crtc[CGA_CRTC_VSYNC]) { + if (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES) + x = (ogc->cga.crtc[CGA_CRTC_HDISP] << 3) + 16; else - x = (ogc->cga.crtc[1] << 4) + 16; + x = (ogc->cga.crtc[CGA_CRTC_HDISP] << 4) + 16; ogc->cga.lastline++; xs_temp = x; @@ -475,7 +475,7 @@ ogc_poll(void *priv) if (!enable_overscan) xs_temp -= 16; - if ((ogc->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { + if ((ogc->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && ((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)); @@ -497,14 +497,14 @@ ogc_poll(void *priv) video_res_x = xsize; video_res_y = ysize; /* 80-col */ - if (ogc->cga.cgamode & 1) { + if (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES) { video_res_x /= 8; - video_res_y /= (ogc->cga.crtc[9] + 1) * 2; + video_res_y /= (ogc->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1) * 2; video_bpp = 0; /* 40-col */ - } else if (!(ogc->cga.cgamode & 2)) { + } else if (!(ogc->cga.cgamode & CGA_MODE_FLAG_GRAPHICS)) { video_res_x /= 16; - video_res_y /= (ogc->cga.crtc[9] + 1) * 2; + video_res_y /= (ogc->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1) * 2; video_bpp = 0; } else if (!(ogc->ctrl_3de & 1)) { video_res_y /= 2; @@ -517,21 +517,21 @@ ogc_poll(void *priv) ogc->cga.oddeven ^= 1; } } else { - ogc->cga.sc++; - ogc->cga.sc &= 31; - ogc->cga.ma = ogc->cga.maback; + ogc->cga.scanline++; + ogc->cga.scanline &= 31; + ogc->cga.memaddr = ogc->cga.memaddr_backup; } 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))) - ogc->cga.con = 1; + if (ogc->cga.scanline == (ogc->cga.crtc[CGA_CRTC_CURSOR_START] & 31) || ((ogc->cga.crtc[CGA_CRTC_INTERLACE] & 3) == 3 && ogc->cga.scanline == ((ogc->cga.crtc[CGA_CRTC_CURSOR_START] & 31) >> 1))) + ogc->cga.cursorvisible = 1; } /* 80-columns */ - if (ogc->cga.cgadispon && (ogc->cga.cgamode & 1)) { - for (x = 0; x < (ogc->cga.crtc[1] << 1); x++) - ogc->cga.charbuffer[x] = ogc->cga.vram[(((ogc->cga.ma << 1) + x) & 0x3fff) + ogc->base]; + if (ogc->cga.cgadispon && (ogc->cga.cgamode & CGA_MODE_FLAG_HIGHRES)) { + for (x = 0; x < (ogc->cga.crtc[CGA_CRTC_HDISP] << 1); x++) + ogc->cga.charbuffer[x] = ogc->cga.vram[(((ogc->cga.memaddr << 1) + x) & 0x3fff) + ogc->base]; } } } diff --git a/src/video/vid_cga_quadcolor.c b/src/video/vid_cga_quadcolor.c new file mode 100644 index 000000000..642391679 --- /dev/null +++ b/src/video/vid_cga_quadcolor.c @@ -0,0 +1,995 @@ +/* + * 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. + * + * Quadram Quadcolor I / I+II emulation + * + * Authors: Sarah Walker, + * Miran Grca, + * W. M. Martinez, + * Benedikt Freisen, + * Jasmine Iwanek, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2023 W. M. Martinez + * Copyright 2024 Benedikt Freisen. + * Copyright 2025 Jasmine Iwanek. + */ + +/* This has been derived from CGA emulation */ +/* omissions: simulated snow (Quadcolor has dual-ported RAM), single and dual 8x16 font configuration */ +/* additions: ports 0x3dd and 0x3de, 2nd char set, 2nd VRAM bank, hi-res bg color, Quadcolor II memory and mode */ +/* assumptions: MA line 12 XORed with Bank Select, hi-res bg is also border color, QC2 mode has simple address counter */ + +#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/video.h> +#include <86box/vid_cga.h> +#include <86box/vid_quadcolor.h> +#include <86box/vid_cga_comp.h> +#include <86box/plat_unused.h> + +#define CGA_RGB 0 +#define CGA_COMPOSITE 1 + +#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 + +#define DEVICE_VRAM 0x8000 +#define DEVICE_VRAM_MASK 0x7fff + +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_quadcolor = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; + +void quadcolor_recalctimings(quadcolor_t *quadcolor); + +static void +quadcolor_update_latch(quadcolor_t *quadcolor) +{ + uint32_t lp_latch = quadcolor->displine * quadcolor->crtc[CGA_CRTC_HDISP]; + + quadcolor->crtc[CGA_CRTC_LIGHT_PEN_ADDR_HIGH] = (lp_latch >> 8) & 0x3f; + quadcolor->crtc[CGA_CRTC_LIGHT_PEN_ADDR_LOW] = lp_latch & 0xff; +} + +void +quadcolor_out(uint16_t addr, uint8_t val, void *priv) +{ + quadcolor_t *quadcolor = (quadcolor_t *) priv; + uint8_t old; + + if ((addr >= 0x3d0) && (addr <= 0x3d7)) + addr = (addr & 0xff9) | 0x004; + + switch (addr) { + case CGA_REGISTER_CRTC_INDEX: + quadcolor->crtcreg = val & 31; + return; + case CGA_REGISTER_CRTC_DATA: + old = quadcolor->crtc[quadcolor->crtcreg]; + quadcolor->crtc[quadcolor->crtcreg] = val & crtcmask[quadcolor->crtcreg]; + if (old != val) { + // Recalc the timings if we are writing any invalid CRTC register or a valid CRTC register + // except the CURSOR and LIGHT PEN registers + if ((quadcolor->crtcreg < 0xe) || (quadcolor->crtcreg > 0x11)) { + quadcolor->fullchange = changeframecount; + quadcolor_recalctimings(quadcolor); + } + } + return; + case CGA_REGISTER_MODE_CONTROL: + old = quadcolor->cgamode; + quadcolor->cgamode = val; + + if (old ^ val) { + if ((old ^ val) & 0x07) + update_cga16_color(val); + + quadcolor_recalctimings(quadcolor); + } + return; + case CGA_REGISTER_COLOR_SELECT: + old = quadcolor->cgacol; + quadcolor->cgacol = val; + if (old ^ val) + quadcolor_recalctimings(quadcolor); + return; + + case CGA_REGISTER_CLEAR_LIGHT_PEN_LATCH: + if (quadcolor->lp_strobe == 1) + quadcolor->lp_strobe = 0; + return; + case CGA_REGISTER_SET_LIGHT_PEN_LATCH: + if (quadcolor->lp_strobe == 0) { + quadcolor->lp_strobe = 1; + quadcolor_update_latch(quadcolor); + } + return; + + case 0x3dd: + quadcolor->quadcolor_ctrl = val & 0x3f; + /* helper variable that can be XORed onto the VRAM address to select the page to display */ + quadcolor->page_offset = (val & 0x10) << 8; + /* in dual 8x8 font configuration, use fontbase 256 if "Character Set Select" bit is set */ + if (quadcolor->has_2nd_charset) + quadcolor->fontbase = (val & 0x20) << 3; + return; + case 0x3de: + /* NOTE: the polarity of this register is the opposite of what the manual says */ + if (quadcolor->has_quadcolor_2) + /* + NOTE: PC Paintbrush writes FF and then gets stuck if it doesn't get enabled, + and then it expects to disable it with 0x00. The only way to square this + with the inverted polarity note above is if that was a value other than + 0x00 with bit 4 clear. + */ + quadcolor->quadcolor_2_oe = ((!(val & 0x10)) || (val == 0xff)) && (val != 0x00); + return; + + default: + break; + } +} + +uint8_t +quadcolor_in(uint16_t addr, void *priv) +{ + quadcolor_t *quadcolor = (quadcolor_t *) priv; + uint8_t ret = 0xff; + + if ((addr >= 0x3d0) && (addr <= 0x3d7)) + addr = (addr & 0xff9) | 0x004; + + switch (addr) { + case CGA_REGISTER_CRTC_INDEX: + ret = quadcolor->crtcreg; + break; + case CGA_REGISTER_CRTC_DATA: + ret = quadcolor->crtc[quadcolor->crtcreg]; + break; + case CGA_REGISTER_STATUS: + ret = quadcolor->cgastat; + break; + case CGA_REGISTER_CLEAR_LIGHT_PEN_LATCH: + if (quadcolor->lp_strobe == 1) + quadcolor->lp_strobe = 0; + break; + case CGA_REGISTER_SET_LIGHT_PEN_LATCH: + if (quadcolor->lp_strobe == 0) { + quadcolor->lp_strobe = 1; + quadcolor_update_latch(quadcolor); + } + break; + + default: + break; + } + + return ret; +} + +void +quadcolor_waitstates(UNUSED(void *priv)) +{ + int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; + int ws; + + ws = ws_array[cycles & 0xf]; + cycles -= ws; +} + +void +quadcolor_write(uint32_t addr, uint8_t val, void *priv) +{ + quadcolor_t *quadcolor = (quadcolor_t *) priv; + + quadcolor->vram[addr & DEVICE_VRAM_MASK] = val; + quadcolor_waitstates(quadcolor); +} + +uint8_t +quadcolor_read(uint32_t addr, void *priv) +{ + quadcolor_t *quadcolor = (quadcolor_t *) priv; + + quadcolor_waitstates(quadcolor); + return quadcolor->vram[addr & DEVICE_VRAM_MASK]; +} + +void +quadcolor_2_write(uint32_t addr, uint8_t val, void *priv) +{ + quadcolor_t *quadcolor = (quadcolor_t *) priv; + quadcolor->vram_2[addr & 0xffff] = val; +} + +uint8_t +quadcolor_2_read(uint32_t addr, void *priv) +{ + quadcolor_t *quadcolor = (quadcolor_t *) priv; + return quadcolor->vram_2[addr & 0xffff]; +} + +void +quadcolor_recalctimings(quadcolor_t *quadcolor) +{ + double disptime; + double _dispontime; + double _dispofftime; + + if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES) { + disptime = (double) (quadcolor->crtc[CGA_CRTC_HTOTAL] + 1); + _dispontime = (double) quadcolor->crtc[CGA_CRTC_HDISP]; + } else { + disptime = (double) ((quadcolor->crtc[CGA_CRTC_HTOTAL] + 1) << 1); + _dispontime = (double) (quadcolor->crtc[CGA_CRTC_HDISP] << 1); + } + _dispofftime = disptime - _dispontime; + _dispontime = _dispontime * CGACONST; + _dispofftime = _dispofftime * CGACONST; + quadcolor->dispontime = (uint64_t) (_dispontime); + quadcolor->dispofftime = (uint64_t) (_dispofftime); +} + +static inline uint8_t +get_next_qc2_pixel(quadcolor_t *quadcolor) +{ + uint8_t mask = quadcolor->qc2mask; + quadcolor->qc2mask = ~quadcolor->qc2mask; + uint8_t pixel = (quadcolor->vram_2[quadcolor->qc2idx] & mask) >> (quadcolor->qc2mask & 4); + + quadcolor->qc2idx += quadcolor->qc2mask >> 7; + + return quadcolor->quadcolor_2_oe ? pixel : 0; +} + +static void +quadcolor_render(quadcolor_t *quadcolor, int line) +{ + uint16_t cursoraddr = (quadcolor->crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (quadcolor->crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & DEVICE_VRAM_MASK; + int drawcursor; + int x; + int column; + uint8_t chr; + uint8_t attr; + uint16_t dat; + int cols[4]; + int col; + + int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS); + + cols[0] = ((quadcolor->cgamode & highres_graphics_flag) == highres_graphics_flag) ? (quadcolor->quadcolor_ctrl & 15) : + (quadcolor->cgacol & 15); + + for (column = 0; column < 8; ++column) { + buffer32->line[line][column] = cols[0]; + if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES) + buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 3) + 8] = cols[0]; + else + buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 4) + 8] = cols[0]; + } + if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES) { /* 80-column text */ + for (x = 0; x < quadcolor->crtc[CGA_CRTC_HDISP]; x++) { + if (quadcolor->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) { + chr = quadcolor->charbuffer[x << 1]; + attr = quadcolor->charbuffer[(x << 1) + 1]; + } else + chr = attr = 0; + drawcursor = ((quadcolor->memaddr == cursoraddr) && quadcolor->cursorvisible && quadcolor->cursoron); + cols[1] = (attr & 15) + 16; + if (quadcolor->cgamode & CGA_MODE_FLAG_BLINK) { + cols[0] = ((attr >> 4) & 7) + 16; + if ((quadcolor->cgablink & 8) && (attr & 0x80) && !quadcolor->drawcursor) + cols[1] = cols[0]; + } else + cols[0] = (attr >> 4) + 16; + uint8_t charline = quadcolor->scanline & 7; + if (drawcursor) { + for (column = 0; column < 8; column++) { + dat = (cols[(fontdat[chr + quadcolor->fontbase][charline] & (1 << (column ^ 7))) ? 1 : 0] ^ 15); + buffer32->line[line][(x << 3) + column + 8] = + dat | get_next_qc2_pixel(quadcolor); + } + } else { + for (column = 0; column < 8; column++) { + dat = cols[(fontdat[chr + quadcolor->fontbase][charline] & (1 << (column ^ 7))) ? 1 : 0]; + buffer32->line[line][(x << 3) + column + 8] = + dat | get_next_qc2_pixel(quadcolor); + } + } + quadcolor->memaddr++; + } + } else if (!(quadcolor->cgamode & CGA_MODE_FLAG_GRAPHICS)) { + /* Not graphics (nor 80-column text) => 40-column text. */ + for (x = 0; x < quadcolor->crtc[CGA_CRTC_HDISP]; x++) { + if (quadcolor->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) { + chr = quadcolor->vram[(quadcolor->page_offset ^ (quadcolor->memaddr << 1)) & DEVICE_VRAM_MASK]; + attr = quadcolor->vram[(quadcolor->page_offset ^ ((quadcolor->memaddr << 1) + 1)) & DEVICE_VRAM_MASK]; + } else + chr = attr = 0; + drawcursor = ((quadcolor->memaddr == cursoraddr) && quadcolor->cursorvisible && quadcolor->cursoron); + cols[1] = (attr & 15) + 16; + if (quadcolor->cgamode & CGA_MODE_FLAG_BLINK) { + cols[0] = ((attr >> 4) & 7) + 16; + if ((quadcolor->cgablink & 8) && (attr & 0x80)) + cols[1] = cols[0]; + } else + cols[0] = (attr >> 4) + 16; + quadcolor->memaddr++; + uint8_t charline = quadcolor->scanline & 7; + if (drawcursor) { + for (column = 0; column < 8; column++) { + dat = (cols[(fontdat[chr + quadcolor->fontbase][charline] & (1 << (column ^ 7))) ? 1 : 0] ^ 15); + buffer32->line[line][(x << 4) + (column << 1) + 8] = + dat | get_next_qc2_pixel(quadcolor); + buffer32->line[line][(x << 4) + (column << 1) + 9] = + dat | get_next_qc2_pixel(quadcolor); + } + } else { + for (column = 0; column < 8; column++) { + dat = cols[(fontdat[chr + quadcolor->fontbase][charline] & (1 << (column ^ 7))) ? 1 : 0]; + buffer32->line[line][(x << 4) + (column << 1) + 8] = + dat | get_next_qc2_pixel(quadcolor); + buffer32->line[line][(x << 4) + (column << 1) + 9] = + dat | get_next_qc2_pixel(quadcolor); + } + } + } + } else if (!(quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) { + /* Not hi-res (but graphics) => 4-color mode. */ + cols[0] = (quadcolor->cgacol & 15) | 16; + col = (quadcolor->cgacol & 16) ? 24 : 16; + if (quadcolor->cgamode & CGA_MODE_FLAG_BW) { + cols[1] = col | 3; /* Cyan */ + cols[2] = col | 4; /* Red */ + cols[3] = col | 7; /* White */ + } else if (quadcolor->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 < quadcolor->crtc[CGA_CRTC_HDISP]; x++) { + if (quadcolor->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) + dat = (quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + + ((quadcolor->scanline & 1) * 0x2000))] << 8) | + quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + + ((quadcolor->scanline & 1) * 0x2000) + 1)]; + else + dat = 0; + quadcolor->memaddr++; + for (column = 0; column < 8; column++) { + buffer32->line[line][(x << 4) + (column << 1) + 8] = cols[dat >> 14] | get_next_qc2_pixel(quadcolor); + buffer32->line[line][(x << 4) + (column << 1) + 9] = cols[dat >> 14] | get_next_qc2_pixel(quadcolor); + dat <<= 2; + } + } + } else { + /* 2-color hi-res graphics mode. */ + /* Background color (Quadcolor-specific). */ + cols[0] = quadcolor->quadcolor_ctrl & 15; + cols[1] = (quadcolor->cgacol & 15) + 16; + for (x = 0; x < quadcolor->crtc[CGA_CRTC_HDISP]; x++) { + if (quadcolor->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) /* video enabled */ + dat = (quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + + ((quadcolor->scanline & 1) * 0x2000))] << 8) | + quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + + ((quadcolor->scanline & 1) * 0x2000) + 1)]; + else + /* TODO: Is Quadcolor bg color actually relevant, here? Probably. See QC2 manual p.46 1. */ + dat = quadcolor->quadcolor_ctrl & 15; + quadcolor->memaddr++; + for (column = 0; column < 16; column++) { + buffer32->line[line][(x << 4) + column + 8] = cols[dat >> 15] | get_next_qc2_pixel(quadcolor); + dat <<= 1; + } + } + } +} + +static void +quadcolor_render_blank(quadcolor_t *quadcolor, int line) +{ + int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS); + + /* `+ 16` isn't in PCem's version */ + int col = ((quadcolor->cgamode & highres_graphics_flag) == highres_graphics_flag) ? (quadcolor->quadcolor_ctrl & 15) + 16 : (quadcolor->cgacol & 15) + 16; /* TODO: Is Quadcolor bg color actually relevant, here? */ + + if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES) + hline(buffer32, 0, line, (quadcolor->crtc[CGA_CRTC_HDISP] << 3) + 16, col); + else + hline(buffer32, 0, line, (quadcolor->crtc[CGA_CRTC_HDISP] << 4) + 16, col); +} + +static void +quadcolor_render_process(quadcolor_t *quadcolor, int line) +{ + int x; + uint8_t border; + int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS); + + if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES) + x = (quadcolor->crtc[CGA_CRTC_HDISP] << 3) + 16; + else + x = (quadcolor->crtc[CGA_CRTC_HDISP] << 4) + 16; + + if (quadcolor->composite) { + border = ((quadcolor->cgamode & highres_graphics_flag) == highres_graphics_flag) ? 0 : (quadcolor->cgacol & 15); + + Composite_Process(quadcolor->cgamode, border, x >> 2, buffer32->line[line]); + } else + video_process_8(x, line); +} + +static uint8_t +quadcolor_interpolate_srgb(uint8_t co1, uint8_t co2, double fraction) +{ + uint8_t ret = ((co2 - co1) * fraction + co1); + + return ret; +} + +static uint8_t +quadcolor_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) round(r2 * 255.0); + + return ret; +} + +static color_t +quadcolor_interpolate_lookup(quadcolor_t *quadcolor, color_t color1, color_t color2, UNUSED(double fraction)) +{ + color_t ret; + uint8_t dt = quadcolor->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 +quadcolor_interpolate(quadcolor_t *quadcolor, 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 = quadcolor_interpolate_lookup(quadcolor, prev_color, black, quotient); + interim_2 = quadcolor_interpolate_lookup(quadcolor, black, next_color, quotient); + final = quadcolor_interpolate_lookup(quadcolor, interim_1, interim_2, quotient); + + buffer32->line[i][j] = final.color; + } + } +} + +static void +quadcolor_blit_memtoscreen(quadcolor_t *quadcolor, int x, int y, int w, int h) +{ + if (quadcolor->double_type > DOUBLE_SIMPLE) + quadcolor_interpolate(quadcolor, x, y, w, h); + + video_blit_memtoscreen(x, y, w, h); +} + +void +quadcolor_poll(void *priv) +{ + quadcolor_t *quadcolor = (quadcolor_t *) priv; + int x; + int scanline_old; + int oldvc; + int xs_temp; + int ys_temp; + int old_ma; + + if (!quadcolor->linepos) { + timer_advance_u64(&quadcolor->timer, quadcolor->dispofftime); + quadcolor->cgastat |= 1; + quadcolor->linepos = 1; + scanline_old = quadcolor->scanline; + if ((quadcolor->crtc[CGA_CRTC_INTERLACE] & 3) == 3) + quadcolor->scanline = ((quadcolor->scanline << 1) + quadcolor->oddeven) & 7; + if (quadcolor->cgadispon) { + if (quadcolor->displine < quadcolor->firstline) { + quadcolor->firstline = quadcolor->displine; + video_wait_for_buffer(); + } + quadcolor->lastline = quadcolor->displine; + switch (quadcolor->double_type) { + default: + quadcolor_render(quadcolor, quadcolor->displine << 1); + quadcolor_render_blank(quadcolor, (quadcolor->displine << 1) + 1); + break; + case DOUBLE_NONE: + quadcolor_render(quadcolor, quadcolor->displine); + break; + case DOUBLE_SIMPLE: + old_ma = quadcolor->memaddr; + quadcolor_render(quadcolor, quadcolor->displine << 1); + quadcolor->memaddr = old_ma; + quadcolor_render(quadcolor, (quadcolor->displine << 1) + 1); + break; + } + } else { + switch (quadcolor->double_type) { + default: + quadcolor_render_blank(quadcolor, quadcolor->displine << 1); + break; + case DOUBLE_NONE: + quadcolor_render_blank(quadcolor, quadcolor->displine); + break; + case DOUBLE_SIMPLE: + quadcolor_render_blank(quadcolor, quadcolor->displine << 1); + quadcolor_render_blank(quadcolor, (quadcolor->displine << 1) + 1); + break; + } + } + + switch (quadcolor->double_type) { + default: + quadcolor_render_process(quadcolor, quadcolor->displine << 1); + quadcolor_render_process(quadcolor, (quadcolor->displine << 1) + 1); + break; + case DOUBLE_NONE: + quadcolor_render_process(quadcolor, quadcolor->displine); + break; + } + + quadcolor->scanline = scanline_old; + if (quadcolor->vc == quadcolor->crtc[CGA_CRTC_VSYNC] && !quadcolor->scanline) + quadcolor->cgastat |= 8; + quadcolor->displine++; + if (quadcolor->displine >= 360) + quadcolor->displine = 0; + } else { + timer_advance_u64(&quadcolor->timer, quadcolor->dispontime); + quadcolor->linepos = 0; + if (quadcolor->vsynctime) { + quadcolor->vsynctime--; + if (!quadcolor->vsynctime) + quadcolor->cgastat &= ~8; + quadcolor->qc2idx = 0; + quadcolor->qc2mask = 0xf0; + } + if (quadcolor->scanline == (quadcolor->crtc[CGA_CRTC_CURSOR_END] & 31) || ((quadcolor->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && + quadcolor->scanline == ((quadcolor->crtc[CGA_CRTC_CURSOR_END] & 31) >> 1))) { + quadcolor->cursorvisible = 0; + } + if ((quadcolor->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && quadcolor->scanline == (quadcolor->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] >> 1)) + quadcolor->memaddr_backup = quadcolor->memaddr; + if (quadcolor->vadj) { + quadcolor->scanline++; + quadcolor->scanline &= 31; + quadcolor->memaddr = quadcolor->memaddr_backup; + quadcolor->vadj--; + if (!quadcolor->vadj) { + quadcolor->cgadispon = 1; + quadcolor->memaddr = quadcolor->memaddr_backup = (quadcolor->crtc[CGA_CRTC_START_ADDR_LOW] | (quadcolor->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & DEVICE_VRAM_MASK; + quadcolor->scanline = 0; + } + } else if (quadcolor->scanline == quadcolor->crtc[CGA_CRTC_MAX_SCANLINE_ADDR]) { + quadcolor->memaddr_backup = quadcolor->memaddr; + quadcolor->scanline = 0; + oldvc = quadcolor->vc; + quadcolor->vc++; + quadcolor->vc &= 127; + + if (quadcolor->vc == quadcolor->crtc[CGA_CRTC_VDISP]) + quadcolor->cgadispon = 0; + + if (oldvc == quadcolor->crtc[CGA_CRTC_VTOTAL]) { + quadcolor->vc = 0; + quadcolor->vadj = quadcolor->crtc[CGA_CRTC_VTOTAL_ADJUST]; + if (!quadcolor->vadj) { + quadcolor->cgadispon = 1; + quadcolor->memaddr = quadcolor->memaddr_backup = (quadcolor->crtc[CGA_CRTC_START_ADDR_LOW] | (quadcolor->crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & DEVICE_VRAM_MASK; + } + + switch (quadcolor->crtc[CGA_CRTC_CURSOR_START] & 0x60) { + case 0x20: + quadcolor->cursoron = 0; + break; + case 0x60: + quadcolor->cursoron = quadcolor->cgablink & 0x10; + break; + default: + quadcolor->cursoron = quadcolor->cgablink & 0x08; + break; + } + } + + if (quadcolor->vc == quadcolor->crtc[CGA_CRTC_VSYNC]) { + quadcolor->cgadispon = 0; + quadcolor->displine = 0; + quadcolor->vsynctime = 16; + if (quadcolor->crtc[CGA_CRTC_VSYNC]) { + if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES) + x = (quadcolor->crtc[CGA_CRTC_HDISP] << 3) + 16; + else + x = (quadcolor->crtc[CGA_CRTC_HDISP] << 4) + 16; + quadcolor->lastline++; + + xs_temp = x; + ys_temp = quadcolor->lastline - quadcolor->firstline; + if (quadcolor->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 = 200; + if (!enable_overscan) + xs_temp -= 16; + + if ((quadcolor->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && ((xs_temp != xsize) || + (ys_temp != ysize) || video_force_resize_get())) { + xsize = xs_temp; + ysize = ys_temp; + if (quadcolor->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 (quadcolor->double_type > DOUBLE_NONE) { + if (enable_overscan) + quadcolor_blit_memtoscreen(quadcolor, 0, (quadcolor->firstline - 4) << 1, + xsize, ((quadcolor->lastline - quadcolor->firstline) << 1) + 16); + else + quadcolor_blit_memtoscreen(quadcolor, 8, quadcolor->firstline << 1, + xsize, (quadcolor->lastline - quadcolor->firstline) << 1); + } else { + if (enable_overscan) + video_blit_memtoscreen(0, quadcolor->firstline - 4, + xsize, (quadcolor->lastline - quadcolor->firstline) + 8); + else + video_blit_memtoscreen(8, quadcolor->firstline, + xsize, quadcolor->lastline - quadcolor->firstline); + } + } + + frames++; + + video_res_x = xsize; + video_res_y = ysize; + if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES) { + video_res_x /= 8; + video_res_y /= quadcolor->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1; + video_bpp = 0; + } else if (!(quadcolor->cgamode & CGA_MODE_FLAG_GRAPHICS)) { + video_res_x /= 16; + video_res_y /= quadcolor->crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1; + video_bpp = 0; + } else if (!(quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) { + video_res_x /= 2; + video_bpp = 2; + } else + video_bpp = 1; + } + quadcolor->firstline = 1000; + quadcolor->lastline = 0; + quadcolor->cgablink++; + quadcolor->oddeven ^= 1; + } + } else { + quadcolor->scanline++; + quadcolor->scanline &= 31; + quadcolor->memaddr = quadcolor->memaddr_backup; + } + if (quadcolor->cgadispon) + quadcolor->cgastat &= ~1; + if (quadcolor->scanline == (quadcolor->crtc[CGA_CRTC_CURSOR_START] & 31) || ((quadcolor->crtc[CGA_CRTC_INTERLACE] & 3) == 3 && + quadcolor->scanline == ((quadcolor->crtc[CGA_CRTC_CURSOR_START] & 31) >> 1))) + quadcolor->cursorvisible = 1; + if (quadcolor->cgadispon && (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES)) { + for (x = 0; x < (quadcolor->crtc[CGA_CRTC_HDISP] << 1); x++) + quadcolor->charbuffer[x] = quadcolor->vram[(quadcolor->page_offset ^ ((quadcolor->memaddr << 1) + x)) & DEVICE_VRAM_MASK]; + } + } +} + +void +quadcolor_init(quadcolor_t *quadcolor) +{ + timer_add(&quadcolor->timer, quadcolor_poll, quadcolor, 1); + quadcolor->composite = 0; +} + +void * +quadcolor_standalone_init(UNUSED(const device_t *info)) +{ + int display_type; + quadcolor_t *quadcolor = calloc(1, sizeof(quadcolor_t)); + + video_inform(VIDEO_FLAG_TYPE_CGA, &timing_quadcolor); + + display_type = device_get_config_int("display_type"); + quadcolor->composite = (display_type != CGA_RGB); + quadcolor->revision = device_get_config_int("composite_type"); + quadcolor->has_2nd_charset = device_get_config_int("has_2nd_charset"); + quadcolor->has_quadcolor_2 = device_get_config_int("has_quadcolor_2"); + + quadcolor->vram = malloc(DEVICE_VRAM); + quadcolor->vram_2 = malloc(0x10000); + + cga_comp_init(quadcolor->revision); + timer_add(&quadcolor->timer, quadcolor_poll, quadcolor, 1); + mem_mapping_add(&quadcolor->mapping, 0xb8000, 0x08000, quadcolor_read, NULL, NULL, quadcolor_write, NULL, NULL, NULL /*quadcolor->vram*/, MEM_MAPPING_EXTERNAL, quadcolor); + /* add mapping for vram_2 at 0xd0000, mirrored at 0xe0000 */ + if (quadcolor->has_quadcolor_2) + mem_mapping_add(&quadcolor->mapping_2, 0xd0000, 0x20000, quadcolor_2_read, NULL, NULL, quadcolor_2_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, + quadcolor); + + io_sethandler(0x03d0, 0x0010, quadcolor_in, NULL, NULL, quadcolor_out, NULL, NULL, quadcolor); + + overscan_x = overscan_y = 16; + + quadcolor->rgb_type = device_get_config_int("rgb_type"); + cga_palette = (quadcolor->rgb_type << 1); + cgapal_rebuild(); + update_cga16_color(quadcolor->cgamode); + + quadcolor->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] = quadcolor_interpolate_srgb(i, j, 0.5); + interp_lut[1][i][j] = quadcolor_interpolate_linear(i, j, 0.5); + } + } + + switch(device_get_config_int("font")) { + case 0: + loadfont(FONT_IBM_MDA_437_PATH, 0); + break; + case 1: + loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0); + break; + case 4: + loadfont(FONT_TULIP_DGA_PATH, 0); + break; + } + + return quadcolor; +} + +void +quadcolor_close(void *priv) +{ + quadcolor_t *quadcolor = (quadcolor_t *) priv; + + free(quadcolor->vram); + free(quadcolor->vram_2); + free(quadcolor); +} + +void +quadcolor_speed_changed(void *priv) +{ + quadcolor_t *quadcolor = (quadcolor_t *) priv; + + quadcolor_recalctimings(quadcolor); +} + +// clang-format off +const device_config_t quadcolor_config[] = { + { + .name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = CGA_RGB, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "RGB", .value = CGA_RGB }, + { .description = "Composite", .value = CGA_COMPOSITE }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "composite_type", + .description = "Composite type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = COMPOSITE_OLD, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Old", .value = COMPOSITE_OLD }, + { .description = "New", .value = COMPOSITE_NEW }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "rgb_type", + .description = "RGB type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Color (generic)", .value = 0 }, + { .description = "Green Monochrome", .value = 1 }, + { .description = "Amber Monochrome", .value = 2 }, + { .description = "Gray Monochrome", .value = 3 }, + { .description = "Color (no brown)", .value = 4 }, + { .description = "Color (IBM 5153)", .value = 5 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "double_type", + .description = "Line doubling type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = DOUBLE_NONE, + .file_filter = NULL, + .spinner = { 0 }, + .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 = "" } + }, + .bios = { { 0 } } + }, + { + .name = "font", + .description = "Font", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "US (CP 437)", .value = 0 }, + { .description = "IBM Nordic (CP 437-Nordic)", .value = 1 }, + { .description = "Tulip DGA", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "has_2nd_charset", + .description = "Has secondary 8x8 character set", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "has_quadcolor_2", + .description = "Has Quadcolor II daughter board", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "contrast", + .description = "Alternate monochrome contrast", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +const device_t quadcolor_device = { + .name = "Quadram Quadcolor I / I+II", + .internal_name = "quadcolor", + .flags = DEVICE_ISA, + .local = 0, + .init = quadcolor_standalone_init, + .close = quadcolor_close, + .reset = NULL, + .available = NULL, + .speed_changed = quadcolor_speed_changed, + .force_redraw = NULL, + .config = quadcolor_config +}; diff --git a/src/machine/m_xt_t1000_vid.c b/src/video/vid_cga_toshiba_t1000.c similarity index 88% rename from src/machine/m_xt_t1000_vid.c rename to src/video/vid_cga_toshiba_t1000.c index efad869e1..2fd382272 100644 --- a/src/machine/m_xt_t1000_vid.c +++ b/src/video/vid_cga_toshiba_t1000.c @@ -245,25 +245,25 @@ t1000_text_row80(t1000_t *t1000) int bold; int blink; uint16_t addr; - uint8_t sc; - uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; - uint16_t ca = (t1000->cga.crtc[15] | (t1000->cga.crtc[14] << 8)) & 0x3fff; + uint8_t scanline; + uint16_t memaddr = (t1000->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t1000->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + uint16_t cursoraddr = (t1000->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (t1000->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff; - sc = (t1000->displine) & 7; - addr = ((ma & ~1) + (t1000->displine >> 3) * 80) * 2; - ma += (t1000->displine >> 3) * 80; + scanline = (t1000->displine) & 7; + addr = ((memaddr & ~1) + (t1000->displine >> 3) * 80) * 2; + memaddr += (t1000->displine >> 3) * 80; - if ((t1000->cga.crtc[10] & 0x60) == 0x20) { + if ((t1000->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) { cursorline = 0; } else { - cursorline = ((t1000->cga.crtc[10] & 0x0F) <= sc) && ((t1000->cga.crtc[11] & 0x0F) >= sc); + cursorline = ((t1000->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0F) <= scanline) && ((t1000->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0F) >= scanline); } for (uint8_t x = 0; x < 80; x++) { chr = t1000->vram[(addr + 2 * x) & 0x3FFF]; attr = t1000->vram[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && (t1000->cga.cgamode & 8) && (t1000->cga.cgablink & 16)); + drawcursor = ((memaddr == cursoraddr) && cursorline && (t1000->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && (t1000->cga.cgablink & 16)); - blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); + blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor); if (t1000->video_options & 1) bold = boldcols[attr] ? chr : chr + 256; @@ -272,7 +272,7 @@ t1000_text_row80(t1000_t *t1000) if (t1000->video_options & 2) bold += 512; - if (t1000->cga.cgamode & 0x20) /* Blink */ + if (t1000->cga.cgamode & CGA_MODE_FLAG_BLINK) /* Blink */ { cols[1] = blinkcols[attr][1]; cols[0] = blinkcols[attr][0]; @@ -284,13 +284,13 @@ t1000_text_row80(t1000_t *t1000) } if (drawcursor) { for (uint8_t c = 0; c < 8; c++) { - (buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); + (buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); } } else { for (uint8_t c = 0; c < 8; c++) - (buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; + (buffer32->line[t1000->displine])[(x << 3) + c] = cols[(fontdat[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0]; } - ++ma; + ++memaddr; } } @@ -306,25 +306,25 @@ t1000_text_row40(t1000_t *t1000) int bold; int blink; uint16_t addr; - uint8_t sc; - uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; - uint16_t ca = (t1000->cga.crtc[15] | (t1000->cga.crtc[14] << 8)) & 0x3fff; + uint8_t scanline; + uint16_t memaddr = (t1000->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t1000->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + uint16_t cursoraddr = (t1000->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (t1000->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff; - sc = (t1000->displine) & 7; - addr = ((ma & ~1) + (t1000->displine >> 3) * 40) * 2; - ma += (t1000->displine >> 3) * 40; + scanline = (t1000->displine) & 7; + addr = ((memaddr & ~1) + (t1000->displine >> 3) * 40) * 2; + memaddr += (t1000->displine >> 3) * 40; - if ((t1000->cga.crtc[10] & 0x60) == 0x20) { + if ((t1000->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) { cursorline = 0; } else { - cursorline = ((t1000->cga.crtc[10] & 0x0F) <= sc) && ((t1000->cga.crtc[11] & 0x0F) >= sc); + cursorline = ((t1000->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0F) <= scanline) && ((t1000->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0F) >= scanline); } for (uint8_t x = 0; x < 40; x++) { chr = t1000->vram[(addr + 2 * x) & 0x3FFF]; attr = t1000->vram[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && (t1000->cga.cgamode & 8) && (t1000->cga.cgablink & 16)); + drawcursor = ((memaddr == cursoraddr) && cursorline && (t1000->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && (t1000->cga.cgablink & 16)); - blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); + blink = ((t1000->cga.cgablink & 16) && (t1000->cga.cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor); if (t1000->video_options & 1) bold = boldcols[attr] ? chr : chr + 256; @@ -333,7 +333,7 @@ t1000_text_row40(t1000_t *t1000) if (t1000->video_options & 2) bold += 512; - if (t1000->cga.cgamode & 0x20) /* Blink */ + if (t1000->cga.cgamode & CGA_MODE_FLAG_BLINK) /* Blink */ { cols[1] = blinkcols[attr][1]; cols[0] = blinkcols[attr][0]; @@ -345,14 +345,14 @@ t1000_text_row40(t1000_t *t1000) } if (drawcursor) { for (uint8_t c = 0; c < 8; c++) { - (buffer32->line[t1000->displine])[(x << 4) + c * 2] = (buffer32->line[t1000->displine])[(x << 4) + c * 2 + 1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); + (buffer32->line[t1000->displine])[(x << 4) + c * 2] = (buffer32->line[t1000->displine])[(x << 4) + c * 2 + 1] = cols[(fontdat[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0] ^ (blue ^ grey); } } else { for (uint8_t c = 0; c < 8; c++) { - (buffer32->line[t1000->displine])[(x << 4) + c * 2] = (buffer32->line[t1000->displine])[(x << 4) + c * 2 + 1] = cols[(fontdat[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; + (buffer32->line[t1000->displine])[(x << 4) + c * 2] = (buffer32->line[t1000->displine])[(x << 4) + c * 2 + 1] = cols[(fontdat[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0]; } } - ++ma; + ++memaddr; } } @@ -366,9 +366,9 @@ t1000_cgaline6(t1000_t *t1000) uint32_t fg = (t1000->cga.cgacol & 0x0F) ? blue : grey; uint32_t bg = grey; - uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; + uint16_t memaddr = (t1000->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t1000->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; - addr = ((t1000->displine) & 1) * 0x2000 + (t1000->displine >> 1) * 80 + ((ma & ~1) << 1); + addr = ((t1000->displine) & 1) * 0x2000 + (t1000->displine >> 1) * 80 + ((memaddr & ~1) << 1); for (uint8_t x = 0; x < 80; x++) { dat = t1000->vram[addr & 0x3FFF]; @@ -376,7 +376,7 @@ t1000_cgaline6(t1000_t *t1000) for (uint8_t c = 0; c < 8; c++) { ink = (dat & 0x80) ? fg : bg; - if (!(t1000->cga.cgamode & 8)) + if (!(t1000->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE)) ink = grey; (buffer32->line[t1000->displine])[x * 8 + c] = ink; dat = dat << 1; @@ -395,8 +395,8 @@ t1000_cgaline4(t1000_t *t1000) uint32_t ink1; uint16_t addr; - uint16_t ma = (t1000->cga.crtc[13] | (t1000->cga.crtc[12] << 8)) & 0x3fff; - addr = ((t1000->displine) & 1) * 0x2000 + (t1000->displine >> 1) * 80 + ((ma & ~1) << 1); + uint16_t memaddr = (t1000->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t1000->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + addr = ((t1000->displine) & 1) * 0x2000 + (t1000->displine >> 1) * 80 + ((memaddr & ~1) << 1); for (uint8_t x = 0; x < 80; x++) { dat = t1000->vram[addr & 0x3FFF]; @@ -404,7 +404,7 @@ t1000_cgaline4(t1000_t *t1000) for (uint8_t c = 0; c < 4; c++) { pattern = (dat & 0xC0) >> 6; - if (!(t1000->cga.cgamode & 8)) + if (!(t1000->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE)) pattern = 0; switch (pattern & 3) { @@ -479,7 +479,7 @@ t1000_poll(void *priv) /* Graphics */ if (t1000->cga.cgamode & 0x02) { - if (t1000->cga.cgamode & 0x10) + if (t1000->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS) t1000_cgaline6(t1000); else t1000_cgaline4(t1000); @@ -532,7 +532,7 @@ t1000_poll(void *priv) video_res_y = T1000_YSIZE; if (t1000->cga.cgamode & 0x02) { - if (t1000->cga.cgamode & 0x10) + if (t1000->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS) video_bpp = 1; else video_bpp = 2; diff --git a/src/machine/m_at_t3100e_vid.c b/src/video/vid_cga_toshiba_t3100e.c similarity index 84% rename from src/machine/m_at_t3100e_vid.c rename to src/video/vid_cga_toshiba_t3100e.c index c827a05e5..e3eb673c8 100644 --- a/src/machine/m_at_t3100e_vid.c +++ b/src/video/vid_cga_toshiba_t3100e.c @@ -169,8 +169,8 @@ t3100e_out(uint16_t addr, uint8_t val, void *priv) t3100e_recalctimings(t3100e); return; - case 0x3D8: /* CGA control register */ - case 0x3D9: /* CGA colour register */ + case CGA_REGISTER_MODE_CONTROL: /* CGA control register */ + case CGA_REGISTER_COLOR_SELECT: /* CGA colour register */ cga_out(addr, val, &t3100e->cga); return; @@ -254,25 +254,25 @@ t3100e_text_row80(t3100e_t *t3100e) int bold; int blink; uint16_t addr; - uint8_t sc; - uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; - uint16_t ca = (t3100e->cga.crtc[15] | (t3100e->cga.crtc[14] << 8)) & 0x7fff; + uint8_t scanline; + uint16_t memaddr = (t3100e->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t3100e->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff; + uint16_t cursoraddr = (t3100e->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (t3100e->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x7fff; - sc = (t3100e->displine) & 15; - addr = ((ma & ~1) + (t3100e->displine >> 4) * 80) * 2; - ma += (t3100e->displine >> 4) * 80; + scanline = (t3100e->displine) & 15; + addr = ((memaddr & ~1) + (t3100e->displine >> 4) * 80) * 2; + memaddr += (t3100e->displine >> 4) * 80; - if ((t3100e->cga.crtc[10] & 0x60) == 0x20) { + if ((t3100e->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) { cursorline = 0; } else { - cursorline = ((t3100e->cga.crtc[10] & 0x0F) * 2 <= sc) && ((t3100e->cga.crtc[11] & 0x0F) * 2 >= sc); + cursorline = ((t3100e->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0F) * 2 <= scanline) && ((t3100e->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0F) * 2 >= scanline); } for (uint8_t x = 0; x < 80; x++) { chr = t3100e->vram[(addr + 2 * x) & 0x7FFF]; attr = t3100e->vram[(addr + 2 * x + 1) & 0x7FFF]; - drawcursor = ((ma == ca) && cursorline && (t3100e->cga.cgamode & 8) && (t3100e->cga.cgablink & 16)); + drawcursor = ((memaddr == cursoraddr) && cursorline && (t3100e->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && (t3100e->cga.cgablink & 16)); - blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); + blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor); if (t3100e->video_options & 4) bold = boldcols[attr] ? chr + 256 : chr; @@ -280,7 +280,7 @@ t3100e_text_row80(t3100e_t *t3100e) bold = boldcols[attr] ? chr : chr + 256; bold += 512 * (t3100e->video_options & 3); - if (t3100e->cga.cgamode & 0x20) /* Blink */ + if (t3100e->cga.cgamode & CGA_MODE_FLAG_BLINK) /* Blink */ { cols[1] = blinkcols[attr][1]; cols[0] = blinkcols[attr][0]; @@ -292,13 +292,13 @@ t3100e_text_row80(t3100e_t *t3100e) } if (drawcursor) { for (uint8_t c = 0; c < 8; c++) { - (buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + (buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); } } else { for (uint8_t c = 0; c < 8; c++) - (buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; + (buffer32->line[t3100e->displine])[(x << 3) + c] = cols[(fontdatm[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0]; } - ++ma; + ++memaddr; } } @@ -315,25 +315,25 @@ t3100e_text_row40(t3100e_t *t3100e) int bold; int blink; uint16_t addr; - uint8_t sc; - uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; - uint16_t ca = (t3100e->cga.crtc[15] | (t3100e->cga.crtc[14] << 8)) & 0x7fff; + uint8_t scanline; + uint16_t memaddr = (t3100e->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t3100e->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff; + uint16_t cursoraddr = (t3100e->cga.crtc[CGA_CRTC_CURSOR_ADDR_LOW] | (t3100e->cga.crtc[CGA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x7fff; - sc = (t3100e->displine) & 15; - addr = ((ma & ~1) + (t3100e->displine >> 4) * 40) * 2; - ma += (t3100e->displine >> 4) * 40; + scanline = (t3100e->displine) & 15; + addr = ((memaddr & ~1) + (t3100e->displine >> 4) * 40) * 2; + memaddr += (t3100e->displine >> 4) * 40; - if ((t3100e->cga.crtc[10] & 0x60) == 0x20) { + if ((t3100e->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) { cursorline = 0; } else { - cursorline = ((t3100e->cga.crtc[10] & 0x0F) * 2 <= sc) && ((t3100e->cga.crtc[11] & 0x0F) * 2 >= sc); + cursorline = ((t3100e->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0F) * 2 <= scanline) && ((t3100e->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0F) * 2 >= scanline); } for (uint8_t x = 0; x < 40; x++) { chr = t3100e->vram[(addr + 2 * x) & 0x7FFF]; attr = t3100e->vram[(addr + 2 * x + 1) & 0x7FFF]; - drawcursor = ((ma == ca) && cursorline && (t3100e->cga.cgamode & 8) && (t3100e->cga.cgablink & 16)); + drawcursor = ((memaddr == cursoraddr) && cursorline && (t3100e->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && (t3100e->cga.cgablink & 16)); - blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); + blink = ((t3100e->cga.cgablink & 16) && (t3100e->cga.cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor); if (t3100e->video_options & 4) bold = boldcols[attr] ? chr + 256 : chr; @@ -341,7 +341,7 @@ t3100e_text_row40(t3100e_t *t3100e) bold = boldcols[attr] ? chr : chr + 256; bold += 512 * (t3100e->video_options & 3); - if (t3100e->cga.cgamode & 0x20) /* Blink */ + if (t3100e->cga.cgamode & CGA_MODE_FLAG_BLINK) /* Blink */ { cols[1] = blinkcols[attr][1]; cols[0] = blinkcols[attr][0]; @@ -353,14 +353,14 @@ t3100e_text_row40(t3100e_t *t3100e) } if (drawcursor) { for (c = 0; c < 8; c++) { - (buffer32->line[t3100e->displine])[(x << 4) + c * 2] = (buffer32->line[t3100e->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + (buffer32->line[t3100e->displine])[(x << 4) + c * 2] = (buffer32->line[t3100e->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); } } else { for (c = 0; c < 8; c++) { - (buffer32->line[t3100e->displine])[(x << 4) + c * 2] = (buffer32->line[t3100e->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0]; + (buffer32->line[t3100e->displine])[(x << 4) + c * 2] = (buffer32->line[t3100e->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[bold][scanline] & (1 << (c ^ 7))) ? 1 : 0]; } } - ++ma; + ++memaddr; } } @@ -374,13 +374,13 @@ t3100e_cgaline6(t3100e_t *t3100e) uint32_t fg = (t3100e->cga.cgacol & 0x0F) ? amber : black; uint32_t bg = black; - uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; + uint16_t memaddr = (t3100e->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t3100e->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff; - if (t3100e->cga.crtc[9] == 3) /* 640*400 */ + if (t3100e->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] == 3) /* 640*400 */ { - addr = ((t3100e->displine) & 1) * 0x2000 + ((t3100e->displine >> 1) & 1) * 0x4000 + (t3100e->displine >> 2) * 80 + ((ma & ~1) << 1); + addr = ((t3100e->displine) & 1) * 0x2000 + ((t3100e->displine >> 1) & 1) * 0x4000 + (t3100e->displine >> 2) * 80 + ((memaddr & ~1) << 1); } else { - addr = ((t3100e->displine >> 1) & 1) * 0x2000 + (t3100e->displine >> 2) * 80 + ((ma & ~1) << 1); + addr = ((t3100e->displine >> 1) & 1) * 0x2000 + (t3100e->displine >> 2) * 80 + ((memaddr & ~1) << 1); } for (uint8_t x = 0; x < 80; x++) { dat = t3100e->vram[addr & 0x7FFF]; @@ -388,7 +388,7 @@ t3100e_cgaline6(t3100e_t *t3100e) for (uint8_t c = 0; c < 8; c++) { ink = (dat & 0x80) ? fg : bg; - if (!(t3100e->cga.cgamode & 8)) + if (!(t3100e->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE)) ink = black; (buffer32->line[t3100e->displine])[x * 8 + c] = ink; dat = dat << 1; @@ -407,13 +407,13 @@ t3100e_cgaline4(t3100e_t *t3100e) uint32_t ink1 = 0; uint16_t addr; - uint16_t ma = (t3100e->cga.crtc[13] | (t3100e->cga.crtc[12] << 8)) & 0x7fff; - if (t3100e->cga.crtc[9] == 3) /* 320*400 undocumented */ + uint16_t memaddr = (t3100e->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (t3100e->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x7fff; + if (t3100e->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] == 3) /* 320*400 undocumented */ { - addr = ((t3100e->displine) & 1) * 0x2000 + ((t3100e->displine >> 1) & 1) * 0x4000 + (t3100e->displine >> 2) * 80 + ((ma & ~1) << 1); + addr = ((t3100e->displine) & 1) * 0x2000 + ((t3100e->displine >> 1) & 1) * 0x4000 + (t3100e->displine >> 2) * 80 + ((memaddr & ~1) << 1); } else /* 320*200 */ { - addr = ((t3100e->displine >> 1) & 1) * 0x2000 + (t3100e->displine >> 2) * 80 + ((ma & ~1) << 1); + addr = ((t3100e->displine >> 1) & 1) * 0x2000 + (t3100e->displine >> 2) * 80 + ((memaddr & ~1) << 1); } for (uint8_t x = 0; x < 80; x++) { dat = t3100e->vram[addr & 0x7FFF]; @@ -421,7 +421,7 @@ t3100e_cgaline4(t3100e_t *t3100e) for (uint8_t c = 0; c < 4; c++) { pattern = (dat & 0xC0) >> 6; - if (!(t3100e->cga.cgamode & 8)) + if (!(t3100e->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE)) pattern = 0; switch (pattern & 3) { @@ -497,12 +497,12 @@ t3100e_poll(void *priv) } /* Graphics */ - if (t3100e->cga.cgamode & 0x02) { - if (t3100e->cga.cgamode & 0x10) + if (t3100e->cga.cgamode & CGA_MODE_FLAG_GRAPHICS) { + if (t3100e->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS) t3100e_cgaline6(t3100e); else t3100e_cgaline4(t3100e); - } else if (t3100e->cga.cgamode & 0x01) /* High-res text */ + } else if (t3100e->cga.cgamode & CGA_MODE_FLAG_HIGHRES) /* High-res text */ { t3100e_text_row80(t3100e); } else { @@ -550,8 +550,8 @@ t3100e_poll(void *priv) video_res_x = T3100E_XSIZE; video_res_y = T3100E_YSIZE; - if (t3100e->cga.cgamode & 0x02) { - if (t3100e->cga.cgamode & 0x10) + if (t3100e->cga.cgamode & CGA_MODE_FLAG_GRAPHICS) { + if (t3100e->cga.cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS) video_bpp = 1; else video_bpp = 2; diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index c9830f0ed..70b2b9e16 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -1098,7 +1098,7 @@ chips_69000_recalctimings(svga_t *svga) svga->hblank_end_val = ((svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00)) | (svga->crtc[0x3c] & 0b11000000); svga->hblank_end_mask = 0xff; - svga->ma_latch |= (svga->crtc[0x40] & 0xF) << 16; + svga->memaddr_latch |= (svga->crtc[0x40] & 0xF) << 16; svga->rowoffset |= (svga->crtc[0x41] & 0xF) << 8; svga->interlace = !!(svga->crtc[0x70] & 0x80); @@ -1268,15 +1268,15 @@ chips_69000_process_pixel(chips_69000_t* chips, uint32_t pixel) if (chips->bitblt_running.bytes_per_pixel == 3) { pattern_pixel = chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) - + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)), chips); + + (3 * ((((chips->bitblt_running.bitblt.destination_addr / 3) & 7) + chips->bitblt_running.x) & 7)), chips); pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) - + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 1, chips) << 8; + + (3 * ((((chips->bitblt_running.bitblt.destination_addr / 3) & 7) + chips->bitblt_running.x) & 7)) + 1, chips) << 8; pattern_pixel |= chips_69000_readb_linear(chips->bitblt_running.bitblt.pat_addr + (4 * 8 * ((vert_pat_alignment + chips->bitblt_running.y) & 7)) - + (3 * (((chips->bitblt_running.bitblt.destination_addr & 7) + chips->bitblt_running.x) & 7)) + 2, chips) << 16; + + (3 * ((((chips->bitblt_running.bitblt.destination_addr / 3) & 7) + chips->bitblt_running.x) & 7)) + 2, chips) << 16; } } if (chips->bitblt_running.bytes_per_pixel == 2) { @@ -2044,7 +2044,7 @@ chips_69000_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -2247,8 +2247,8 @@ chips_69000_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0x13: - chips->linear_mapping.base = val << 24; mem_mapping_disable(&chips->linear_mapping); + chips->linear_mapping.base = val << 24; if ((chips->pci_conf_status & PCI_COMMAND_MEM) && (chips->linear_mapping.base > 0x00000000)) mem_mapping_set_addr(&chips->linear_mapping, chips->linear_mapping.base, (1 << 24)); @@ -2786,6 +2786,8 @@ chips_69000_disable_handlers(chips_69000_t *chips) if (!chips->on_board) mem_mapping_disable(&chips->bios_rom.mapping); + chips->linear_mapping.base = 0; + /* Save all the mappings and the timers because they are part of linked lists. */ reset_state->linear_mapping = chips->linear_mapping; reset_state->svga.mapping = chips->svga.mapping; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 4988b3797..0a43ab4ce 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -33,6 +33,7 @@ #include <86box/pci.h> #include <86box/rom.h> #include <86box/device.h> +#include <86box/machine.h> #include <86box/timer.h> #include <86box/video.h> #include <86box/i2c.h> @@ -44,6 +45,7 @@ #include <86box/plat_unused.h> #define BIOS_GD5401_PATH "roms/video/cirruslogic/avga1.rom" +#define BIOS_GD5401_ONBOARD_PATH "roms/machines/drsm35286/qpaw01-6658237d5e3c2611427518.bin" #define BIOS_GD5402_PATH "roms/video/cirruslogic/avga2.rom" #define BIOS_GD5402_ONBOARD_PATH "roms/machines/cmdsl386sx25/c000.rom" #define BIOS_GD5420_PATH "roms/video/cirruslogic/5420.vbi" @@ -574,7 +576,7 @@ gd54xx_overlay_draw(svga_t *svga, int displine) 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]; + uint8_t *src2 = &svga->vram[(svga->memaddr - (svga->hdisp * bytesperpix)) & svga->vram_display_mask]; int occl; int ckval; @@ -1254,7 +1256,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; @@ -1701,6 +1703,7 @@ static void gd543x_recalc_mapping(gd54xx_t *gd54xx) { svga_t *svga = &gd54xx->svga; + xga_t *xga = (xga_t *) svga->xga; uint32_t base; uint32_t size; @@ -1727,6 +1730,10 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) { + xga->on = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + } break; case 0x8: /*32k at B0000*/ mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); @@ -1874,7 +1881,7 @@ gd54xx_recalctimings(svga_t *svga) } else if (svga->gdcreg[5] & 0x40) svga->render = svga_render_8bpp_lowres; - svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); + svga->memaddr_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); svga->bpp = 8; @@ -4141,8 +4148,6 @@ gd54xx_reset(void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - pclog("gd54xx_reset()\n"); - memset(svga->crtc, 0x00, sizeof(svga->crtc)); memset(svga->seqregs, 0x00, sizeof(svga->seqregs)); memset(svga->gdcreg, 0x00, sizeof(svga->gdcreg)); @@ -4237,8 +4242,11 @@ gd54xx_init(const device_t *info) switch (id) { case CIRRUS_ID_CLGD5401: - romfn = BIOS_GD5401_PATH; - break; + if (info->local & 0x100) + romfn = BIOS_GD5401_ONBOARD_PATH; + else + romfn = BIOS_GD5401_PATH; + break; case CIRRUS_ID_CLGD5402: if (info->local & 0x200) @@ -4248,14 +4256,23 @@ gd54xx_init(const device_t *info) break; case CIRRUS_ID_CLGD5420: - romfn = BIOS_GD5420_PATH; + if (info->local & 0x200) + romfn = NULL; + else + romfn = BIOS_GD5420_PATH; break; case CIRRUS_ID_CLGD5422: - case CIRRUS_ID_CLGD5424: romfn = BIOS_GD5422_PATH; break; + case CIRRUS_ID_CLGD5424: + if (info->local & 0x200) + romfn = /*NULL*/ "roms/machines/advantage40xxd/AST101.09A"; + else + romfn = BIOS_GD5422_PATH; + break; + case CIRRUS_ID_CLGD5426: if (info->local & 0x200) romfn = NULL; @@ -4274,7 +4291,10 @@ gd54xx_init(const device_t *info) break; case CIRRUS_ID_CLGD5428: - if (info->local & 0x100) + if (info->local & 0x200) { + romfn = NULL; + gd54xx->has_bios = 0; + } else if (info->local & 0x100) if (gd54xx->vlb) romfn = BIOS_GD5428_DIAMOND_B1_VLB_PATH; else { @@ -4318,7 +4338,8 @@ gd54xx_init(const device_t *info) break; case CIRRUS_ID_CLGD5436: - if (info->local & 0x200) { + if ((info->local & 0x200) && + !strstr(machine_get_internal_name(), "sb486pv")) { romfn = NULL; gd54xx->has_bios = 0; } else @@ -4463,8 +4484,8 @@ gd54xx_init(const device_t *info) } io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430) { - if (romfn == NULL) + if (gd54xx->pci && (id >= CIRRUS_ID_CLGD5430)) { + if (info->local & 0x200) 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); @@ -4750,26 +4771,6 @@ static const device_config_t gd5426_config[] = { { .name = "", .description = "", .type = CONFIG_END } }; -static const device_config_t gd5428_onboard_config[] = { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 2048, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "512 KB", .value = 512 }, - { .description = "1 MB", .value = 1024 }, - { .description = "2 MB", .value = 2048 }, - { .description = "" } - }, - .bios = { { 0 } } - }, - { .name = "", .description = "", .type = CONFIG_END } -}; - static const device_config_t gd5429_config[] = { { .name = "memory", @@ -4810,7 +4811,7 @@ static const device_config_t gd5430_vlb_config[] = { .description = "Linear framebuffer base", .type = CONFIG_SELECTION, .default_string = NULL, - .default_int = 2, + .default_int = 2048, .file_filter = NULL, .spinner = { 0 }, .selection = { @@ -4885,7 +4886,7 @@ static const device_config_t gd5434_vlb_config[] = { .description = "Linear framebuffer base", .type = CONFIG_SELECTION, .default_string = NULL, - .default_int = 2, + .default_int = 2048, .file_filter = NULL, .spinner = { 0 }, .selection = { @@ -4953,6 +4954,20 @@ const device_t gd5401_isa_device = { .config = NULL, }; +const device_t gd5401_onboard_device = { + .name = "Cirrus Logic GD5401 (ISA) (ACUMOS AVGA1) (On-Board)", + .internal_name = "cl_gd5402_onboard", + .flags = DEVICE_ISA16, + .local = CIRRUS_ID_CLGD5401 | 0x100, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, + .available = NULL, + .speed_changed = gd54xx_speed_changed, + .force_redraw = gd54xx_force_redraw, + .config = NULL, +}; + const device_t gd5402_isa_device = { .name = "Cirrus Logic GD5402 (ISA) (ACUMOS AVGA2)", .internal_name = "cl_gd5402_isa", @@ -4995,6 +5010,20 @@ const device_t gd5420_isa_device = { .config = gd542x_config, }; +const device_t gd5420_onboard_device = { + .name = "Cirrus Logic GD5420 (ISA) (On-Board)", + .internal_name = "cl_gd5420_onboard", + .flags = DEVICE_ISA16, + .local = CIRRUS_ID_CLGD5420 | 0x200, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, + .available = NULL, + .speed_changed = gd54xx_speed_changed, + .force_redraw = gd54xx_force_redraw, + .config = gd542x_config, +}; + const device_t gd5422_isa_device = { .name = "Cirrus Logic GD5422 (ISA)", .internal_name = "cl_gd5422_isa", @@ -5023,6 +5052,20 @@ const device_t gd5424_vlb_device = { .config = gd542x_config, }; +const device_t gd5424_onboard_device = { + .name = "Cirrus Logic GD5424 (VLB) (On-Board)", + .internal_name = "cl_gd5424_onboard", + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5424 | 0x200, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, + .available = NULL, + .speed_changed = gd54xx_speed_changed, + .force_redraw = gd54xx_force_redraw, + .config = gd542x_config, +}; + const device_t gd5426_isa_device = { .name = "Cirrus Logic GD5426 (ISA)", .internal_name = "cl_gd5426_isa", @@ -5176,7 +5219,7 @@ const device_t gd5428_onboard_device = { .available = gd5428_isa_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, - .config = gd5428_onboard_config + .config = gd5426_config }; const device_t gd5428_vlb_onboard_device = { @@ -5190,7 +5233,21 @@ const device_t gd5428_vlb_onboard_device = { .available = NULL, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, - .config = gd5428_onboard_config + .config = gd5426_config +}; + +const device_t gd5428_onboard_vlb_device = { + .name = "Cirrus Logic GD5428 (VLB) (On-Board) (Dell)", + .internal_name = "cl_gd5428_onboard_vlb", + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5428 | 0x200, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, + .available = NULL, + .speed_changed = gd54xx_speed_changed, + .force_redraw = gd54xx_force_redraw, + .config = gd542x_config }; const device_t gd5429_isa_device = { diff --git a/src/video/vid_compaq_cga.c b/src/video/vid_compaq_cga.c deleted file mode 100644 index 13fc399eb..000000000 --- a/src/video/vid_compaq_cga.c +++ /dev/null @@ -1,502 +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. - * - * Emulation of the Compaq CGA graphics cards. - * - * - * - * Authors: John Elliott, - * Sarah Walker, - * Miran Grca, - * - * Copyright 2016-2019 John Elliott. - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#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/video.h> -#include <86box/vid_cga.h> -#include <86box/vid_cga_comp.h> - -#define CGA_RGB 0 -#define CGA_COMPOSITE 1 - -static uint32_t vflags; -static uint8_t mdaattr[256][2][2]; - -typedef struct compaq_cga_t { - cga_t cga; -} compaq_cga_t; - -#ifdef ENABLE_COMPAQ_CGA_LOG -int compaq_cga_do_log = ENABLE_COMPAQ_CGA_LOG; - -static void -compaq_cga_log(const char *fmt, ...) -{ - va_list ap; - - if (compaq_cga_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define compaq_cga_log(fmt, ...) -#endif - -void -compaq_cga_recalctimings(compaq_cga_t *self) -{ - double _dispontime; - double _dispofftime; - double disptime; - disptime = self->cga.crtc[0] + 1; - - _dispontime = self->cga.crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - self->cga.dispontime = (uint64_t) (_dispontime); - self->cga.dispofftime = (uint64_t) (_dispofftime); -} - -void -compaq_cga_poll(void *priv) -{ - compaq_cga_t *self = (compaq_cga_t *) priv; - uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x; - int c; - int xs_temp; - int ys_temp; - int oldvc; - uint8_t chr; - uint8_t attr; - uint8_t border; - uint8_t cols[4]; - int oldsc; - int underline = 0; - int blink = 0; - - /* If in graphics mode or character height is not 13, behave as CGA */ - if ((self->cga.cgamode & 0x12) || (self->cga.crtc[9] != 13)) { - overscan_x = overscan_y = 16; - cga_poll(&self->cga); - return; - } else - overscan_x = overscan_y = 0; - - /* We are in Compaq 350-line CGA territory */ - if (!self->cga.linepos) { - timer_advance_u64(&self->cga.timer, self->cga.dispofftime); - self->cga.cgastat |= 1; - self->cga.linepos = 1; - oldsc = self->cga.sc; - if ((self->cga.crtc[8] & 3) == 3) - self->cga.sc = ((self->cga.sc << 1) + self->cga.oddeven) & 7; - if (self->cga.cgadispon) { - if (self->cga.displine < self->cga.firstline) { - self->cga.firstline = self->cga.displine; - video_wait_for_buffer(); - compaq_cga_log("Firstline %i\n", self->cga.firstline); - } - self->cga.lastline = self->cga.displine; - - cols[0] = (self->cga.cgacol & 15) + 16; - - for (c = 0; c < 8; c++) { - buffer32->line[self->cga.displine][c] = cols[0]; - if (self->cga.cgamode & 1) - buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 3) + 8] = cols[0]; - else - buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 4) + 8] = cols[0]; - } - - if (self->cga.cgamode & 1) { - for (x = 0; x < self->cga.crtc[1]; x++) { - chr = self->cga.charbuffer[x << 1]; - attr = self->cga.charbuffer[(x << 1) + 1]; - drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); - - if (vflags) { - underline = 0; - blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - } - - if (vflags && (self->cga.cgamode & 0x80)) { - cols[0] = mdaattr[attr][blink][0]; - cols[1] = mdaattr[attr][blink][1]; - - if ((self->cga.sc == 12) && ((attr & 7) == 1)) - underline = 1; - } else if (self->cga.cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; - - if (vflags) { - if (blink) - cols[1] = cols[0]; - } else { - if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) - cols[1] = cols[0]; - } - } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; - } - - if (vflags && underline) { - for (c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 3) + c + 8] = mdaattr[attr][blink][1]; - } else if (drawcursor) { - for (c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } else { - for (c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; - } - self->cga.ma++; - } - } else { - for (x = 0; x < self->cga.crtc[1]; x++) { - chr = self->cga.vram[(self->cga.ma << 1) & 0x3fff]; - attr = self->cga.vram[((self->cga.ma << 1) + 1) & 0x3fff]; - drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); - - if (vflags) { - underline = 0; - blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - } - - if (vflags && (self->cga.cgamode & 0x80)) { - cols[0] = mdaattr[attr][blink][0]; - cols[1] = mdaattr[attr][blink][1]; - if (self->cga.sc == 12 && (attr & 7) == 1) - underline = 1; - } else if (self->cga.cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; - - if (vflags) { - if (blink) - cols[1] = cols[0]; - } else { - if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) - cols[1] = cols[0]; - } - } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; - } - self->cga.ma++; - - if (vflags && underline) { - for (c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 9] = mdaattr[attr][blink][1]; - } else if (drawcursor) { - for (c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } else { - for (c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } - } else { - cols[0] = (self->cga.cgacol & 15) + 16; - - if (self->cga.cgamode & 1) - hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 3) + 16, cols[0]); - else - hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 4) + 16, cols[0]); - } - - if (self->cga.cgamode & 1) - x = (self->cga.crtc[1] << 3) + 16; - else - x = (self->cga.crtc[1] << 4) + 16; - - if (self->cga.composite) { - if (self->cga.cgamode & 0x10) - border = 0x00; - else - border = self->cga.cgacol & 0x0f; - - if (vflags) - Composite_Process(self->cga.cgamode & 0x7f, border, x >> 2, buffer32->line[self->cga.displine]); - else - Composite_Process(self->cga.cgamode, border, x >> 2, buffer32->line[self->cga.displine]); - } else - video_process_8(x, self->cga.displine); - - self->cga.sc = oldsc; - if (self->cga.vc == self->cga.crtc[7] && !self->cga.sc) - self->cga.cgastat |= 8; - self->cga.displine++; - if (self->cga.displine >= 500) - self->cga.displine = 0; - } else { - timer_advance_u64(&self->cga.timer, self->cga.dispontime); - self->cga.linepos = 0; - if (self->cga.vsynctime) { - self->cga.vsynctime--; - if (!self->cga.vsynctime) - self->cga.cgastat &= ~8; - } - - if (self->cga.sc == (self->cga.crtc[11] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[11] & 31) >> 1))) { - self->cga.con = 0; - self->cga.coff = 1; - } - if ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == (self->cga.crtc[9] >> 1)) - self->cga.maback = self->cga.ma; - if (self->cga.vadj) { - self->cga.sc++; - self->cga.sc &= 31; - self->cga.ma = self->cga.maback; - self->cga.vadj--; - if (!self->cga.vadj) { - self->cga.cgadispon = 1; - self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; - self->cga.sc = 0; - } - } else if (self->cga.sc == self->cga.crtc[9]) { - self->cga.maback = self->cga.ma; - self->cga.sc = 0; - oldvc = self->cga.vc; - self->cga.vc++; - self->cga.vc &= 127; - - if (self->cga.vc == self->cga.crtc[6]) - self->cga.cgadispon = 0; - - if (oldvc == self->cga.crtc[4]) { - self->cga.vc = 0; - self->cga.vadj = self->cga.crtc[5]; - - if (!self->cga.vadj) - self->cga.cgadispon = 1; - - if (!self->cga.vadj) - self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; - - if ((self->cga.crtc[10] & 0x60) == 0x20) - self->cga.cursoron = 0; - else - self->cga.cursoron = self->cga.cgablink & 8; - } - - if (self->cga.vc == self->cga.crtc[7]) { - self->cga.cgadispon = 0; - self->cga.displine = 0; - self->cga.vsynctime = 16; - - if (self->cga.crtc[7]) { - compaq_cga_log("Lastline %i Firstline %i %i\n", self->cga.lastline, - self->cga.firstline, self->cga.lastline - self->cga.firstline); - - if (self->cga.cgamode & 1) - x = (self->cga.crtc[1] << 3) + 16; - else - x = (self->cga.crtc[1] << 4) + 16; - - self->cga.lastline++; - - xs_temp = x; - ys_temp = (self->cga.lastline - self->cga.firstline); - - if ((xs_temp > 0) && (ys_temp > 0)) { - if (xs_temp < 64) - xs_temp = 656; - if (ys_temp < 32) - ys_temp = 400; - if (!enable_overscan) - xs_temp -= 16; - - if ((self->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 (video_force_resize_get()) - video_force_resize_set(0); - } - - if (enable_overscan) - video_blit_memtoscreen(0, self->cga.firstline - 8, xsize, (self->cga.lastline - self->cga.firstline) + 16); - else - video_blit_memtoscreen(8, self->cga.firstline, xsize, self->cga.lastline - self->cga.firstline); - } - - frames++; - - video_res_x = xsize; - if (enable_overscan) - xsize -= 16; - video_res_y = ysize; - if (self->cga.cgamode & 1) { - video_res_x /= 8; - video_res_y /= self->cga.crtc[9] + 1; - video_bpp = 0; - } else if (!(self->cga.cgamode & 2)) { - video_res_x /= 16; - video_res_y /= self->cga.crtc[9] + 1; - video_bpp = 0; - } else if (!(self->cga.cgamode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else - video_bpp = 1; - } - - self->cga.firstline = 1000; - self->cga.lastline = 0; - self->cga.cgablink++; - self->cga.oddeven ^= 1; - } - } else { - self->cga.sc++; - self->cga.sc &= 31; - self->cga.ma = self->cga.maback; - } - - if (self->cga.cgadispon) - self->cga.cgastat &= ~1; - - if (self->cga.sc == (self->cga.crtc[10] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[10] & 31) >> 1))) - self->cga.con = 1; - - if (self->cga.cgadispon && (self->cga.cgamode & 1)) { - for (x = 0; x < (self->cga.crtc[1] << 1); x++) - self->cga.charbuffer[x] = self->cga.vram[((self->cga.ma << 1) + x) & 0x3fff]; - } - } -} - -void * -compaq_cga_init(const device_t *info) -{ - int display_type; - compaq_cga_t *self = malloc(sizeof(compaq_cga_t)); - memset(self, 0, sizeof(compaq_cga_t)); - - display_type = device_get_config_int("display_type"); - self->cga.composite = (display_type != CGA_RGB); - self->cga.revision = device_get_config_int("composite_type"); - self->cga.snow_enabled = device_get_config_int("snow_enabled"); - - self->cga.vram = malloc(0x4000); - - cga_comp_init(self->cga.revision); - timer_add(&self->cga.timer, compaq_cga_poll, self, 1); - mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL /*self->cga.vram*/, MEM_MAPPING_EXTERNAL, self); - io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, self); - - if (info->local) { - for (uint16_t c = 0; c < 256; c++) { - mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16; - if (c & 8) - mdaattr[c][0][1] = 15 + 16; - else - mdaattr[c][0][1] = 7 + 16; - } - - mdaattr[0x70][0][1] = 16; - mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15; - mdaattr[0xF0][0][1] = 16; - mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15; - mdaattr[0x78][0][1] = 16 + 7; - mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15; - mdaattr[0xF8][0][1] = 16 + 7; - mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15; - mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16; - mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16; - mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16; - mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16; - } - - vflags = info->local; - - overscan_x = overscan_y = 16; - - self->cga.rgb_type = device_get_config_int("rgb_type"); - cga_palette = (self->cga.rgb_type << 1); - cgapal_rebuild(); - - self->cga.crtc[9] = 13; - - return self; -} - -void -compaq_cga_close(void *priv) -{ - compaq_cga_t *self = (compaq_cga_t *) priv; - - free(self->cga.vram); - free(self); -} - -void -compaq_cga_speed_changed(void *priv) -{ - compaq_cga_t *self = (compaq_cga_t *) priv; - - if (self->cga.crtc[9] == 13) /* Character height */ - compaq_cga_recalctimings(self); - else - cga_recalctimings(&self->cga); -} - -extern const device_config_t cga_config[]; - -const device_t compaq_cga_device = { - .name = "Compaq CGA", - .internal_name = "compaq_cga", - .flags = DEVICE_ISA, - .local = 0, - .init = compaq_cga_init, - .close = compaq_cga_close, - .reset = NULL, - .available = NULL, - .speed_changed = compaq_cga_speed_changed, - .force_redraw = NULL, - .config = cga_config -}; - -const device_t compaq_cga_2_device = { - .name = "Compaq CGA 2", - .internal_name = "compaq_cga_2", - .flags = DEVICE_ISA, - .local = 1, - .init = compaq_cga_init, - .close = compaq_cga_close, - .reset = NULL, - .available = NULL, - .speed_changed = compaq_cga_speed_changed, - .force_redraw = NULL, - .config = cga_config -}; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index b828239c0..26bb38991 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -47,7 +47,7 @@ void ega_doblit(int wx, int wy, ega_t *ega); static video_timings_t timing_ega = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; static uint8_t ega_rotate[8][256]; -static int active = 0; +static int active = 0; uint32_t pallook16[256]; uint32_t pallook64[256]; static int ega_type = EGA_TYPE_IBM; @@ -72,7 +72,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv) uint8_t gdcmask = (ega_type == EGA_SUPEREGA) ? 0xff : 0x0f; uint8_t crtcmask = (atype == EGA_SUPEREGA) ? 0xff : 0x1f; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) + if (((((addr & 0xfff0) == 0x3d0) || ((addr & 0xfff0) == 0x2d0)) || (((addr & 0xfff0) == 0x3b0) || ((addr & 0xfff0) == 0x2b0))) && !(ega->miscout & 1)) addr ^= 0x60; switch (addr) { @@ -94,7 +94,9 @@ ega_out(uint16_t addr, uint8_t val, void *priv) } break; + case 0x2c0: case 0x3c0: + case 0x2c1: case 0x3c1: if (atype == EGA_SUPEREGA) val &= 0x7f; /* Bit 7 indicates the flipflop status (read only) */ @@ -108,8 +110,9 @@ ega_out(uint16_t addr, uint8_t val, void *priv) } else { if ((ega->attraddr == 0x13) && (ega->attrregs[0x13] != val)) ega->fullchange = changeframecount; - o = ega->attrregs[ega->attraddr & 31]; - ega->attrregs[ega->attraddr & 31] = val; + uint8_t aidx = ega->attraddr & 31; + o = ega->attrregs[aidx]; + ega->attrregs[aidx] = val; if (ega->attraddr < 16) ega->fullchange = changeframecount; int is_attr14 = ega->chipset && (ega->attraddr == 0x14); @@ -139,6 +142,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv) } ega->attrff ^= 1; break; + case 0x2c2: case 0x3c2: o = ega->miscout; egaswitchread = (val & 0xc) >> 2; @@ -148,13 +152,21 @@ ega_out(uint16_t addr, uint8_t val, void *priv) ega->miscout = val; ega->overscan_color = ega->vres ? pallook16[ega->attrregs[0x11] & 0x0f] : pallook64[ega->attrregs[0x11] & 0x3f]; - 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); + + uint16_t base_addr = 0x03a0; +#ifdef EGA_ALT_ADDR_SUPPORT + if (ega->alt_addr == 1) + base_addr = 0x02a0; +#endif + if (ega->priv_parent == NULL) { + io_removehandler(base_addr, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + if (!(val & 1)) + io_sethandler(base_addr, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + } ega_recalctimings(ega); if ((type == EGA_TYPE_COMPAQ) && !(val & 0x02)) mem_mapping_disable(&ega->mapping); - else switch (ega->gdcreg[6] & 0xc) { + else switch (ega->gdcreg[6] & 0xc) { case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&ega->mapping, 0xa0000, 0x20000); break; @@ -172,9 +184,11 @@ ega_out(uint16_t addr, uint8_t val, void *priv) break; } break; + case 0x2c4: case 0x3c4: ega->seqaddr = val; break; + case 0x2c5: case 0x3c5: o = ega->seqregs[ega->seqaddr & 0xf]; ega->seqregs[ega->seqaddr & 0xf] = val; @@ -201,16 +215,20 @@ ega_out(uint16_t addr, uint8_t val, void *priv) break; } break; + case 0x2c6: case 0x3c6: if (type == EGA_TYPE_COMPAQ) ega->ctl_mode = val; break; + case 0x2ce: case 0x3ce: ega->gdcaddr = val; break; - case 0x3cf: - ega->gdcreg[ega->gdcaddr & gdcmask] = val; - switch (ega->gdcaddr & gdcmask) { + case 0x2cf: + case 0x3cf: { + uint8_t reg = ega->gdcaddr & gdcmask; + ega->gdcreg[reg] = val; + switch (reg) { case 2: ega->colourcompare = val; break; @@ -225,7 +243,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv) case 6: if ((type == EGA_TYPE_COMPAQ) && !(ega->miscout & 0x02)) mem_mapping_disable(&ega->mapping); - else switch (val & 0xc) { + else switch (val & 0xc) { case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&ega->mapping, 0xa0000, 0x20000); break; @@ -264,38 +282,40 @@ ega_out(uint16_t addr, uint8_t val, void *priv) break; } break; + } + case 0x2d0: case 0x3d0: + case 0x2d4: case 0x3d4: - if (ega->chipset) - ega->crtcreg = val & 0x3f; - else - ega->crtcreg = val; + ega->crtcreg = ega->chipset ? (val & 0x3f) : val; return; + case 0x2d1: case 0x3d1: + case 0x2d5: case 0x3d5: { int idx = ega->crtcreg; if (ega->chipset) { - if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80)) + if ((idx < 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80)) return; - if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80)) + if ((idx == 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80)) val = (ega->crtc[7] & ~0x10) | (val & 0x10); } else { idx &= crtcmask; - if ((idx >= 0x19) & (idx <= 0xf6)) + if ((idx >= 0x19) && (idx <= 0xf6)) return; if ((idx < 7) && (ega->crtc[0x11] & 0x80)) return; if ((idx == 7) && (ega->crtc[0x11] & 0x80)) val = (ega->crtc[7] & ~0x10) | (val & 0x10); } - old = ega->crtc[idx]; + old = ega->crtc[idx]; ega->crtc[idx] = val; if (old != val) { if ((idx < 0xe) || (idx > 0x10)) { if ((idx == 0xc) || (idx == 0xd)) { ega->fullchange = 3; - ega->ma_latch = ((ega->crtc[0xc] << 8) | ega->crtc[0xd]) + + ega->memaddr_latch = ((ega->crtc[0xc] << 8) | ega->crtc[0xd]) + ((ega->crtc[8] & 0x60) >> 5); } else { ega->fullchange = changeframecount; @@ -305,7 +325,9 @@ ega_out(uint16_t addr, uint8_t val, void *priv) } break; - } default: + } + + default: break; } } @@ -313,14 +335,14 @@ ega_out(uint16_t addr, uint8_t val, void *priv) uint8_t ega_in(uint16_t addr, void *priv) { - ega_t *ega = (ega_t *) priv; + ega_t *ega = (ega_t *) priv; uint8_t ret = 0xff; int type = ega_type; int atype = ega->actual_type; uint8_t gdcmask = (atype == EGA_SUPEREGA) ? 0xff : 0x0f; uint8_t crtcmask = (atype == EGA_SUPEREGA) ? 0xff : 0x1f; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) + if (((((addr & 0xfff0) == 0x3d0) || ((addr & 0xfff0) == 0x2d0)) || (((addr & 0xfff0) == 0x3b0) || ((addr & 0xfff0) == 0x2b0))) && !(ega->miscout & 1)) addr ^= 0x60; switch (addr) { @@ -341,7 +363,9 @@ ega_in(uint16_t addr, void *priv) } break; + case 0x2c0: case 0x3c0: + case 0x2c1: case 0x3c1: if (type == EGA_TYPE_OTHER) { int data = (atype == EGA_SUPEREGA) ? (ega->attrff & 1) : (addr & 1); @@ -354,9 +378,11 @@ ega_in(uint16_t addr, void *priv) ret = (ret & 0x3f) | (ega->attrff ? 0x80 : 0x00); } break; + case 0x2c2: case 0x3c2: ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00; break; + case 0x2c4: case 0x3c4: if (type == EGA_TYPE_OTHER) { if (atype == EGA_SUPEREGA) @@ -365,28 +391,34 @@ ega_in(uint16_t addr, void *priv) ret = ega->seqaddr; } break; + case 0x2c5: case 0x3c5: if (type == EGA_TYPE_OTHER) { - if ((ega->seqaddr & 0x0f) > 0x04) - ret = ega->chipset ? ega->seqregs[ega->seqaddr & 0xf] : 0xff; + uint8_t idx = ega->seqaddr & 0xf; + if (idx > 0x04) + ret = ega->chipset ? ega->seqregs[idx] : 0xff; else - ret = ega->seqregs[ega->seqaddr & 0xf]; + ret = ega->seqregs[idx]; } break; + case 0x2c6: case 0x3c6: if (type == EGA_TYPE_COMPAQ) ret = ega->ctl_mode; break; + case 0x2c8: case 0x3c8: if (type == EGA_TYPE_OTHER) ret = 2; break; + case 0x2cc: case 0x3cc: if (type == EGA_TYPE_OTHER) ret = ega->miscout; break; + case 0x2ce: case 0x3ce: - if (ega_type == EGA_TYPE_OTHER) { + if (type == EGA_TYPE_OTHER) { ret = ega->gdcaddr; if (atype == EGA_SUPEREGA) { ret = (ret & 0x0f) | 0xe0; @@ -395,14 +427,16 @@ ega_in(uint16_t addr, void *priv) } } break; + case 0x2cf: case 0x3cf: if (type == EGA_TYPE_OTHER) { - switch (ega->gdcaddr & gdcmask) { + uint8_t gidx = ega->gdcaddr & gdcmask; + switch (gidx) { default: - ret = ega->gdcreg[ega->gdcaddr & gdcmask]; + ret = ega->gdcreg[gidx]; break; case 0x09 ... 0xf7: - ret = ega->chipset ? ega->gdcreg[ega->gdcaddr & gdcmask] : 0xff; + ret = ega->chipset ? ega->gdcreg[gidx] : 0xff; break; case 0xf8: ret = ega->la; @@ -419,9 +453,11 @@ ega_in(uint16_t addr, void *priv) } } break; + case 0x2d0: case 0x3d0: + case 0x2d4: case 0x3d4: - if (ega_type == EGA_TYPE_OTHER) { + if (type == EGA_TYPE_OTHER) { ret = ega->crtcreg; if (atype == EGA_SUPEREGA) { ret = (ret & 0x1f) | 0xc0; @@ -430,7 +466,9 @@ ega_in(uint16_t addr, void *priv) } } break; + case 0x2d1: case 0x3d1: + case 0x2d5: case 0x3d5: switch (ega->crtcreg & crtcmask) { case 0xc: @@ -465,10 +503,11 @@ ega_in(uint16_t addr, void *priv) break; } break; + case 0x2da: case 0x3da: ega->attrff = 0; if (type == EGA_TYPE_COMPAQ) { - ret = ega->stat & 0xcf; + ret = ega->status & 0xcf; switch ((ega->attrregs[0x12] >> 4) & 0x03) { case 0x00: /* 00 = Pri. Red (5), Pri. Blue (4) */ @@ -489,12 +528,12 @@ ega_in(uint16_t addr, void *priv) break; } } else { - ega->stat ^= 0x30; /* Fools IBM EGA video BIOS self-test. */ - ret = ega->stat; + ega->status ^= 0x30; /* Fools IBM EGA video BIOS self-test. */ + ret = ega->status; } break; case 0x7c6: - ret = 0xfd; /* EGA mode supported. */ + ret = 0xfd; /* EGA mode supported. */ break; case 0xbc6: /* 0000 = None; @@ -525,6 +564,7 @@ ega_recalctimings(ega_t *ega) double _dispofftime; double disptime; double crtcconst; + double mdiv = (ega->seqregs[1] & 1) ? 8.0 : 9.0; ega->vtotal = ega->crtc[6]; ega->dispend = ega->crtc[0x12]; @@ -578,10 +618,7 @@ ega_recalctimings(ega_t *ega) else crtcconst = (cpuclock / 16872000.0 * (double) (1ULL << 32)); } - if (!(ega->seqregs[1] & 1)) - crtcconst *= 9.0; - else - crtcconst *= 8.0; + crtcconst *= mdiv; } else if (ega->eeprom) { clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0); @@ -603,24 +640,18 @@ ega_recalctimings(ega_t *ega) crtcconst = (cpuclock / 36000000.0 * (double) (1ULL << 32)); break; } - if (!(ega->seqregs[1] & 1)) - crtcconst *= 9.0; - else - crtcconst *= 8.0; + crtcconst *= mdiv; } else { if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); 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->dot_clock = crtcconst / mdiv; ega->interlace = 0; - ega->ma_latch = (ega->crtc[0xc] << 8) | ega->crtc[0xd]; + ega->memaddr_latch = (ega->crtc[0xc] << 8) | ega->crtc[0xd]; ega->render = ega_render_blank; if (!ega->scrblank && ega->attr_palette_enable) { @@ -629,17 +660,16 @@ 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->hdisp_old = ega->hdisp; + ega->render = ega_render_text; } else { ega->hdisp *= (ega->seqregs[1] & 8) ? 16 : 8; - ega->render = ega_render_graphics; - ega->hdisp_old = ega->hdisp; + ega->render = ega_render_graphics; } + ega->hdisp_old = ega->hdisp; } if (ega->chipset) { - if (ega->hdisp > 640) { + if (ega->hdisp >= 800) { ega->dispend <<= 1; ega->vtotal <<= 1; ega->split <<= 1; @@ -696,7 +726,7 @@ ega_recalctimings(ega_t *ega) timer_disable(&ega->dot_timer); timer_set_delay_u64(&ega->dot_timer, ega->dot_time); ega->cca = 0; - active = 1; + active = 1; ega->dot = 0; } @@ -708,30 +738,30 @@ ega_recalctimings(ega_t *ega) 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 = 0; - static int bg = 0; - static uint32_t dat = 0x00000000; - static int cclock = 0; - static int disptime; - static int _dispontime; - static int _dispofftime; + 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->scanline == (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 = 0; + static int bg = 0; + static uint32_t dat = 0x00000000; + static int cclock = 0; + static int disptime; + static int _dispontime; + static int _dispofftime; if (ega->seqregs[1] & 8) { disptime = ((ega->crtc[0] + 2) << 1); @@ -764,7 +794,7 @@ ega_dot_poll(void *priv) else charaddr = ega->charseta + (chr * 0x80); - dat = ega->vram[charaddr + (ega->sc << 2)]; + dat = ega->vram[charaddr + (ega->scanline << 2)]; dat <<= 1; if ((chr & ~0x1F) == 0xC0 && attrlinechars) dat |= (dat >> 1) & 1; @@ -803,30 +833,28 @@ void ega_poll(void *priv) { ega_t *ega = (ega_t *) priv; - int x, y; int old_ma; int wx = 640; int wy = 350; - uint32_t blink_delay; if (!ega->linepos) { timer_advance_u64(&ega->timer, ega->dispofftime); - ega->stat |= 1; + ega->status |= 1; ega->linepos = 1; if (ega->dispon) { ega->hdisp_on = 1; - ega->ma &= ega->vrammask; + ega->memaddr &= ega->vrammask; if (ega->firstline == 2000) { ega->firstline = ega->displine; video_wait_for_buffer(); } - old_ma = ega->ma; + old_ma = ega->memaddr; ega->displine *= ega->vres + 1; ega->y_add *= ega->vres + 1; - for (y = 0; y <= ega->vres; y++) { + for (int y = 0; y <= ega->vres; y++) { /* Render scanline */ ega->render(ega); @@ -837,7 +865,7 @@ ega_poll(void *priv) ega->x_add = (overscan_x >> 1) - ega->scrollcache; if (y != ega->vres) { - ega->ma = old_ma; + ega->memaddr = old_ma; ega->displine++; } } @@ -851,11 +879,11 @@ ega_poll(void *priv) ega->displine++; if (ega->interlace) ega->displine++; - if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines) - ega->stat &= ~8; + if ((ega->status & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines) + ega->status &= ~8; ega->vslines++; if (ega->chipset) { - if (ega->hdisp > 640) { + if (ega->hdisp >= 800) { if (ega->displine > 2000) ega->displine = 0; } else { @@ -870,35 +898,35 @@ ega_poll(void *priv) timer_advance_u64(&ega->timer, ega->dispontime); if (ega->dispon) - ega->stat &= ~1; + ega->status &= ~1; ega->hdisp_on = 0; ega->linepos = 0; - if ((ega->sc == (ega->crtc[11] & 31)) || (ega->sc == ega->rowcount)) - ega->con = 0; + if ((ega->scanline == (ega->crtc[11] & 31)) || (ega->scanline == ega->rowcount)) + ega->cursorvisible = 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; + ega->memaddr = ega->memaddr_backup; + ega->cca = ega->memaddr_backup; } - if (ega->sc == (ega->crtc[9] & 31)) { + if (ega->scanline == (ega->crtc[9] & 31)) { ega->linecountff = 0; - ega->sc = 0; + ega->scanline = 0; - ega->maback += (ega->rowoffset << 3); + ega->memaddr_backup += (ega->rowoffset << 3); if (ega->interlace) - ega->maback += (ega->rowoffset << 3); - ega->maback &= ega->vrammask; - ega->ma = ega->maback; - ega->cca = ega->maback; + ega->memaddr_backup += (ega->rowoffset << 3); + ega->memaddr_backup &= ega->vrammask; + ega->memaddr = ega->memaddr_backup; + ega->cca = ega->memaddr_backup; } else { ega->linecountff = 0; - ega->sc++; - ega->sc &= 31; - ega->ma = ega->maback; - ega->cca = ega->maback; + ega->scanline++; + ega->scanline &= 31; + ega->memaddr = ega->memaddr_backup; + ega->cca = ega->memaddr_backup; } } ega->real_vc++; @@ -906,7 +934,7 @@ ega_poll(void *priv) !(ega->real_vc & 1)) ega->vc++; if (ega->chipset) { - if (ega->hdisp > 640) + if (ega->hdisp >= 800) ega->vc &= 1023; else ega->vc &= 511; @@ -915,17 +943,17 @@ ega_poll(void *priv) 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) - ega->ma = ega->maback = ega->rowoffset << 1; + ega->memaddr = ega->memaddr_backup = ega->rowoffset << 1; else - ega->ma = ega->maback = 0; - ega->ma <<= 2; - ega->cca = ega->ma; - ega->maback <<= 2; - ega->sc = 0; + ega->memaddr = ega->memaddr_backup = 0; + ega->memaddr <<= 2; + ega->cca = ega->memaddr; + ega->memaddr_backup <<= 2; + ega->scanline = 0; } if (ega->vc == ega->dispend) { ega->dispon = 0; - blink_delay = (ega->crtc[11] & 0x60) >> 5; + uint32_t blink_delay = (ega->crtc[11] & 0x60) >> 5; if (ega->crtc[10] & 0x20) ega->cursoron = 0; else if (blink_delay == 2) @@ -942,18 +970,18 @@ ega_poll(void *priv) } if (ega->vc == ega->vsyncstart) { ega->dispon = 0; - ega->stat |= 8; + ega->status |= 8; #if 0 picint(1 << 2); #endif - x = ega->hdisp; +// x = ega->hdisp; if (ega->interlace && !ega->oddeven) ega->lastline++; if (ega->interlace && ega->oddeven) ega->firstline--; - wx = x; + wx = ega->hdisp; if (ega->vres) { wy = (ega->lastline - ega->firstline) << 1; @@ -981,19 +1009,19 @@ ega_poll(void *priv) ega->vslines = 0; if (ega->interlace && ega->oddeven) - ega->ma = ega->maback = ega->ma_latch + (ega->rowoffset << 1); + ega->memaddr = ega->memaddr_backup = ega->memaddr_latch + (ega->rowoffset << 1); else - ega->ma = ega->maback = ega->ma_latch; - ega->ca = (ega->crtc[0xe] << 8) | ega->crtc[0xf]; + ega->memaddr = ega->memaddr_backup = ega->memaddr_latch; + ega->cursoraddr = (ega->crtc[0xe] << 8) | ega->crtc[0xf]; - ega->ma <<= 2; - ega->maback <<= 2; - ega->ca <<= 2; - ega->cca = ega->ma; + ega->memaddr <<= 2; + ega->memaddr_backup <<= 2; + ega->cursoraddr <<= 2; + ega->cca = ega->memaddr; } if (ega->vc == ega->vtotal) { ega->vc = 0; - ega->sc = (ega->crtc[0x8] & 0x1f); + ega->scanline = (ega->crtc[0x8] & 0x1f); ega->dispon = 1; ega->displine = (ega->interlace && ega->oddeven) ? 1 : 0; @@ -1010,8 +1038,8 @@ ega_poll(void *priv) ega->linecountff = 0; } - if (ega->sc == (ega->crtc[10] & 31)) - ega->con = 1; + if (ega->scanline == (ega->crtc[10] & 31)) + ega->cursorvisible = 1; } } @@ -1024,9 +1052,6 @@ ega_doblit(int wx, int wy, ega_t *ega) int y_start = enable_overscan ? 0 : (unscaled_overscan_y >> 1); int x_start = enable_overscan ? 0 : (overscan_x >> 1); int bottom = (unscaled_overscan_y >> 1); - uint32_t *p; - int i; - int j; int xs_temp; int ys_temp; @@ -1073,17 +1098,17 @@ ega_doblit(int wx, int wy, ega_t *ega) if ((wx >= 160) && ((wy + 1) >= 120)) { /* Draw (overscan_size - scroll size) lines of overscan on top and bottom. */ - for (i = 0; i < ega->y_add; i++) { - p = &buffer32->line[i & 0x7ff][0]; + for (int i = 0; i < ega->y_add; i++) { + uint32_t *p = &buffer32->line[i & 0x7ff][0]; - for (j = 0; j < (xsize + x_add); j++) + for (int j = 0; j < (xsize + x_add); j++) p[j] = ega->overscan_color; } - for (i = 0; i < bottom; i++) { - p = &buffer32->line[(ysize + ega->y_add + i) & 0x7ff][0]; + for (int i = 0; i < bottom; i++) { + uint32_t *p = &buffer32->line[(ysize + ega->y_add + i) & 0x7ff][0]; - for (j = 0; j < (xsize + x_add); j++) + for (int j = 0; j < (xsize + x_add); j++) p[j] = ega->overscan_color; } } @@ -1107,12 +1132,11 @@ ega_remap_cpu_addr(uint32_t inaddr, ega_t *ega) // bit 2: 1 = 128K mapping, 0 = other mapping (from memory decode PROM) a0mux = 0; - if (ega->gdcreg[6] & 2) { + if (ega->gdcreg[6] & 2) a0mux |= 2; - } - if (ega->vram_limit <= 64 * 1024) { + + if (ega->vram_limit <= 64 * 1024) a0mux |= 1; - } switch (ega->gdcreg[6] & 0xC) { case 0x0: // 128K A000 @@ -1179,9 +1203,8 @@ ega_write(uint32_t addr, uint8_t val, void *priv) cycles -= video_timing_write_b; - if (ega->chain2_write) { + if (ega->chain2_write) writemask2 &= 0x5 << (addr & 1); - } addr = ega_remap_cpu_addr(addr, ega); @@ -1361,9 +1384,8 @@ ega_read(uint32_t addr, void *priv) cycles -= video_timing_read_b; - if (ega->chain2_read) { + if (ega->chain2_read) readplane = (readplane & 2) | (addr & 1); - } addr = ega_remap_cpu_addr(addr, ega); @@ -1401,23 +1423,19 @@ ega_read(uint32_t addr, void *priv) void ega_init(ega_t *ega, int monitor_type, int is_mono) { - int c; - int d; - int e; - ega->vram = malloc(0x40000); ega->vrammask = 0x3ffff; - for (c = 0; c < 256; c++) { - e = c; - for (d = 0; d < 8; d++) { + for (uint16_t c = 0; c < 256; c++) { + int e = c; + for (uint8_t d = 0; d < 8; d++) { ega_rotate[d][c] = e; e = (e >> 1) | ((e & 1) ? 0x80 : 0); } } if (is_mono) { - for (c = 0; c < 256; c++) { + for (uint16_t c = 0; c < 256; c++) { if (((c >> 3) & 3) == 0) pallook64[c] = pallook16[c] = makecol32(0, 0, 0); else @@ -1474,9 +1492,14 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) } } - io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + uint16_t base_addr = 0x03a0; +#ifdef EGA_ALT_ADDR_SUPPORT + if (ega->alt_addr == 1) + base_addr = 0x02a0; +#endif + io_sethandler(base_addr, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); } else { - for (c = 0; c < 256; c++) { + for (uint16_t c = 0; c < 256; c++) { pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); pallook64[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); pallook16[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); @@ -1491,24 +1514,24 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) ega->pallook = pallook16; for (uint16_t c = 0; c < 256; c++) { - ega->mdacols[c][0][0] = ega->mdacols[c][1][0] = ega->mdacols[c][1][1] = 16; + ega->mda_attr_to_color_table[c][0][0] = ega->mda_attr_to_color_table[c][1][0] = ega->mda_attr_to_color_table[c][1][1] = 16; if (c & 8) - ega->mdacols[c][0][1] = 15 + 16; + ega->mda_attr_to_color_table[c][0][1] = 15 + 16; else - ega->mdacols[c][0][1] = 7 + 16; + ega->mda_attr_to_color_table[c][0][1] = 7 + 16; } - ega->mdacols[0x70][0][1] = 16; - ega->mdacols[0x70][0][0] = ega->mdacols[0x70][1][0] = ega->mdacols[0x70][1][1] = 16 + 15; - ega->mdacols[0xF0][0][1] = 16; - ega->mdacols[0xF0][0][0] = ega->mdacols[0xF0][1][0] = ega->mdacols[0xF0][1][1] = 16 + 15; - ega->mdacols[0x78][0][1] = 16 + 7; - ega->mdacols[0x78][0][0] = ega->mdacols[0x78][1][0] = ega->mdacols[0x78][1][1] = 16 + 15; - ega->mdacols[0xF8][0][1] = 16 + 7; - ega->mdacols[0xF8][0][0] = ega->mdacols[0xF8][1][0] = ega->mdacols[0xF8][1][1] = 16 + 15; - ega->mdacols[0x00][0][1] = ega->mdacols[0x00][1][1] = 16; - ega->mdacols[0x08][0][1] = ega->mdacols[0x08][1][1] = 16; - ega->mdacols[0x80][0][1] = ega->mdacols[0x80][1][1] = 16; - ega->mdacols[0x88][0][1] = ega->mdacols[0x88][1][1] = 16; + ega->mda_attr_to_color_table[0x70][0][1] = 16; + ega->mda_attr_to_color_table[0x70][0][0] = ega->mda_attr_to_color_table[0x70][1][0] = ega->mda_attr_to_color_table[0x70][1][1] = 16 + 15; + ega->mda_attr_to_color_table[0xF0][0][1] = 16; + ega->mda_attr_to_color_table[0xF0][0][0] = ega->mda_attr_to_color_table[0xF0][1][0] = ega->mda_attr_to_color_table[0xF0][1][1] = 16 + 15; + ega->mda_attr_to_color_table[0x78][0][1] = 16 + 7; + ega->mda_attr_to_color_table[0x78][0][0] = ega->mda_attr_to_color_table[0x78][1][0] = ega->mda_attr_to_color_table[0x78][1][1] = 16 + 15; + ega->mda_attr_to_color_table[0xF8][0][1] = 16 + 7; + ega->mda_attr_to_color_table[0xF8][0][0] = ega->mda_attr_to_color_table[0xF8][1][0] = ega->mda_attr_to_color_table[0xF8][1][1] = 16 + 15; + ega->mda_attr_to_color_table[0x00][0][1] = ega->mda_attr_to_color_table[0x00][1][1] = 16; + ega->mda_attr_to_color_table[0x08][0][1] = ega->mda_attr_to_color_table[0x08][1][1] = 16; + ega->mda_attr_to_color_table[0x80][0][1] = ega->mda_attr_to_color_table[0x80][1][1] = 16; + ega->mda_attr_to_color_table[0x88][0][1] = ega->mda_attr_to_color_table[0x88][1][1] = 16; egaswitches = monitor_type & 0xf; @@ -1562,11 +1585,9 @@ ega_set_type(void *priv, uint32_t local) static void * ega_standalone_init(const device_t *info) { - ega_t *ega = malloc(sizeof(ega_t)); + ega_t *ega = calloc(1, sizeof(ega_t)); int monitor_type; - memset(ega, 0x00, sizeof(ega_t)); - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ega); overscan_x = 16; @@ -1622,7 +1643,7 @@ ega_standalone_init(const device_t *info) } } - monitor_type = device_get_config_int("monitor_type"); + monitor_type = ega->chipset ? 0x09 : device_get_config_int("monitor_type"); ega_init(ega, monitor_type, (monitor_type & 0x0F) == 0x0B); ega->vram_limit = device_get_config_int("memory") * 1024; @@ -1631,12 +1652,19 @@ 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); if (ega_type == EGA_TYPE_COMPAQ) mem_mapping_disable(&ega->mapping); - io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + uint16_t addr = 0x03c0; +#ifdef EGA_ALT_ADDR_SUPPORT + if (ega_type == EGA_TYPE_IBM) { + addr = device_get_config_hex16("base"); + if (addr == 0x02c0) + ega->alt_addr = 1; + } +#endif + io_sethandler(addr, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); 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)); + ega->eeprom = calloc(1, sizeof(ati_eeprom_t)); 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); @@ -1712,6 +1740,66 @@ ega_speed_changed(void *priv) 0 = Switch closed (ON); 1 = Switch open (OFF). */ +static const device_config_t ega_ibm_config[] = { + // clang-format off + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 256, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "32 KB", .value = 32 }, + { .description = "64 KB", .value = 64 }, + { .description = "128 KB", .value = 128 }, + { .description = "256 KB", .value = 256 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "monitor_type", + .description = "Monitor type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 9, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Monochrome (5151/MDA) (white)", .value = 0x0B | (DISPLAY_WHITE << 4) }, + { .description = "Monochrome (5151/MDA) (green)", .value = 0x0B | (DISPLAY_GREEN << 4) }, + { .description = "Monochrome (5151/MDA) (amber)", .value = 0x0B | (DISPLAY_AMBER << 4) }, + { .description = "Color 40x25 (5153/CGA)", .value = 0x06 }, + { .description = "Color 80x25 (5153/CGA)", .value = 0x07 }, + { .description = "Enhanced Color - Normal Mode (5154/ECD)", .value = 0x08 }, + { .description = "Enhanced Color - Enhanced Mode (5154/ECD)", .value = 0x09 }, + { .description = "" } + }, + .bios = { { 0 } } + }, +#ifdef EGA_ALT_ADDR_SUPPORT + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x03c0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x3C0", .value = 0x03c0 }, + { .description = "0x2C0", .value = 0x02c0 }, + { .description = "" } + }, + .bios = { { 0 } } + }, +#endif + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + static const device_config_t ega_config[] = { // clang-format off { @@ -1755,6 +1843,29 @@ static const device_config_t ega_config[] = { // clang-format on }; +static const device_config_t atiega800p_config[] = { + // clang-format off + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 256, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "32 KB", .value = 32 }, + { .description = "64 KB", .value = 64 }, + { .description = "128 KB", .value = 128 }, + { .description = "256 KB", .value = 256 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + const device_t ega_device = { .name = "IBM EGA", .internal_name = "ega", @@ -1766,7 +1877,7 @@ const device_t ega_device = { .available = ega_standalone_available, .speed_changed = ega_speed_changed, .force_redraw = NULL, - .config = ega_config + .config = ega_ibm_config }; const device_t cpqega_device = { @@ -1784,7 +1895,7 @@ const device_t cpqega_device = { }; const device_t sega_device = { - .name = "SuperEGA", + .name = "Chips & Technologies SuperEGA", .internal_name = "superega", .flags = DEVICE_ISA, .local = EGA_SUPEREGA, @@ -1808,7 +1919,7 @@ const device_t atiega800p_device = { .available = atiega800p_standalone_available, .speed_changed = ega_speed_changed, .force_redraw = NULL, - .config = ega_config + .config = atiega800p_config }; const device_t iskra_ega_device = { diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index 8a73ffbbb..c1c44dfdb 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -141,9 +141,9 @@ ega_render_text(ega_t *ega) } for (int x = 0; x < (ega->hdisp + ega->scrollcache); x += charwidth) { - uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask; + uint32_t addr = ega->remap_func(ega, ega->memaddr) & ega->vrammask; - int drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); + int drawcursor = ((ega->memaddr == ega->cursoraddr) && ega->cursorvisible && ega->cursoron); uint32_t chr; uint32_t attr; @@ -175,7 +175,7 @@ ega_render_text(ega_t *ega) } } - uint32_t dat = ega->vram[charaddr + (ega->sc << 2)]; + uint32_t dat = ega->vram[charaddr + (ega->scanline << 2)]; dat <<= 1; if (((chr & ~0x1f) == 0xc0) && attrlinechars) dat |= (dat >> 1) & 1; @@ -184,21 +184,21 @@ ega_render_text(ega_t *ega) if (monoattrs) { int bit = (dat & (0x100 >> (xx >> dwshift))) ? 1 : 0; int blink = (!drawcursor && (attr & 0x80) && attrblink && blinked); - if ((ega->sc == ega->crtc[0x14]) && ((attr & 7) == 1)) - p[xx] = ega->mdacols[attr][blink][1]; + if ((ega->scanline == ega->crtc[0x14]) && ((attr & 7) == 1)) + p[xx] = ega->mda_attr_to_color_table[attr][blink][1]; else - p[xx] = ega->mdacols[attr][blink][bit]; + p[xx] = ega->mda_attr_to_color_table[attr][blink][bit]; if (drawcursor) - p[xx] ^= ega->mdacols[attr][0][1]; + p[xx] ^= ega->mda_attr_to_color_table[attr][0][1]; p[xx] = ega->pallook[ega->egapal[p[xx] & 0x0f]]; } else p[xx] = (dat & (0x100 >> (xx >> dwshift))) ? fg : bg; } - ega->ma += 4; + ega->memaddr += 4; p += charwidth; } - ega->ma &= 0x3ffff; + ega->memaddr &= 0x3ffff; } } @@ -236,7 +236,7 @@ ega_render_graphics(ega_t *ega) } for (int x = 0; x <= (ega->hdisp + ega->scrollcache); x += charwidth) { - uint32_t addr = ega->remap_func(ega, ega->ma) & ega->vrammask; + uint32_t addr = ega->remap_func(ega, ega->memaddr) & ega->vrammask; uint8_t edat[4]; if (seqoddeven) { @@ -247,12 +247,12 @@ ega_render_graphics(ega_t *ega) edat[3] = ega->vram[(addr | 3) ^ secondcclk]; secondcclk = (secondcclk + 1) & 1; if (secondcclk == 0) - ega->ma += 4; + ega->memaddr += 4; } else { *(uint32_t *) (&edat[0]) = *(uint32_t *) (&ega->vram[addr]); - ega->ma += 4; + ega->memaddr += 4; } - ega->ma &= 0x3ffff; + ega->memaddr &= 0x3ffff; if (cga2bpp) { // Remap CGA 2bpp-chunky data into fully planar data diff --git a/src/video/vid_et3000.c b/src/video/vid_et3000.c index 193fed3c7..a75a63829 100644 --- a/src/video/vid_et3000.c +++ b/src/video/vid_et3000.c @@ -424,7 +424,7 @@ et3000_out(uint16_t addr, uint8_t val, void *priv) static void et3000_recalctimings(svga_t *svga) { - svga->ma_latch |= (svga->crtc[0x23] & 2) << 15; + svga->memaddr_latch |= (svga->crtc[0x23] & 2) << 15; if (svga->crtc[0x25] & 1) svga->vblankstart |= 0x400; if (svga->crtc[0x25] & 2) @@ -439,7 +439,7 @@ et3000_recalctimings(svga_t *svga) svga->interlace = !!(svga->crtc[0x25] & 0x80); if (svga->attrregs[0x16] & 0x10) { - svga->ma_latch <<= (1 << 0); + svga->memaddr_latch <<= (1 << 0); svga->rowoffset <<= (1 << 0); switch (svga->gdcreg[5] & 0x60) { case 0x00: @@ -476,6 +476,20 @@ et3000_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / 36000000.0; break; } + + if (svga->render == svga_render_4bpp_highres) + svga->render = svga_render_4bpp_tseng_highres; +} + +static int +et3000_line_compare(svga_t* svga) +{ + if (svga->split > svga->vsyncstart) { + /* Don't do line compare if we're already in vertical retrace. */ + /* This makes picture bouncing effect work on Copper demo. */ + return 0; + } + return 1; } static void * @@ -511,6 +525,7 @@ et3000_init(const device_t *info) dev->svga.miscout = 1; dev->svga.packed_chain4 = 1; + dev->svga.line_compare = et3000_line_compare; return dev; } diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 064d79230..b19aad20a 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -378,7 +378,7 @@ et4000_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -642,7 +642,7 @@ et4000_recalctimings(svga_t *svga) { const et4000_t *dev = (et4000_t *) svga->priv; - svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; + svga->memaddr_latch |= (svga->crtc[0x33] & 3) << 16; svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; @@ -701,7 +701,7 @@ et4000_recalctimings(svga_t *svga) if (dev->type == ET4000_TYPE_KOREAN || dev->type == ET4000_TYPE_TRIGEM || dev->type == ET4000_TYPE_KASAN) { if ((svga->render == svga_render_text_80) && ((svga->crtc[0x37] & 0x0A) == 0x0A)) { if (dev->port_32cb_val & 0x80) { - svga->ma_latch -= 2; + svga->memaddr_latch -= 2; svga->ca_adj = -2; } if ((dev->port_32cb_val & 0xB4) == ((svga->crtc[0x37] & 3) == 2 ? 0xB4 : 0xB0)) { @@ -719,10 +719,21 @@ et4000_recalctimings(svga_t *svga) } if ((svga->seqregs[0x0e] & 0x02) && ((svga->gdcreg[5] & 0x60) >= 0x40) && svga->lowres) { - svga->ma_latch <<= 1; + svga->memaddr_latch <<= 1; svga->rowoffset <<= 1; svga->render = svga_render_8bpp_highres; } + + if (svga->render == svga_render_4bpp_highres) + svga->render = svga_render_4bpp_tseng_highres; + + if (dev->type == ET4000_TYPE_TC6058AF) { + if (svga->render == svga_render_8bpp_lowres) + svga->render = svga_render_8bpp_tseng_lowres; + + else if (svga->render == svga_render_8bpp_highres) + svga->render = svga_render_8bpp_tseng_highres; + } } static void @@ -734,7 +745,7 @@ et4000_kasan_recalctimings(svga_t *svga) if (svga->render == svga_render_text_80 && (et4000->kasan_cfg_regs[0] & 8)) { svga->hdisp += svga->dots_per_clock; - svga->ma_latch -= 4; + svga->memaddr_latch -= 4; svga->ca_adj = (et4000->kasan_cfg_regs[0] >> 6) - 3; svga->ksc5601_sbyte_mask = (et4000->kasan_cfg_regs[0] & 4) << 5; if ((et4000->kasan_cfg_regs[0] & 0x23) == 0x20 && (et4000->kasan_cfg_regs[4] & 0x80) && ((svga->crtc[0x37] & 0x0B) == 0x0A)) @@ -773,6 +784,17 @@ et4000_mca_feedb(UNUSED(void *priv)) return et4000->pos_regs[2] & 1; } +static int +et4000_line_compare(svga_t* svga) +{ + if (svga->split > svga->vsyncstart) { + /* Don't do line compare if we're already in vertical retrace. */ + /* This makes picture bouncing effect work on Copper demo. */ + return 0; + } + return 1; +} + static void * et4000_init(const device_t *info) { @@ -881,8 +903,13 @@ et4000_init(const device_t *info) if (dev->type >= ET4000_TYPE_ISA) dev->svga.ramdac = device_add(&sc1502x_ramdac_device); + if (dev->type == ET4000_TYPE_TC6058AF) + dev->svga.adv_flags |= FLAG_PRECISETIME; + dev->vram_mask = dev->vram_size - 1; + dev->svga.line_compare = et4000_line_compare; + rom_init(&dev->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -942,22 +969,6 @@ et4000_kasan_available(void) static const device_config_t et4000_tc6058af_config[] = { // clang-format off - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 512, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "256 KB", .value = 256 }, - { .description = "512 KB", .value = 512 }, - { .description = "1 MB", .value = 1024 }, - { .description = "" } - }, - .bios = { { 0 } } - }, { .name = "bios_ver", .description = "BIOS Revision", @@ -989,18 +1000,12 @@ static const device_config_t et4000_tc6058af_config[] = { { .files_no = 0 } } }, - { .name = "", .description = "", .type = CONFIG_END } -// clang-format on -}; - -static const device_config_t et4000_bios_config[] = { - // clang-format off { .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, .default_string = NULL, - .default_int = 1024, + .default_int = 512, .file_filter = NULL, .spinner = { 0 }, .selection = { @@ -1011,6 +1016,12 @@ static const device_config_t et4000_bios_config[] = { }, .bios = { { 0 } } }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format on +}; + +static const device_config_t et4000_bios_config[] = { + // clang-format off { .name = "bios_ver", .description = "BIOS Revision", @@ -1042,6 +1053,22 @@ static const device_config_t et4000_bios_config[] = { { .files_no = 0 } } }, + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1024, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "256 KB", .value = 256 }, + { .description = "512 KB", .value = 512 }, + { .description = "1 MB", .value = 1024 }, + { .description = "" } + }, + .bios = { { 0 } } + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 246decb9c..2e9a7796a 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -238,7 +238,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -430,7 +430,7 @@ et4000w32p_recalctimings(svga_t *svga) { et4000w32p_t *et4000 = (et4000w32p_t *) svga->priv; - svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; + svga->memaddr_latch |= (svga->crtc[0x33] & 0x7) << 16; svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; @@ -600,6 +600,9 @@ et4000w32p_recalctimings(svga_t *svga) } } } + + if (svga->render == svga_render_4bpp_highres) + svga->render = svga_render_4bpp_tseng_highres; } void diff --git a/src/video/vid_f82c425.c b/src/video/vid_f82c425.c index c607cda14..078e0f3df 100644 --- a/src/video/vid_f82c425.c +++ b/src/video/vid_f82c425.c @@ -361,28 +361,28 @@ f82c425_text_row(f82c425_t *f82c425) int cursorline; int blink; uint16_t addr; - uint8_t sc; - uint16_t ma = (f82c425->cga.crtc[0x0d] | (f82c425->cga.crtc[0x0c] << 8)) & 0x3fff; - uint16_t ca = (f82c425->cga.crtc[0x0f] | (f82c425->cga.crtc[0x0e] << 8)) & 0x3fff; - uint8_t sl = f82c425->cga.crtc[9] + 1; - int columns = f82c425->cga.crtc[1]; + uint8_t scanline; + uint16_t memaddr = (f82c425->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (f82c425->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + uint16_t cursoraddr = (f82c425->cga.crtc[0x0f] | (f82c425->cga.crtc[0x0e] << 8)) & 0x3fff; + uint8_t sl = f82c425->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1; + int columns = f82c425->cga.crtc[CGA_CRTC_HDISP]; - sc = (f82c425->displine) & 7; - addr = ((ma & ~1) + (f82c425->displine >> 3) * columns) * 2; - ma += (f82c425->displine >> 3) * columns; + scanline = (f82c425->displine) & 7; + addr = ((memaddr & ~1) + (f82c425->displine >> 3) * columns) * 2; + memaddr += (f82c425->displine >> 3) * columns; - if ((f82c425->cga.crtc[0x0a] & 0x60) == 0x20) { + if ((f82c425->cga.crtc[CGA_CRTC_CURSOR_START] & 0x60) == 0x20) { cursorline = 0; } else { - cursorline = ((f82c425->cga.crtc[0x0a] & 0x0F) <= sc) && ((f82c425->cga.crtc[0x0b] & 0x0F) >= sc); + cursorline = ((f82c425->cga.crtc[CGA_CRTC_CURSOR_START] & 0x0F) <= scanline) && ((f82c425->cga.crtc[CGA_CRTC_CURSOR_END] & 0x0F) >= scanline); } for (int x = 0; x < columns; x++) { chr = f82c425->vram[(addr + 2 * x) & 0x3FFF]; attr = f82c425->vram[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && (f82c425->cga.cgamode & 0x8) && (f82c425->cga.cgablink & 0x10)); + drawcursor = ((memaddr == cursoraddr) && cursorline && (f82c425->cga.cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) && (f82c425->cga.cgablink & 0x10)); - blink = ((f82c425->cga.cgablink & 0x10) && (f82c425->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); + blink = ((f82c425->cga.cgablink & 0x10) && (f82c425->cga.cgamode & CGA_MODE_FLAG_BLINK) && (attr & 0x80) && !drawcursor); if (drawcursor) { colors[0] = smartmap[~attr & 0xff][0]; @@ -398,16 +398,16 @@ f82c425_text_row(f82c425_t *f82c425) if (f82c425->cga.cgamode & 0x01) { /* High resolution (80 cols) */ for (c = 0; c < sl; c++) { - (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][scanline] & (1 << (c ^ 7))) ? 1 : 0]; } } else { /* Low resolution (40 columns, stretch pixels horizontally) */ for (c = 0; c < sl; c++) { - (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]; + (buffer32->line[f82c425->displine])[(x << 4) + c * 2] = (buffer32->line[f82c425->displine])[(x << 4) + c * 2 + 1] = colors[(fontdat[chr][scanline] & (1 << (c ^ 7))) ? 1 : 0]; } } - ++ma; + ++memaddr; } } @@ -418,9 +418,9 @@ f82c425_cgaline6(f82c425_t *f82c425) uint8_t dat; uint16_t addr; - uint16_t ma = (f82c425->cga.crtc[0x0d] | (f82c425->cga.crtc[0x0c] << 8)) & 0x3fff; + uint16_t memaddr = (f82c425->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (f82c425->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; - addr = ((f82c425->displine) & 1) * 0x2000 + (f82c425->displine >> 1) * 80 + ((ma & ~1) << 1); + addr = ((f82c425->displine) & 1) * 0x2000 + (f82c425->displine >> 1) * 80 + ((memaddr & ~1) << 1); for (uint8_t x = 0; x < 80; x++) { dat = f82c425->vram[addr & 0x3FFF]; @@ -442,8 +442,8 @@ f82c425_cgaline4(f82c425_t *f82c425) uint8_t pattern; uint16_t addr; - uint16_t ma = (f82c425->cga.crtc[0x0d] | (f82c425->cga.crtc[0x0c] << 8)) & 0x3fff; - addr = ((f82c425->displine) & 1) * 0x2000 + (f82c425->displine >> 1) * 80 + ((ma & ~1) << 1); + uint16_t memaddr = (f82c425->cga.crtc[CGA_CRTC_START_ADDR_LOW] | (f82c425->cga.crtc[CGA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + addr = ((f82c425->displine) & 1) * 0x2000 + (f82c425->displine >> 1) * 80 + ((memaddr & ~1) << 1); for (uint8_t x = 0; x < 80; x++) { dat = f82c425->vram[addr & 0x3FFF]; @@ -526,7 +526,7 @@ f82c425_poll(void *priv) f82c425->displine = 0; f82c425->cga.cgastat &= ~8; f82c425->dispon = 1; - } else if (f82c425->displine == (f82c425->cga.crtc[9] + 1) * f82c425->cga.crtc[6]) { + } else if (f82c425->displine == (f82c425->cga.crtc[CGA_CRTC_MAX_SCANLINE_ADDR] + 1) * f82c425->cga.crtc[CGA_CRTC_VDISP]) { /* Start of VSYNC */ f82c425->cga.cgastat |= 8; f82c425->dispon = 0; diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index c7a91aac6..366fa25e1 100644 --- a/src/video/vid_genius.c +++ b/src/video/vid_genius.c @@ -387,7 +387,7 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) int cw = 9; /* Each character is 9 pixels wide */ uint8_t chr; uint8_t attr; - uint8_t sc; + uint8_t scanline; uint8_t ctrl; const uint8_t *crtc; uint8_t bitmap[2]; @@ -398,8 +398,8 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) int drawcursor; int cursorline; 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; + uint16_t memaddr = (genius->mda_crtc[13] | (genius->mda_crtc[12] << 8)) & 0x3fff; + uint16_t cursoraddr = (genius->mda_crtc[15] | (genius->mda_crtc[14] << 8)) & 0x3fff; const uint8_t *framebuf = genius->vram + 0x10000; uint32_t col; uint32_t dl = genius->displine; @@ -416,14 +416,14 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) #if 0 if (genius->genius_charh & 0x10) { row = ((dl >> 1) / charh); - sc = ((dl >> 1) % charh); + scanline = ((dl >> 1) % charh); } else { row = (dl / charh); - sc = (dl % charh); + scanline = (dl % charh); } #else row = (dl / charh); - sc = (dl % charh); + scanline = (dl % charh); #endif } else { if ((genius->displine < 512) || (genius->displine >= 912)) @@ -439,23 +439,23 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) charh = crtc[9] + 1; row = ((dl >> 1) / charh); - sc = ((dl >> 1) % charh); + scanline = ((dl >> 1) % charh); } - ma = (crtc[13] | (crtc[12] << 8)) & 0x3fff; - ca = (crtc[15] | (crtc[14] << 8)) & 0x3fff; + memaddr = (crtc[13] | (crtc[12] << 8)) & 0x3fff; + cursoraddr = (crtc[15] | (crtc[14] << 8)) & 0x3fff; - addr = ((ma & ~1) + row * w) * 2; + addr = ((memaddr & ~1) + row * w) * 2; if (!mda) dl += 512; - ma += (row * w); + memaddr += (row * w); if ((crtc[10] & 0x60) == 0x20) cursorline = 0; else - cursorline = ((crtc[10] & 0x1F) <= sc) && ((crtc[11] & 0x1F) >= sc); + cursorline = ((crtc[10] & 0x1F) <= scanline) && ((crtc[11] & 0x1F) >= scanline); for (int x = 0; x < w; x++) { #if 0 @@ -467,7 +467,7 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) chr = framebuf[(addr + 2 * x) & 0x3FFF]; attr = framebuf[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && genius->enabled && (ctrl & 8)); + drawcursor = ((memaddr == cursoraddr) && cursorline && genius->enabled && (ctrl & 8)); switch (crtc[10] & 0x60) { case 0x00: @@ -487,7 +487,7 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) attr &= 0x7F; /* MDA underline */ - if (mda && (sc == charh) && ((attr & 7) == 1)) { + if (mda && (scanline == charh) && ((attr & 7) == 1)) { col = mdaattr[attr][blink][1]; if (genius->genius_control & 0x20) @@ -504,9 +504,9 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) } } else { /* Draw 8 pixels of character */ if (mda) - bitmap[0] = fontdat8x12[chr][sc]; + bitmap[0] = fontdat8x12[chr][scanline]; else - bitmap[0] = fontdat[chr][sc]; + bitmap[0] = fontdat[chr][scanline]; for (c = 0; c < 8; c++) { col = mdaattr[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; @@ -563,7 +563,7 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) } } } - ++ma; + ++memaddr; } } } diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index 00374d08f..15b9e69cd 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -27,9 +27,9 @@ #include <86box/rom.h> #include <86box/io.h> #include <86box/timer.h> +#include <86box/device.h> #include <86box/lpt.h> #include <86box/pit.h> -#include <86box/device.h> #include <86box/video.h> #include <86box/vid_hercules.h> #include <86box/plat_unused.h> @@ -168,9 +168,9 @@ hercules_in(uint16_t addr, void *priv) case 0x03b5: case 0x03b7: if (dev->crtcreg == 0x0c) - ret = (dev->ma >> 8) & 0x3f; + ret = (dev->memaddr >> 8) & 0x3f; else if (dev->crtcreg == 0x0d) - ret = dev->ma & 0xff; + ret = dev->memaddr & 0xff; else ret = dev->crtc[dev->crtcreg]; break; @@ -178,8 +178,8 @@ hercules_in(uint16_t addr, void *priv) case 0x03ba: ret = 0x70; /* Hercules ident */ ret |= (dev->lp_ff ? 2 : 0); - ret |= (dev->stat & 0x01); - if (dev->stat & 0x08) + ret |= (dev->status & 0x01); + if (dev->status & 0x08) ret |= 0x80; if ((ret & 0x81) == 0x80) ret |= 0x08; @@ -281,10 +281,10 @@ hercules_poll(void *priv) hercules_t *dev = (hercules_t *) priv; uint8_t chr; uint8_t attr; - uint16_t ca; + uint16_t cursoraddr; uint16_t dat; uint16_t pa; - int oldsc; + int scanline_old; int blink; int x; int xx; @@ -296,16 +296,16 @@ hercules_poll(void *priv) uint32_t *p; VIDEO_MONITOR_PROLOGUE() - ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff; + cursoraddr = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff; if (!dev->linepos) { timer_advance_u64(&dev->timer, dev->dispofftime); - dev->stat |= 1; + dev->status |= 1; dev->linepos = 1; - oldsc = dev->sc; + scanline_old = dev->scanline; if ((dev->crtc[8] & 3) == 3) - dev->sc = (dev->sc << 1) & 7; + dev->scanline = (dev->scanline << 1) & 7; if (dev->dispon) { if (dev->displine < dev->firstline) { @@ -317,16 +317,16 @@ hercules_poll(void *priv) hercules_render_overscan_left(dev); if (dev->ctrl & 0x02) { - ca = (dev->sc & 3) * 0x2000; + cursoraddr = (dev->scanline & 3) * 0x2000; if (dev->ctrl & 0x80) - ca += 0x8000; + cursoraddr += 0x8000; for (x = 0; x < dev->crtc[1]; x++) { if (dev->ctrl & 8) - dat = (dev->vram[((dev->ma << 1) & 0x1fff) + ca] << 8) | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 1]; + dat = (dev->vram[((dev->memaddr << 1) & 0x1fff) + cursoraddr] << 8) | dev->vram[((dev->memaddr << 1) & 0x1fff) + cursoraddr + 1]; else dat = 0; - dev->ma++; + dev->memaddr++; for (c = 0; c < 16; c++) buffer32->line[dev->displine + 14][(x << 4) + c + 8] = (dat & (32768 >> c)) ? 7 : 0; for (c = 0; c < 16; c += 8) @@ -341,25 +341,25 @@ hercules_poll(void *priv) attr = dev->charbuffer[(x << 1) + 1]; } else chr = attr = 0; - drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron); + drawcursor = ((dev->memaddr == cursoraddr) && dev->cursorvisible && dev->cursoron); blink = ((dev->blink & 16) && (dev->ctrl & 0x20) && (attr & 0x80) && !drawcursor); - if (dev->sc == 12 && ((attr & 7) == 1)) { + if (dev->scanline == 12 && ((attr & 7) == 1)) { for (c = 0; c < 9; c++) buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][1]; } else { for (c = 0; c < 8; c++) - buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][(fontdatm[chr][dev->sc] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][(fontdatm[chr][dev->scanline] & (1 << (c ^ 7))) ? 1 : 0]; if ((chr & ~0x1f) == 0xc0) - buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][fontdatm[chr][dev->sc] & 1]; + buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][fontdatm[chr][dev->scanline] & 1]; else buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][0]; } if (dev->ctrl2 & 0x01) - dev->ma = (dev->ma + 1) & 0x3fff; + dev->memaddr = (dev->memaddr + 1) & 0x3fff; else - dev->ma = (dev->ma + 1) & 0x7ff; + dev->memaddr = (dev->memaddr + 1) & 0x7ff; if (drawcursor) { for (c = 0; c < 9; c++) @@ -377,10 +377,10 @@ hercules_poll(void *priv) video_process_8(x + 16, dev->displine + 14); } - dev->sc = oldsc; + dev->scanline = scanline_old; - if (dev->vc == dev->crtc[7] && !dev->sc) - dev->stat |= 8; + if (dev->vc == dev->crtc[7] && !dev->scanline) + dev->status |= 8; dev->displine++; if (dev->displine >= 500) dev->displine = 0; @@ -388,33 +388,32 @@ hercules_poll(void *priv) timer_advance_u64(&dev->timer, dev->dispontime); if (dev->dispon) - dev->stat &= ~1; + dev->status &= ~1; dev->linepos = 0; if (dev->vsynctime) { dev->vsynctime--; if (!dev->vsynctime) - dev->stat &= ~8; + dev->status &= ~8; } - if (dev->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) { - dev->con = 0; - dev->coff = 1; + if (dev->scanline == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[11] & 31) >> 1))) { + dev->cursorvisible = 0; } if (dev->vadj) { - dev->sc++; - dev->sc &= 31; - dev->ma = dev->maback; + dev->scanline++; + dev->scanline &= 31; + dev->memaddr = dev->memaddr_backup; dev->vadj--; if (!dev->vadj) { dev->dispon = 1; - dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; - dev->sc = 0; + dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + dev->scanline = 0; } - } else if (((dev->crtc[8] & 3) != 3 && dev->sc == dev->crtc[9]) || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) { - dev->maback = dev->ma; - dev->sc = 0; + } else if (((dev->crtc[8] & 3) != 3 && dev->scanline == dev->crtc[9]) || ((dev->crtc[8] & 3) == 3 && dev->scanline == (dev->crtc[9] >> 1))) { + dev->memaddr_backup = dev->memaddr; + dev->scanline = 0; oldvc = dev->vc; dev->vc++; dev->vc &= 127; @@ -427,7 +426,7 @@ hercules_poll(void *priv) dev->vadj = dev->crtc[5]; if (!dev->vadj) { dev->dispon = 1; - dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; } switch (dev->crtc[10] & 0x60) { case 0x20: @@ -512,17 +511,17 @@ hercules_poll(void *priv) dev->blink++; } } else { - dev->sc++; - dev->sc &= 31; - dev->ma = dev->maback; + dev->scanline++; + dev->scanline &= 31; + dev->memaddr = dev->memaddr_backup; } - if (dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1))) - dev->con = 1; + if (dev->scanline == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[10] & 31) >> 1))) + dev->cursorvisible = 1; if (dev->dispon && !(dev->ctrl & 0x02)) { for (x = 0; x < (dev->crtc[1] << 1); x++) { pa = (dev->ctrl & 0x80) ? ((x & 1) ? 0x0000 : 0x8000) : 0x0000; - dev->charbuffer[x] = dev->vram[(((dev->ma << 1) + x) & 0x3fff) + pa]; + dev->charbuffer[x] = dev->vram[(((dev->memaddr << 1) + x) & 0x3fff) + pa]; } } } @@ -543,14 +542,36 @@ hercules_init(UNUSED(const device_t *info)) dev->vram = (uint8_t *) malloc(0x10000); + switch(device_get_config_int("font")) { + case 0: + loadfont(FONT_IBM_MDA_437_PATH, 0); + break; + case 1: + loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0); + break; + case 2: + loadfont(FONT_KAM_PATH, 0); + break; + case 3: + loadfont(FONT_KAMCL16_PATH, 0); + break; + case 4: + loadfont(FONT_TULIP_DGA_PATH, 0); + break; + } + timer_add(&dev->timer, hercules_poll, dev, 1); mem_mapping_add(&dev->mapping, 0xb0000, 0x08000, - hercules_read, NULL, NULL, hercules_write, NULL, NULL, - NULL /*dev->vram*/, MEM_MAPPING_EXTERNAL, dev); + hercules_read, NULL, NULL, + hercules_write, NULL, NULL, + NULL /*dev->vram*/, MEM_MAPPING_EXTERNAL, + dev); - io_sethandler(0x03b0, 16, - hercules_in, NULL, NULL, hercules_out, NULL, NULL, dev); + io_sethandler(0x03b0, 0x0010, + hercules_in, NULL, NULL, + hercules_out, NULL, NULL, + dev); for (uint16_t c = 0; c < 256; c++) { dev->cols[c][0][0] = dev->cols[c][1][0] = dev->cols[c][1][1] = 16; @@ -585,7 +606,9 @@ hercules_init(UNUSED(const device_t *info)) video_inform(VIDEO_FLAG_TYPE_MDA, &timing_hercules); /* Force the LPT3 port to be enabled. */ - lpt3_setup(LPT_MDA_ADDR); + dev->lpt = device_add_inst(&lpt_port_device, 1); + lpt_port_setup(dev->lpt, LPT_MDA_ADDR); + lpt_set_3bc_used(1); return dev; } @@ -631,6 +654,24 @@ static const device_config_t hercules_config[] = { }, .bios = { { 0 } } }, + { + .name = "font", + .description = "Font", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "US (CP 437)", .value = 0 }, + { .description = "IBM Nordic (CP 437-Nordic)", .value = 1 }, + { .description = "Czech Kamenicky (CP 895) #1", .value = 2 }, + { .description = "Czech Kamenicky (CP 895) #2", .value = 3 }, + { .description = "Tulip DGA", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } + }, { .name = "blend", .description = "Blend", diff --git a/src/video/vid_incolor.c b/src/video/vid_hercules_incolor.c similarity index 87% rename from src/video/vid_incolor.c rename to src/video/vid_hercules_incolor.c index d9b48f43a..6e3b6a6d2 100644 --- a/src/video/vid_incolor.c +++ b/src/video/vid_hercules_incolor.c @@ -24,11 +24,11 @@ #include <86box/86box.h> #include <86box/io.h> #include <86box/timer.h> +#include <86box/device.h> #include <86box/lpt.h> #include <86box/pit.h> #include <86box/mem.h> #include <86box/rom.h> -#include <86box/device.h> #include <86box/video.h> #include <86box/plat_unused.h> @@ -157,7 +157,7 @@ typedef struct { uint8_t crtc[32]; int crtcreg; - uint8_t ctrl, ctrl2, stat; + uint8_t ctrl, ctrl2, status; uint64_t dispontime, dispofftime; pc_timer_t timer; @@ -165,9 +165,9 @@ typedef struct { int firstline, lastline; int linepos, displine; - int vc, sc; - uint16_t ma, maback; - int con, coff, cursoron; + int vc, scanline; + uint16_t memaddr, memaddr_backup; + int cursorvisible, cursoron; int dispon, blink; int vsynctime; int vadj; @@ -179,6 +179,8 @@ typedef struct { uint32_t rgb[64]; uint8_t *vram; + + lpt_t *lpt; } incolor_t; static video_timings_t timing_incolor = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; @@ -285,7 +287,7 @@ incolor_in(uint16_t port, void *priv) case 0x3ba: /* 0x50: InColor card identity */ - ret = (dev->stat & 0xf) | ((dev->stat & 8) << 4) | 0x50; + ret = (dev->status & 0xf) | ((dev->status & 8) << 4) | 0x50; break; default: @@ -483,11 +485,11 @@ draw_char_rom(incolor_t *dev, int x, uint8_t chr, uint8_t attr) elg = ((chr >= 0xc0) && (chr <= 0xdf)); } - fnt = &(fontdatm[chr][dev->sc]); + fnt = &(fontdatm[chr][dev->scanline]); if (blk) { val = 0x000; /* Blinking, draw all background */ - } else if (dev->sc == ull) { + } else if (dev->scanline == ull) { val = 0x1ff; /* Underscore, draw all foreground */ } else { val = fnt[0] << 1; @@ -559,12 +561,12 @@ draw_char_ram4(incolor_t *dev, int x, uint8_t chr, uint8_t attr) } else { elg = ((chr >= 0xc0) && (chr <= 0xdf)); } - fnt = dev->vram + 0x4000 + 16 * chr + dev->sc; + fnt = dev->vram + 0x4000 + 16 * chr + dev->scanline; if (blk) { /* Blinking, draw all background */ val[0] = val[1] = val[2] = val[3] = 0x000; - } else if (dev->sc == ull) { + } else if (dev->scanline == ull) { /* Underscore, draw all foreground */ val[0] = val[1] = val[2] = val[3] = 0x1ff; } else { @@ -685,12 +687,12 @@ draw_char_ram48(incolor_t *dev, int x, uint8_t chr, uint8_t attr) } else { elg = ((chr >= 0xc0) && (chr <= 0xdf)); } - fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->sc; + fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->scanline; if (blk) { /* Blinking, draw all background */ val[0] = val[1] = val[2] = val[3] = 0x000; - } else if (dev->sc == ull) { + } else if (dev->scanline == ull) { /* Underscore, draw all foreground */ val[0] = val[1] = val[2] = val[3] = 0x1ff; } else { @@ -716,9 +718,9 @@ draw_char_ram48(incolor_t *dev, int x, uint8_t chr, uint8_t attr) /* Generate pixel colour */ cfg = 0; pmask = 1; - if (dev->sc == oll) { + if (dev->scanline == oll) { cfg = olc ^ ibg; /* Strikethrough */ - } else if (dev->sc == ull) { + } else if (dev->scanline == ull) { cfg = ulc ^ ibg; /* Underline */ } else { for (uint8_t plane = 0; plane < 4; plane++, pmask = pmask << 1) { @@ -746,7 +748,7 @@ draw_char_ram48(incolor_t *dev, int x, uint8_t chr, uint8_t attr) } static void -text_line(incolor_t *dev, uint16_t ca) +text_line(incolor_t *dev, uint16_t cursoraddr) { int drawcursor; uint8_t chr; @@ -755,12 +757,12 @@ 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) & 0x3fff]; - attr = dev->vram[((dev->ma << 1) + 1) & 0x3fff]; + chr = dev->vram[(dev->memaddr << 1) & 0x3fff]; + attr = dev->vram[((dev->memaddr << 1) + 1) & 0x3fff]; } else chr = attr = 0; - drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron); + drawcursor = ((dev->memaddr == cursoraddr) && dev->cursorvisible && dev->cursoron); switch (dev->crtc[INCOLOR_CRTC_XMODE] & 5) { case 0: @@ -779,7 +781,7 @@ text_line(incolor_t *dev, uint16_t ca) default: break; } - ++dev->ma; + ++dev->memaddr; if (drawcursor) { int cw = INCOLOR_CW; @@ -808,29 +810,29 @@ static void graphics_line(incolor_t *dev) { uint8_t mask; - uint16_t ca; + uint16_t cursoraddr; int plane; int col; uint8_t ink; uint16_t val[4]; /* Graphics mode. */ - ca = (dev->sc & 3) * 0x2000; + cursoraddr = (dev->scanline & 3) * 0x2000; if ((dev->ctrl & INCOLOR_CTRL_PAGE1) && (dev->ctrl2 & INCOLOR_CTRL2_PAGE1)) - ca += 0x8000; + cursoraddr += 0x8000; for (uint8_t x = 0; x < dev->crtc[1]; x++) { mask = dev->crtc[INCOLOR_CRTC_MASK]; /* Planes to display */ for (plane = 0; plane < 4; plane++, mask = mask >> 1) { if (dev->ctrl & 8) { if (mask & 1) - val[plane] = (dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; + val[plane] = (dev->vram[((dev->memaddr << 1) & 0x1fff) + cursoraddr + 0x10000 * plane] << 8) | dev->vram[((dev->memaddr << 1) & 0x1fff) + cursoraddr + 0x10000 * plane + 1]; else val[plane] = 0; } else val[plane] = 0; } - dev->ma++; + dev->memaddr++; for (uint8_t c = 0; c < 16; c++) { ink = 0; @@ -855,19 +857,19 @@ static void incolor_poll(void *priv) { incolor_t *dev = (incolor_t *) priv; - uint16_t ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff; + uint16_t cursoraddr = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff; int x; int oldvc; - int oldsc; + int scanline_old; int cw = INCOLOR_CW; if (!dev->linepos) { timer_advance_u64(&dev->timer, dev->dispofftime); - dev->stat |= 1; + dev->status |= 1; dev->linepos = 1; - oldsc = dev->sc; + scanline_old = dev->scanline; if ((dev->crtc[8] & 3) == 3) - dev->sc = (dev->sc << 1) & 7; + dev->scanline = (dev->scanline << 1) & 7; if (dev->dispon) { if (dev->displine < dev->firstline) { @@ -878,44 +880,43 @@ incolor_poll(void *priv) if ((dev->ctrl & INCOLOR_CTRL_GRAPH) && (dev->ctrl2 & INCOLOR_CTRL2_GRAPH)) graphics_line(dev); else - text_line(dev, ca); + text_line(dev, cursoraddr); } - dev->sc = oldsc; - if (dev->vc == dev->crtc[7] && !dev->sc) - dev->stat |= 8; + dev->scanline = scanline_old; + if (dev->vc == dev->crtc[7] && !dev->scanline) + dev->status |= 8; dev->displine++; if (dev->displine >= 500) dev->displine = 0; } else { timer_advance_u64(&dev->timer, dev->dispontime); if (dev->dispon) - dev->stat &= ~1; + dev->status &= ~1; dev->linepos = 0; if (dev->vsynctime) { dev->vsynctime--; if (!dev->vsynctime) - dev->stat &= ~8; + dev->status &= ~8; } - if (dev->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) { - dev->con = 0; - dev->coff = 1; + if (dev->scanline == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[11] & 31) >> 1))) { + dev->cursorvisible = 0; } if (dev->vadj) { - dev->sc++; - dev->sc &= 31; - dev->ma = dev->maback; + dev->scanline++; + dev->scanline &= 31; + dev->memaddr = dev->memaddr_backup; dev->vadj--; if (!dev->vadj) { dev->dispon = 1; - dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; - dev->sc = 0; + dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + dev->scanline = 0; } - } else if (dev->sc == dev->crtc[9] || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) { - dev->maback = dev->ma; - dev->sc = 0; - oldvc = dev->vc; + } else if (dev->scanline == dev->crtc[9] || ((dev->crtc[8] & 3) == 3 && dev->scanline == (dev->crtc[9] >> 1))) { + dev->memaddr_backup = dev->memaddr; + dev->scanline = 0; + oldvc = dev->vc; dev->vc++; dev->vc &= 127; if (dev->vc == dev->crtc[6]) @@ -926,7 +927,7 @@ incolor_poll(void *priv) if (!dev->vadj) dev->dispon = 1; if (!dev->vadj) - dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; if ((dev->crtc[10] & 0x60) == 0x20) dev->cursoron = 0; else @@ -972,13 +973,13 @@ incolor_poll(void *priv) dev->blink++; } } else { - dev->sc++; - dev->sc &= 31; - dev->ma = dev->maback; + dev->scanline++; + dev->scanline &= 31; + dev->memaddr = dev->memaddr_backup; } - if (dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1))) - dev->con = 1; + if (dev->scanline == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[10] & 31) >> 1))) + dev->cursorvisible = 1; } } @@ -993,6 +994,24 @@ incolor_init(UNUSED(const device_t *info)) dev->vram = (uint8_t *) malloc(0x40000); /* 4 planes of 64k */ + switch(device_get_config_int("font")) { + case 0: + loadfont(FONT_IBM_MDA_437_PATH, 0); + break; + case 1: + loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0); + break; + case 2: + loadfont(FONT_KAM_PATH, 0); + break; + case 3: + loadfont(FONT_KAMCL16_PATH, 0); + break; + case 4: + loadfont(FONT_TULIP_DGA_PATH, 0); + break; + } + timer_add(&dev->timer, incolor_poll, dev, 1); mem_mapping_add(&dev->mapping, 0xb0000, 0x08000, @@ -1018,7 +1037,9 @@ incolor_init(UNUSED(const device_t *info)) video_inform(VIDEO_FLAG_TYPE_MDA, &timing_incolor); /* Force the LPT3 port to be enabled. */ - lpt3_setup(LPT_MDA_ADDR); + dev->lpt = device_add_inst(&lpt_port_device, 1); + lpt_port_setup(dev->lpt, LPT_MDA_ADDR); + lpt_set_3bc_used(1); return dev; } @@ -1045,6 +1066,30 @@ speed_changed(void *priv) recalc_timings(dev); } +static const device_config_t incolor_config[] = { + // clang-format off + { + .name = "font", + .description = "Font", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "US (CP 437)", .value = 0 }, + { .description = "IBM Nordic (CP 437-Nordic)", .value = 1 }, + { .description = "Czech Kamenicky (CP 895) #1", .value = 2 }, + { .description = "Czech Kamenicky (CP 895) #2", .value = 3 }, + { .description = "Tulip DGA", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + const device_t incolor_device = { .name = "Hercules InColor", .internal_name = "incolor", @@ -1056,5 +1101,5 @@ const device_t incolor_device = { .available = NULL, .speed_changed = speed_changed, .force_redraw = NULL, - .config = NULL + .config = incolor_config }; diff --git a/src/video/vid_herculesplus.c b/src/video/vid_hercules_plus.c similarity index 82% rename from src/video/vid_herculesplus.c rename to src/video/vid_hercules_plus.c index fb42c3022..c6b442ce0 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_hercules_plus.c @@ -24,11 +24,11 @@ #include <86box/86box.h> #include <86box/io.h> #include <86box/timer.h> +#include <86box/device.h> #include <86box/lpt.h> #include <86box/pit.h> #include <86box/mem.h> #include <86box/rom.h> -#include <86box/device.h> #include <86box/video.h> #include <86box/plat_unused.h> @@ -67,7 +67,7 @@ typedef struct { uint8_t crtc[32]; int crtcreg; - uint8_t ctrl, ctrl2, stat; + uint8_t ctrl, ctrl2, status; uint64_t dispontime, dispofftime; pc_timer_t timer; @@ -75,9 +75,9 @@ typedef struct { int firstline, lastline; int linepos, displine; - int vc, sc; - uint16_t ma, maback; - int con, coff, cursoron; + int vc, scanline; + uint16_t memaddr, memaddr_backup; + int cursorvisible, cursoron; int dispon, blink; int vsynctime; int vadj; @@ -86,6 +86,8 @@ typedef struct { int cols[256][2][2]; uint8_t *vram; + + lpt_t *lpt; } herculesplus_t; #define VIDEO_MONITOR_PROLOGUE() \ @@ -194,7 +196,7 @@ herculesplus_in(uint16_t port, void *priv) case 0x3ba: /* 0x10: Hercules Plus card identity */ - ret = (dev->stat & 0xf) | ((dev->stat & 8) << 4) | 0x10; + ret = (dev->status & 0xf) | ((dev->status & 8) << 4) | 0x10; break; default: @@ -260,11 +262,11 @@ draw_char_rom(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) else elg = ((chr >= 0xc0) && (chr <= 0xdf)); - fnt = &(fontdatm[chr][dev->sc]); + fnt = &(fontdatm[chr][dev->scanline]); if (blk) { val = 0x000; /* Blinking, draw all background */ - } else if (dev->sc == ull) { + } else if (dev->scanline == ull) { val = 0x1ff; /* Underscore, draw all foreground */ } else { val = fnt[0] << 1; @@ -319,11 +321,11 @@ draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) else elg = ((chr >= 0xc0) && (chr <= 0xdf)); - fnt = dev->vram + 0x4000 + 16 * chr + dev->sc; + fnt = dev->vram + 0x4000 + 16 * chr + dev->scanline; if (blk) { val = 0x000; /* Blinking, draw all background */ - } else if (dev->sc == ull) { + } else if (dev->scanline == ull) { val = 0x1ff; /* Underscore, draw all foreground */ } else { val = fnt[0] << 1; @@ -384,11 +386,11 @@ draw_char_ram48(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) else elg = ((chr >= 0xc0) && (chr <= 0xdf)); - fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->sc; + fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->scanline; if (blk) { val = 0x000; /* Blinking, draw all background */ - } else if (dev->sc == ull) { + } else if (dev->scanline == ull) { val = 0x1ff; /* Underscore, draw all foreground */ } else { val = fnt[0] << 1; @@ -404,7 +406,7 @@ draw_char_ram48(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) } static void -text_line(herculesplus_t *dev, uint16_t ca) +text_line(herculesplus_t *dev, uint16_t cursoraddr) { int drawcursor; uint8_t chr; @@ -413,12 +415,12 @@ 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) & 0x3fff]; - attr = dev->vram[((dev->ma << 1) + 1) & 0x3fff]; + chr = dev->vram[(dev->memaddr << 1) & 0x3fff]; + attr = dev->vram[((dev->memaddr << 1) + 1) & 0x3fff]; } else chr = attr = 0; - drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron); + drawcursor = ((dev->memaddr == cursoraddr) && dev->cursorvisible && dev->cursoron); switch (dev->crtc[HERCULESPLUS_CRTC_XMODE] & 5) { case 0: @@ -437,7 +439,7 @@ text_line(herculesplus_t *dev, uint16_t ca) default: break; } - ++dev->ma; + ++dev->memaddr; if (drawcursor) { int cw = HERCULESPLUS_CW; @@ -452,24 +454,24 @@ text_line(herculesplus_t *dev, uint16_t ca) static void graphics_line(herculesplus_t *dev) { - uint16_t ca; + uint16_t cursoraddr; int c; int plane = 0; uint16_t val; /* Graphics mode. */ - ca = (dev->sc & 3) * 0x2000; + cursoraddr = (dev->scanline & 3) * 0x2000; if ((dev->ctrl & HERCULESPLUS_CTRL_PAGE1) && (dev->ctrl2 & HERCULESPLUS_CTRL2_PAGE1)) - ca += 0x8000; + cursoraddr += 0x8000; for (uint8_t x = 0; x < dev->crtc[1]; x++) { if (dev->ctrl & 8) - val = (dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) - | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; + val = (dev->vram[((dev->memaddr << 1) & 0x1fff) + cursoraddr + 0x10000 * plane] << 8) + | dev->vram[((dev->memaddr << 1) & 0x1fff) + cursoraddr + 0x10000 * plane + 1]; else val = 0; - dev->ma++; + dev->memaddr++; for (c = 0; c < 16; c++) { buffer32->line[dev->displine][(x << 4) + c] = (val & 0x8000) ? 7 : 0; @@ -485,20 +487,20 @@ static void herculesplus_poll(void *priv) { herculesplus_t *dev = (herculesplus_t *) priv; - uint16_t ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff; + uint16_t cursoraddr = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff; int x; int oldvc; - int oldsc; + int scanline_old; int cw = HERCULESPLUS_CW; VIDEO_MONITOR_PROLOGUE(); if (!dev->linepos) { timer_advance_u64(&dev->timer, dev->dispofftime); - dev->stat |= 1; + dev->status |= 1; dev->linepos = 1; - oldsc = dev->sc; + scanline_old = dev->scanline; if ((dev->crtc[8] & 3) == 3) - dev->sc = (dev->sc << 1) & 7; + dev->scanline = (dev->scanline << 1) & 7; if (dev->dispon) { if (dev->displine < dev->firstline) { dev->firstline = dev->displine; @@ -508,7 +510,7 @@ herculesplus_poll(void *priv) if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) graphics_line(dev); else - text_line(dev, ca); + text_line(dev, cursoraddr); if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) x = dev->crtc[1] << 4; @@ -517,40 +519,39 @@ herculesplus_poll(void *priv) video_process_8(x, dev->displine); } - dev->sc = oldsc; - if (dev->vc == dev->crtc[7] && !dev->sc) - dev->stat |= 8; + dev->scanline = scanline_old; + if (dev->vc == dev->crtc[7] && !dev->scanline) + dev->status |= 8; dev->displine++; if (dev->displine >= 500) dev->displine = 0; } else { timer_advance_u64(&dev->timer, dev->dispontime); if (dev->dispon) - dev->stat &= ~1; + dev->status &= ~1; dev->linepos = 0; if (dev->vsynctime) { dev->vsynctime--; if (!dev->vsynctime) - dev->stat &= ~8; + dev->status &= ~8; } - if (dev->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) { - dev->con = 0; - dev->coff = 1; + if (dev->scanline == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[11] & 31) >> 1))) { + dev->cursorvisible = 0; } if (dev->vadj) { - dev->sc++; - dev->sc &= 31; - dev->ma = dev->maback; + dev->scanline++; + dev->scanline &= 31; + dev->memaddr = dev->memaddr_backup; dev->vadj--; if (!dev->vadj) { dev->dispon = 1; - dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; - dev->sc = 0; + dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + dev->scanline = 0; } - } else if (dev->sc == dev->crtc[9] || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) { - dev->maback = dev->ma; - dev->sc = 0; + } else if (dev->scanline == dev->crtc[9] || ((dev->crtc[8] & 3) == 3 && dev->scanline == (dev->crtc[9] >> 1))) { + dev->memaddr_backup = dev->memaddr; + dev->scanline = 0; oldvc = dev->vc; dev->vc++; dev->vc &= 127; @@ -562,7 +563,7 @@ herculesplus_poll(void *priv) if (!dev->vadj) dev->dispon = 1; if (!dev->vadj) - dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + dev->memaddr = dev->memaddr_backup = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; if ((dev->crtc[10] & 0x60) == 0x20) dev->cursoron = 0; else @@ -607,13 +608,13 @@ herculesplus_poll(void *priv) dev->blink++; } } else { - dev->sc++; - dev->sc &= 31; - dev->ma = dev->maback; + dev->scanline++; + dev->scanline &= 31; + dev->memaddr = dev->memaddr_backup; } - if (dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1))) - dev->con = 1; + if (dev->scanline == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->scanline == ((dev->crtc[10] & 31) >> 1))) + dev->cursorvisible = 1; } VIDEO_MONITOR_EPILOGUE(); @@ -630,6 +631,24 @@ herculesplus_init(UNUSED(const device_t *info)) dev->vram = (uint8_t *) malloc(0x10000); /* 64k VRAM */ dev->monitor_index = monitor_index_global; + switch(device_get_config_int("font")) { + case 0: + loadfont(FONT_IBM_MDA_437_PATH, 0); + break; + case 1: + loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0); + break; + case 2: + loadfont(FONT_KAM_PATH, 0); + break; + case 3: + loadfont(FONT_KAMCL16_PATH, 0); + break; + case 4: + loadfont(FONT_TULIP_DGA_PATH, 0); + break; + } + timer_add(&dev->timer, herculesplus_poll, dev, 1); mem_mapping_add(&dev->mapping, 0xb0000, 0x08000, @@ -670,7 +689,9 @@ herculesplus_init(UNUSED(const device_t *info)) video_inform(VIDEO_FLAG_TYPE_MDA, &timing_herculesplus); /* Force the LPT3 port to be enabled. */ - lpt3_setup(LPT_MDA_ADDR); + dev->lpt = device_add_inst(&lpt_port_device, 1); + lpt_port_setup(dev->lpt, LPT_MDA_ADDR); + lpt_set_3bc_used(1); return dev; } @@ -716,6 +737,24 @@ static const device_config_t herculesplus_config[] = { }, .bios = { { 0 } } }, + { + .name = "font", + .description = "Font", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "US (CP 437)", .value = 0 }, + { .description = "IBM Nordic (CP 437-Nordic)", .value = 1 }, + { .description = "Czech Kamenicky (CP 895) #1", .value = 2 }, + { .description = "Czech Kamenicky (CP 895) #2", .value = 3 }, + { .description = "Tulip DGA", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } + }, { .name = "blend", .description = "Blend", diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index b650cb53b..3089ae26d 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -448,7 +448,7 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -660,10 +660,10 @@ ht216_recalctimings(svga_t *svga) break; } - svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12); + svga->memaddr_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12); if (ht216->ht_regs[0xf6] & 0x80) - svga->ma_latch = ((ht216->ht_regs[0xf6] & 0x30) << 12); + svga->memaddr_latch = ((ht216->ht_regs[0xf6] & 0x30) << 12); svga->interlace = ht216->ht_regs[0xe0] & 0x01; diff --git a/src/video/vid_jega.c b/src/video/vid_jega.c index 4240f5e98..eafdceb9c 100644 --- a/src/video/vid_jega.c +++ b/src/video/vid_jega.c @@ -113,17 +113,17 @@ typedef struct jega_t { uint8_t attr_palette_enable; uint32_t *pallook; int is_vga; - int con; + int cursorvisible; int cursoron; int cursorblink_disable; - int ca; + int cursoraddr; int font_index; int sbcsbank_inv; int attr3_sbcsbank; int start_scan_lower; int start_scan_upper; int start_scan_count; - uint8_t * vram; + uint8_t *vram; uint8_t jfont_sbcs_19[SBCS19_FILESIZE]; /* 8 x 19 font */ uint8_t jfont_dbcs_16[DBCS16_FILESIZE]; /* 16 x 16 font. Use dbcs_read/write to access it. */ } jega_t; @@ -134,28 +134,30 @@ static void jega_recalctimings(void *priv); #define FONTX_LEN_FN 8 typedef struct { - char id[FONTX_LEN_ID]; - char name[FONTX_LEN_FN]; - uint8_t width; - uint8_t height; - uint8_t type; + char id[FONTX_LEN_ID]; + char name[FONTX_LEN_FN]; + uint8_t width; + uint8_t height; + uint8_t type; } fontx_h; typedef struct { - uint16_t start; - uint16_t end; + uint16_t start; + uint16_t end; } fontx_tbl; -extern uint32_t pallook16[256]; -extern uint32_t pallook64[256]; -static bool is_SJIS_1(uint8_t chr) { return (chr >= 0x81 && chr <= 0x9f) || (chr >= 0xe0 && chr <= 0xfc); } -static bool is_SJIS_2(uint8_t chr) { return (chr >= 0x40 && chr <= 0x7e) || (chr >= 0x80 && chr <= 0xfc); } +extern uint32_t pallook16[256]; +extern uint32_t pallook64[256]; +static bool is_SJIS_1(uint8_t chr) { return (chr >= 0x81 && chr <= 0x9f) || (chr >= 0xe0 && chr <= 0xfc); } +static bool is_SJIS_2(uint8_t chr) { return (chr >= 0x40 && chr <= 0x7e) || (chr >= 0x80 && chr <= 0xfc); } + +static uint8_t jega_in(uint16_t addr, void *priv); static uint16_t SJIS_to_SEQ(uint16_t sjis) { uint32_t chr1 = (sjis >> 8) & 0xff; - uint32_t chr2 = sjis & 0xff; + uint32_t chr2 = sjis & 0xff; if (!is_SJIS_1(chr1) || !is_SJIS_2(chr2)) return INVALIDACCESS16; @@ -177,8 +179,8 @@ SJIS_to_SEQ(uint16_t sjis) static uint8_t dbcs_read(uint16_t sjis, int index, void *priv) { - jega_t *jega = (jega_t *) priv; - int seq = SJIS_to_SEQ(sjis); + jega_t *jega = (jega_t *) priv; + int seq = SJIS_to_SEQ(sjis); if ((seq >= DBCS16_CHARS) || (index >= 32)) return INVALIDACCESS8; return jega->jfont_dbcs_16[seq * 32 + index]; @@ -186,8 +188,8 @@ dbcs_read(uint16_t sjis, int index, void *priv) { static void dbcs_write(uint16_t sjis, int index, uint8_t val, void *priv) { - jega_t *jega = (jega_t *) priv; - int seq = SJIS_to_SEQ(sjis); + jega_t *jega = (jega_t *) priv; + int seq = SJIS_to_SEQ(sjis); if ((seq >= DBCS16_CHARS) || (index >= 32)) return; jega->jfont_dbcs_16[seq * 32 + index] = val; @@ -197,39 +199,39 @@ dbcs_write(uint16_t sjis, int index, uint8_t val, void *priv) { void jega_render_text(void *priv) { - jega_t * jega = (jega_t *) priv; + jega_t *jega = (jega_t *) priv; #ifdef USE_DOUBLE_WIDTH_AND_LINE_CHARS - uint8_t * seqregs = jega->is_vga ? jega->vga.svga.seqregs : + uint8_t *seqregs = jega->is_vga ? jega->vga.svga.seqregs : jega->ega.seqregs; - uint8_t * attrregs = jega->is_vga ? jega->vga.svga.attrregs : + uint8_t *attrregs = jega->is_vga ? jega->vga.svga.attrregs : jega->ega.attrregs; #endif - uint8_t * crtc = jega->is_vga ? jega->vga.svga.crtc : + uint8_t *crtc = jega->is_vga ? jega->vga.svga.crtc : jega->ega.crtc; - uint8_t * vram = jega->is_vga ? jega->vga.svga.vram : + uint8_t *vram = jega->is_vga ? jega->vga.svga.vram : jega->ega.vram; - int * firstline_draw = jega->is_vga ? &jega->vga.svga.firstline_draw : + int *firstline_draw = jega->is_vga ? &jega->vga.svga.firstline_draw : &jega->ega.firstline_draw; - int * lastline_draw = jega->is_vga ? &jega->vga.svga.lastline_draw : + int *lastline_draw = jega->is_vga ? &jega->vga.svga.lastline_draw : &jega->ega.lastline_draw; - int * displine = jega->is_vga ? &jega->vga.svga.displine : + int *displine = jega->is_vga ? &jega->vga.svga.displine : &jega->ega.displine; - int * fullchange = jega->is_vga ? &jega->vga.svga.fullchange : + int *fullchange = jega->is_vga ? &jega->vga.svga.fullchange : &jega->ega.fullchange; - int * blink = jega->is_vga ? &jega->vga.svga.blink : + int *blink = jega->is_vga ? &jega->vga.svga.blink : &jega->ega.blink; - int * x_add = jega->is_vga ? &jega->vga.svga.x_add : + int *x_add = jega->is_vga ? &jega->vga.svga.x_add : &jega->ega.x_add; - int * y_add = jega->is_vga ? &jega->vga.svga.y_add : + int *y_add = jega->is_vga ? &jega->vga.svga.y_add : &jega->ega.y_add; - int * sc = jega->is_vga ? &jega->vga.svga.sc : - &jega->ega.sc; - int * hdisp = jega->is_vga ? &jega->vga.svga.hdisp : + int *sc = jega->is_vga ? &jega->vga.svga.scanline : + &jega->ega.scanline; + int *hdisp = jega->is_vga ? &jega->vga.svga.hdisp : &jega->ega.hdisp; - int * scrollcache = jega->is_vga ? &jega->vga.svga.scrollcache : + int *scrollcache = jega->is_vga ? &jega->vga.svga.scrollcache : &jega->ega.scrollcache; - uint32_t *ma = jega->is_vga ? &jega->vga.svga.ma : - &jega->ega.ma; + uint32_t *memaddr = jega->is_vga ? &jega->vga.svga.memaddr : + &jega->ega.memaddr; uint8_t mask = jega->is_vga ? jega->vga.svga.dac_mask : 0xff; if (*firstline_draw == 2000) @@ -253,19 +255,19 @@ jega_render_text(void *priv) uint32_t attr_basic = 0; uint32_t chr_first; int fg = 0; - int bg; + int bg = 0; for (int x = 0; x < (*hdisp + *scrollcache); x += charwidth) { uint32_t addr = 0; if (jega->is_vga) { if (!jega->vga.svga.force_old_addr) - addr = jega->vga.svga.remap_func(&jega->vga.svga, jega->vga.svga.ma) & + addr = jega->vga.svga.remap_func(&jega->vga.svga, jega->vga.svga.memaddr) & jega->vga.svga.vram_display_mask; } else - addr = jega->ega.remap_func(&jega->ega, *ma) & jega->ega.vrammask; + addr = jega->ega.remap_func(&jega->ega, *memaddr) & jega->ega.vrammask; - int drawcursor = ((*ma == jega->ca) && cursoron); + int drawcursor = ((*memaddr == jega->cursoraddr) && cursoron); uint32_t chr; uint32_t attr; @@ -389,9 +391,9 @@ jega_render_text(void *priv) for (int xx = 0; xx < charwidth; xx++) p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if (attr_basic & 0x20) { /* vertical line */ + if (attr_basic & 0x20) /* vertical line */ p[0] = fg; - } + if ((*sc == jega->regs[RPULP]) && (attr_basic & 0x10)) { /* underline */ for (int xx = 0; xx < charwidth; xx++) p[xx] = fg; @@ -399,9 +401,9 @@ jega_render_text(void *priv) p += charwidth; } } - *ma += 4; + *memaddr += 4; } - *ma &= 0x3ffff; + *memaddr &= 0x3ffff; } } @@ -422,7 +424,10 @@ jega_out(uint16_t addr, uint8_t val, void *priv) if (!jega->attrff) { jega->attraddr = val & 31; if ((val & 0x20) != jega->attr_palette_enable) { - jega->ega.fullchange = 3; + if (jega->is_vga) + jega->vga.svga.fullchange = 3; + else + jega->ega.fullchange = 3; jega->attr_palette_enable = val & 0x20; jega_recalctimings(jega); } @@ -449,6 +454,13 @@ jega_out(uint16_t addr, uint8_t val, void *priv) } jega->attrff ^= 1; break; + case 0x3c2: + if (jega->regs[RMOD1] & 0x0c) { + io_removehandler(0x03a0, 0x0020, jega_in, NULL, NULL, jega_out, NULL, NULL, jega); + if (!(val & 1)) + io_sethandler(0x03a0, 0x0020, jega_in, NULL, NULL, jega_out, NULL, NULL, jega); + } + break; case 0x3b4: case 0x3d4: /* Index 0x00-0x1F (write only), 0xB8-0xDF (write and read) */ @@ -523,7 +535,7 @@ jega_out(uint16_t addr, uint8_t val, void *priv) break; case RCCLH: case RCCLL: - jega->ca = jega->regs[RCCLH] << 10 | jega->regs[RCCLL] << 2; + jega->cursoraddr = jega->regs[RCCLH] << 10 | jega->regs[RCCLL] << 2; break; case RCMOD: jega->cursoron = (val & 0x80); @@ -643,11 +655,11 @@ jega_in(uint16_t addr, void *priv) static int getfontx2header(FILE *fp, fontx_h *header) { - fread(header->id, FONTX_LEN_ID, 1, fp); - if (strncmp(header->id, "FONTX2", FONTX_LEN_ID) != 0) { + (void) !fread(header->id, FONTX_LEN_ID, 1, fp); + if (strncmp(header->id, "FONTX2", FONTX_LEN_ID) != 0) return 1; - } - fread(header->name, FONTX_LEN_FN, 1, fp); + + (void) !fread(header->name, FONTX_LEN_FN, 1, fp); header->width = (uint8_t) getc(fp); header->height = (uint8_t) getc(fp); header->type = (uint8_t) getc(fp); @@ -657,9 +669,8 @@ getfontx2header(FILE *fp, fontx_h *header) static uint16_t chrtosht(FILE *fp) { - uint16_t i, j; - i = (uint16_t) getc(fp); - j = (uint16_t) getc(fp) << 8; + uint16_t i = (uint16_t) getc(fp); + uint16_t j = (uint16_t) getc(fp) << 8; return (i | j); } @@ -683,7 +694,6 @@ LoadFontxFile(const char *fn, void *priv) uint16_t scode; uint8_t size; uint8_t buf; - int line; jega_t *jega = (jega_t *) priv; FILE *fp = rom_fopen(fn, "rb"); jega_log("JEGA: Loading font\n"); @@ -706,10 +716,10 @@ LoadFontxFile(const char *fn, void *priv) for (code = ftbl[i].start; code <= ftbl[i].end; code++) { scode = SJIS_to_SEQ(code); if (scode != INVALIDACCESS16) { - for (line = 0; line < 16; line++) { - fread(&buf, sizeof(uint8_t), 1, fp); + for (uint8_t line = 0; line < 16; line++) { + (void) !fread(&buf, sizeof(uint8_t), 1, fp); jega->jfont_dbcs_16[(int) (scode * 32) + line] = buf; - fread(&buf, sizeof(uint8_t), 1, fp); + (void) !fread(&buf, sizeof(uint8_t), 1, fp); jega->jfont_dbcs_16[(int) (scode * 32) + line + 16] = buf; } } else { @@ -723,9 +733,9 @@ LoadFontxFile(const char *fn, void *priv) return 1; } } else { - if (fhead.width == 8 && fhead.height == 19) { - fread(jega->jfont_sbcs_19, sizeof(uint8_t), SBCS19_FILESIZE, fp); - } else { + if (fhead.width == 8 && fhead.height == 19) + (void) !fread(jega->jfont_sbcs_19, sizeof(uint8_t), SBCS19_FILESIZE, fp); + else { fclose(fp); jega_log("JEGA: Width or height of SBCS font doesn't match.\n"); return 1; @@ -742,11 +752,21 @@ jega_commoninit(const device_t *info, void *priv, int vga) jega->is_vga = vga; if (vga) { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_vga); - vga_init(info, &jega->vga, 1); + svga_init(info, &jega->vga.svga, &jega->vga, 1 << 18, /*256kb*/ + NULL, + jega_in, jega_out, + NULL, + NULL); + + jega->vga.svga.bpp = 8; + jega->vga.svga.miscout = 1; + + jega->vga.svga.vga_enabled = 0; jega->vga.svga.priv_parent = jega; jega->pallook = jega->vga.svga.pallook; + io_sethandler(0x03c0, 0x0020, jega_in, NULL, NULL, jega_out, NULL, NULL, jega); } else { - for (int c = 0; c < 256; c++) { + for (uint16_t c = 0; c < 256; c++) { pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); pallook64[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); } @@ -758,9 +778,11 @@ jega_commoninit(const device_t *info, void *priv, int vga) mem_mapping_add(&jega->ega.mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, &jega->ega); + /* I/O 3DD and 3DE are used by Oki if386 */ + io_sethandler(0x03c0, 0x001c, jega_in, NULL, NULL, jega_out, NULL, NULL, jega); } /* I/O 3DD and 3DE are used by Oki if386 */ - io_sethandler(0x03b0, 0x002c, jega_in, NULL, NULL, jega_out, NULL, NULL, jega); + // io_sethandler(0x03b0, 0x002c, jega_in, NULL, NULL, jega_out, NULL, NULL, jega); jega->regs[RMOD1] = 0x48; } @@ -797,40 +819,44 @@ jega_close(void *priv) { jega_t *jega = (jega_t *) priv; #ifdef ENABLE_JEGA_LOG - FILE *f; - // f = fopen("jega_font16.dmp", "wb"); - // if (f != NULL) { - // fwrite(jega->jfont_dbcs_16, DBCS16_FILESIZE, 1, f); - // fclose(f); - // } - // f = fopen("jega_font19.dmp", "wb"); - // if (f != NULL) { - // fwrite(jega->jfont_sbcs_19, SBCS19_FILESIZE, 1, f); - // fclose(f); - // } - f = fopen("jega_regs.txt", "wb"); - if (f != NULL) { - for (int i = 0; i < 49; i++) - fprintf(f, "Regs %02X: %4X\n", i, jega->regs[i]); - for (int i = 0; i < 32; i++) - fprintf(f, "Attr %02X: %4X\n", i, jega->attrregs[i]); - for (int i = 0; i < 16; i++) - fprintf(f, "JEGAPal %02X: %4X\n", i, jega->egapal[i]); - for (int i = 0; i < 16; i++) - fprintf(f, "EGAPal %02X: %4X\n", i, jega->ega.egapal[i]); - for (int i = 0; i < 64; i++) - fprintf(f, "RealPal %02X: %4X\n", i, jega->pallook[i]); + FILE *fp; +#if 0 + fp = fopen("jega_font16.dmp", "wb"); + if (fp != NULL) { + fwrite(jega->jfont_dbcs_16, DBCS16_FILESIZE, 1, fp); fclose(f); } - // f = fopen("ega_vram.dmp", "wb"); - // if (f != NULL) { - // fwrite(jega->ega.vram, 256 * 1024, 1, f); - // fclose(f); - // } - f = fopen("ram_bda.dmp", "wb"); + fp = fopen("jega_font19.dmp", "wb"); + if (fp != NULL) { + fwrite(jega->jfont_sbcs_19, SBCS19_FILESIZE, 1, fp); + fclose(fp); + } +#endif + f = fopen("jega_regs.txt", "wb"); if (f != NULL) { - fwrite(&ram[0x0], 0x500, 1, f); - fclose(f); + for (uint8_t i = 0; i < 49; i++) + fprintf(fp, "Regs %02X: %4X\n", i, jega->regs[i]); + for (uint8_t i = 0; i < 32; i++) + fprintf(fp, "Attr %02X: %4X\n", i, jega->attrregs[i]); + for (uint8_t i = 0; i < 16; i++) + fprintf(fp, "JEGAPal %02X: %4X\n", i, jega->egapal[i]); + for (uint8_t i = 0; i < 16; i++) + fprintf(fp, "EGAPal %02X: %4X\n", i, jega->ega.egapal[i]); + for (uint8_t i = 0; i < 64; i++) + fprintf(fp, "RealPal %02X: %4X\n", i, jega->pallook[i]); + fclose(fp); + } +#if 0 + fp = fopen("ega_vram.dmp", "wb"); + if (fp != NULL) { + fwrite(jega->ega.vram, 256 * 1024, 1, fp); + fclose(fp); + } +#endif + fp = fopen("ram_bda.dmp", "wb"); + if (fp != NULL) { + fwrite(&ram[0x0], 0x500, 1, fp); + fclose(fp); } pclog("jeclosed %04X:%04X DS %04X\n", cs >> 4, cpu_state.pc, DS); #endif @@ -950,7 +976,7 @@ if386_p6x_write(uint16_t port, uint8_t val, void *priv) p65[p65idx] = val; if (p65idx == 0x03) { if (val & 0x04) { /* Color monitor */ - for (int c = 0; c < 256; c++) { + for (uint16_t c = 0; c < 256; c++) { pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); pallook64[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); pallook16[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); @@ -959,7 +985,7 @@ if386_p6x_write(uint16_t port, uint8_t val, void *priv) pallook16[c] = makecol32(0xaa, 0x55, 0); } } else { /* Monochrome LCD */ - for (int c = 0; c < 256; c++) { + for (uint16_t c = 0; c < 256; c++) { int cval = 0; #ifdef SIMPLE_BW if (c & 0x0f) diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 66a0fbb71..be6a8b6b8 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -6,16 +6,19 @@ * * This file is part of the 86Box distribution. * - * MDA emulation. + * IBM Monochrome Display and Printer Adapter emulation. * * * * Authors: Sarah Walker, * Miran Grca, + * Connor Hyde, * * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2025 Miran Grca. + * Copyright 2025 starfrost / Connor Hyde */ +#include #include #include #include @@ -24,16 +27,26 @@ #include <86box/86box.h> #include <86box/io.h> #include <86box/timer.h> +#include <86box/device.h> #include <86box/lpt.h> #include <86box/pit.h> #include <86box/mem.h> #include <86box/rom.h> -#include <86box/device.h> #include <86box/video.h> #include <86box/vid_mda.h> #include <86box/plat_unused.h> -static int mdacols[256][2][2]; +// Enumerates MDA monitor types +enum mda_monitor_type_e { + MDA_MONITOR_TYPE_DEFAULT = 0, // Default MDA monitor type. + MDA_MONITOR_TYPE_GREEN = 1, // Green phosphor + MDA_MONITOR_TYPE_AMBER = 2, // Amber phosphor + MDA_MONITOR_TYPE_GRAY = 3, // Gray phosphor + MDA_MONITOR_TYPE_RGBI = 4, // RGBI colour monitor with modified rev1 or rev0 MDA card for colour support +} mda_monitor_type; + +// [attr][blink][fg] +static int mda_attr_to_color_table[256][2][2]; static video_timings_t timing_mda = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; @@ -44,32 +57,31 @@ mda_out(uint16_t addr, uint8_t val, void *priv) { mda_t *mda = (mda_t *) priv; - switch (addr) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6: - mda->crtcreg = val & 31; - return; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7: - mda->crtc[mda->crtcreg] = val; - if (mda->crtc[10] == 6 && mda->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ - { - mda->crtc[10] = 0xb; - mda->crtc[11] = 0xc; - } - mda_recalctimings(mda); - return; - case 0x3b8: - mda->ctrl = val; - return; + if (addr < MDA_REGISTER_START + || addr > MDA_REGISTER_CRT_STATUS) // Maintain old behaviour for printer registers, just in case + return; + switch (addr) { + case MDA_REGISTER_MODE_CONTROL: + mda->mode = val; + return; default: break; } + + // addr & 1 == 1 = MDA_REGISTER_CRTC_DATA + // otherwise MDA_REGISTER_CRTC_INDEX + if (addr & 1) { + mda->crtc[mda->crtcreg] = val; + if (mda->crtc[MDA_CRTC_CURSOR_START] == 6 + && mda->crtc[MDA_CRTC_CURSOR_END] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ + { + mda->crtc[MDA_CRTC_CURSOR_START] = 0xb; + mda->crtc[MDA_CRTC_CURSOR_END] = 0xc; + } + mda_recalctimings(mda); + } else + mda->crtcreg = val & 31; } uint8_t @@ -78,23 +90,23 @@ mda_in(uint16_t addr, void *priv) const mda_t *mda = (mda_t *) priv; switch (addr) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6: - return mda->crtcreg; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7: - return mda->crtc[mda->crtcreg]; - case 0x3ba: - return mda->stat | 0xF0; - + case MDA_REGISTER_CRT_STATUS: + return mda->status | 0xF0; default: + if (addr < MDA_REGISTER_START + || addr > MDA_REGISTER_CRT_STATUS) // Maintain old behaviour for printer registers, just in case + return 0xFF; + + // MDA_REGISTER_CRTC_DATA + if (addr & 1) + return mda->crtc[mda->crtcreg]; + else + return mda->crtcreg; + break; } - return 0xff; + + return 0xFF; } void @@ -118,8 +130,8 @@ mda_recalctimings(mda_t *mda) double _dispontime; double _dispofftime; double disptime; - disptime = mda->crtc[0] + 1; - _dispontime = mda->crtc[1]; + disptime = mda->crtc[MDA_CRTC_HTOTAL] + 1; + _dispontime = mda->crtc[MDA_CRTC_HDISP]; _dispofftime = disptime - _dispontime; _dispontime *= MDACONST; _dispofftime *= MDACONST; @@ -130,59 +142,141 @@ mda_recalctimings(mda_t *mda) void mda_poll(void *priv) { - mda_t *mda = (mda_t *) priv; - uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x; - int c; - int oldvc; + mda_t *mda = (mda_t *) priv; + uint16_t cursoraddr = (mda->crtc[MDA_CRTC_CURSOR_ADDR_LOW] | (mda->crtc[MDA_CRTC_CURSOR_ADDR_HIGH] << 8)) & 0x3fff; + bool drawcursor; + int32_t oldvc; uint8_t chr; uint8_t attr; - int oldsc; - int blink; + int32_t scanline_old; + int32_t blink; VIDEO_MONITOR_PROLOGUE() + if (!mda->linepos) { timer_advance_u64(&mda->timer, mda->dispofftime); - mda->stat |= 1; + mda->status |= 1; mda->linepos = 1; - oldsc = mda->sc; - if ((mda->crtc[8] & 3) == 3) - mda->sc = (mda->sc << 1) & 7; + scanline_old = mda->scanline; + if ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3) + mda->scanline = (mda->scanline << 1) & 7; + if (mda->dispon) { if (mda->displine < mda->firstline) { mda->firstline = mda->displine; video_wait_for_buffer(); } mda->lastline = mda->displine; - for (x = 0; x < mda->crtc[1]; x++) { - chr = mda->vram[(mda->ma << 1) & 0xfff]; - attr = mda->vram[((mda->ma << 1) + 1) & 0xfff]; - drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron); - blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); - if (mda->sc == 12 && ((attr & 7) == 1)) { - for (c = 0; c < 9; c++) - 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->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->fontbase][mda->sc] & 1]; - else - buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0]; + + for (uint32_t x = 0; x < mda->crtc[MDA_CRTC_HDISP]; x++) { + chr = mda->vram[(mda->memaddr << 1) & 0xfff]; + attr = mda->vram[((mda->memaddr << 1) + 1) & 0xfff]; + drawcursor = ((mda->memaddr == cursoraddr) && mda->cursorvisible && mda->cursoron); + blink = ((mda->blink & 16) && (mda->mode & MDA_MODE_BLINK) && (attr & 0x80) && !drawcursor); + + // Colours that will be used + int32_t color_bg = 0, color_fg = 0; + + // If we are using an RGBI monitor allow colour + if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI + && !(mda->mode & MDA_MODE_BW)) { + color_bg = (attr >> 4) & 0x0F; + color_fg = (attr & 0x0F); + + // turn off bright bg colours in blink mode + if ((mda->mode & MDA_MODE_BLINK) + && (color_bg & 0x8)) + color_bg &= ~(0x8); + + // black-on-non black or white colours forced to white + // grey-on-colours forced to bright white + + bool special_treatment = (color_bg != 0 && color_bg != 7); + + if (color_fg == MDA_COLOR_GREY + && special_treatment) + color_fg = MDA_COLOR_BRIGHT_WHITE; + + if (color_fg == 0 + && special_treatment) + color_fg = MDA_COLOR_GREY; + + // gray is black + if (color_fg == MDA_COLOR_GREY + && (color_bg == MDA_COLOR_GREY || color_bg == MDA_COLOR_BLACK)) + color_fg = MDA_COLOR_BLACK; } - mda->ma++; + + if (mda->scanline == 12 + && ((attr & 7) == 1)) { // underline + for (uint32_t column = 0; column < 9; column++) { + if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI + && !(mda->mode & MDA_MODE_BW)) { + buffer32->line[mda->displine][(x * 9) + column] = CGAPAL_CGA_START + color_fg; + } else + buffer32->line[mda->displine][(x * 9) + column] = mda_attr_to_color_table[attr][blink][1]; + } + } else { // character + for (uint32_t column = 0; column < 8; column++) { + // bg=0, fg=1 + bool is_fg = (fontdatm[chr + mda->fontbase][mda->scanline] & (1 << (column ^ 7))) ? 1 : 0; + + uint32_t font_char = mda_attr_to_color_table[attr][blink][is_fg]; + + if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI + && !(mda->mode & MDA_MODE_BW)) { + if (!is_fg) + font_char = CGAPAL_CGA_START + color_bg; + else + font_char = CGAPAL_CGA_START + color_fg; + } + + buffer32->line[mda->displine][(x * 9) + column] = font_char; + } + + // these characters (C0-DF) have their background extended to their 9th column + if ((chr & ~0x1f) == 0xc0) { + bool is_fg = fontdatm[chr + mda->fontbase][mda->scanline] & 1; + uint32_t final_result = mda_attr_to_color_table[attr][blink][is_fg]; + + if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI + && !(mda->mode & MDA_MODE_BW)) { + if (!is_fg) + final_result = CGAPAL_CGA_START + color_bg; + else + final_result = CGAPAL_CGA_START + color_fg; + } + + buffer32->line[mda->displine][(x * 9) + 8] = final_result; + + } else { + if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI + && !(mda->mode & MDA_MODE_BW)) { + buffer32->line[mda->displine][(x * 9) + 8] = CGAPAL_CGA_START + color_bg; + + } else + buffer32->line[mda->displine][(x * 9) + 8] = mda_attr_to_color_table[attr][blink][0]; + } + } + + mda->memaddr++; + if (drawcursor) { - for (c = 0; c < 9; c++) - buffer32->line[mda->displine][(x * 9) + c] ^= mdacols[attr][0][1]; + for (uint32_t column = 0; column < 9; column++) { + if (mda->monitor_type == MDA_MONITOR_TYPE_RGBI + && !(mda->mode & MDA_MODE_BW)) { + buffer32->line[mda->displine][(x * 9) + column] ^= CGAPAL_CGA_START + color_fg; + } else + buffer32->line[mda->displine][(x * 9) + column] ^= mda_attr_to_color_table[attr][0][1]; + } } } - video_process_8(mda->crtc[1] * 9, mda->displine); + video_process_8(mda->crtc[MDA_CRTC_HDISP] * 9, mda->displine); } - mda->sc = oldsc; - if (mda->vc == mda->crtc[7] && !mda->sc) { - mda->stat |= 8; + mda->scanline = scanline_old; + if (mda->vc == mda->crtc[MDA_CRTC_VSYNC] && !mda->scanline) { + mda->status |= 8; } mda->displine++; if (mda->displine >= 500) @@ -190,54 +284,60 @@ mda_poll(void *priv) } else { timer_advance_u64(&mda->timer, mda->dispontime); if (mda->dispon) - mda->stat &= ~1; + mda->status &= ~1; mda->linepos = 0; + if (mda->vsynctime) { mda->vsynctime--; if (!mda->vsynctime) { - mda->stat &= ~8; + mda->status &= ~8; } } - if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) { - mda->con = 0; - mda->coff = 1; + if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_END] & 31) + || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 + && mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_END] & 31) >> 1))) { + mda->cursorvisible = 0; } + if (mda->vadj) { - mda->sc++; - mda->sc &= 31; - mda->ma = mda->maback; + mda->scanline++; + mda->scanline &= 31; + mda->memaddr = mda->memaddr_backup; mda->vadj--; if (!mda->vadj) { - mda->dispon = 1; - mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - mda->sc = 0; + mda->dispon = 1; + mda->memaddr = mda->memaddr_backup = (mda->crtc[MDA_CRTC_START_ADDR_LOW] | (mda->crtc[MDA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + mda->scanline = 0; } - } else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) { - mda->maback = mda->ma; - mda->sc = 0; - oldvc = mda->vc; + } else if (mda->scanline == mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR] + || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 + && mda->scanline == (mda->crtc[MDA_CRTC_MAX_SCANLINE_ADDR] >> 1))) { + mda->memaddr_backup = mda->memaddr; + mda->scanline = 0; + oldvc = mda->vc; mda->vc++; mda->vc &= 127; - if (mda->vc == mda->crtc[6]) + if (mda->vc == mda->crtc[MDA_CRTC_VDISP]) mda->dispon = 0; - if (oldvc == mda->crtc[4]) { + if (oldvc == mda->crtc[MDA_CRTC_VTOTAL]) { mda->vc = 0; - mda->vadj = mda->crtc[5]; + mda->vadj = mda->crtc[MDA_CRTC_VTOTAL_ADJUST]; if (!mda->vadj) mda->dispon = 1; if (!mda->vadj) - mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - if ((mda->crtc[10] & 0x60) == 0x20) + mda->memaddr = mda->memaddr_backup = (mda->crtc[MDA_CRTC_START_ADDR_LOW] | (mda->crtc[MDA_CRTC_START_ADDR_HIGH] << 8)) & 0x3fff; + if ((mda->crtc[MDA_CRTC_CURSOR_START] & 0x60) == 0x20) mda->cursoron = 0; else mda->cursoron = mda->blink & 16; } - if (mda->vc == mda->crtc[7]) { + + if (mda->vc == mda->crtc[MDA_CRTC_VSYNC]) { mda->dispon = 0; mda->displine = 0; mda->vsynctime = 16; - if (mda->crtc[7]) { - x = mda->crtc[1] * 9; + if (mda->crtc[MDA_CRTC_VSYNC]) { + uint32_t x = mda->crtc[MDA_CRTC_HDISP] * 9; mda->lastline++; if ((x != xsize) || ((mda->lastline - mda->firstline) != ysize) || video_force_resize_get()) { xsize = x; @@ -253,8 +353,8 @@ mda_poll(void *priv) } video_blit_memtoscreen(0, mda->firstline, xsize, ysize); frames++; - video_res_x = mda->crtc[1]; - video_res_y = mda->crtc[6]; + video_res_x = mda->crtc[MDA_CRTC_HDISP]; + video_res_y = mda->crtc[MDA_CRTC_VDISP]; video_bpp = 0; } mda->firstline = 1000; @@ -262,12 +362,15 @@ mda_poll(void *priv) mda->blink++; } } else { - mda->sc++; - mda->sc &= 31; - mda->ma = mda->maback; + mda->scanline++; + mda->scanline &= 31; + mda->memaddr = mda->memaddr_backup; } - if (mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1))) { - mda->con = 1; + + if (mda->scanline == (mda->crtc[MDA_CRTC_CURSOR_START] & 31) + || ((mda->crtc[MDA_CRTC_INTERLACE] & 3) == 3 + && mda->scanline == ((mda->crtc[MDA_CRTC_CURSOR_START] & 31) >> 1))) { + mda->cursorvisible = 1; } } VIDEO_MONITOR_EPILOGUE(); @@ -276,30 +379,32 @@ mda_poll(void *priv) void mda_init(mda_t *mda) { - for (uint16_t c = 0; c < 256; c++) { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; - if (c & 8) - mdacols[c][0][1] = 15 + 16; + + for (uint16_t attr = 0; attr < 256; attr++) { + mda_attr_to_color_table[attr][0][0] = mda_attr_to_color_table[attr][1][0] = mda_attr_to_color_table[attr][1][1] = 16; + if (attr & 8) + mda_attr_to_color_table[attr][0][1] = 15 + 16; else - mdacols[c][0][1] = 7 + 16; + mda_attr_to_color_table[attr][0][1] = 7 + 16; } - mdacols[0x70][0][1] = 16; - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15; - mdacols[0xF0][0][1] = 16; - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15; - mdacols[0x78][0][1] = 16 + 7; - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15; - mdacols[0xF8][0][1] = 16 + 7; - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; + mda_attr_to_color_table[0x70][0][1] = 16; + mda_attr_to_color_table[0x70][0][0] = mda_attr_to_color_table[0x70][1][0] = mda_attr_to_color_table[0x70][1][1] = CGAPAL_CGA_START + 15; + mda_attr_to_color_table[0xF0][0][1] = 16; + mda_attr_to_color_table[0xF0][0][0] = mda_attr_to_color_table[0xF0][1][0] = mda_attr_to_color_table[0xF0][1][1] = CGAPAL_CGA_START + 15; + mda_attr_to_color_table[0x78][0][1] = CGAPAL_CGA_START + 7; + mda_attr_to_color_table[0x78][0][0] = mda_attr_to_color_table[0x78][1][0] = mda_attr_to_color_table[0x78][1][1] = CGAPAL_CGA_START + 15; + mda_attr_to_color_table[0xF8][0][1] = CGAPAL_CGA_START + 7; + mda_attr_to_color_table[0xF8][0][0] = mda_attr_to_color_table[0xF8][1][0] = mda_attr_to_color_table[0xF8][1][1] = CGAPAL_CGA_START + 15; + mda_attr_to_color_table[0x00][0][1] = mda_attr_to_color_table[0x00][1][1] = 16; + mda_attr_to_color_table[0x08][0][1] = mda_attr_to_color_table[0x08][1][1] = 16; + mda_attr_to_color_table[0x80][0][1] = mda_attr_to_color_table[0x80][1][1] = 16; + mda_attr_to_color_table[0x88][0][1] = mda_attr_to_color_table[0x88][1][1] = 16; overscan_x = overscan_y = 0; mda->monitor_index = monitor_index_global; - cga_palette = device_get_config_int("rgb_type") << 1; + mda->monitor_type = device_get_config_int("rgb_type"); + cga_palette = mda->monitor_type << 1; if (cga_palette > 6) { cga_palette = 0; } @@ -317,12 +422,40 @@ mda_standalone_init(UNUSED(const device_t *info)) mda->vram = malloc(0x1000); - mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda); - io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda); + switch (device_get_config_int("font")) { + case 0: + loadfont(FONT_IBM_MDA_437_PATH, 0); + break; + case 1: + loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0); + break; + case 2: + loadfont(FONT_KAM_PATH, 0); + break; + case 3: + loadfont(FONT_KAMCL16_PATH, 0); + break; + case 4: + loadfont(FONT_TULIP_DGA_PATH, 0); + break; + } + + mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, + mda_read, NULL, NULL, + mda_write, NULL, NULL, + NULL, MEM_MAPPING_EXTERNAL, + mda); + + io_sethandler(0x03b0, 0x0010, + mda_in, NULL, NULL, + mda_out, NULL, NULL, + mda); mda_init(mda); - lpt3_setup(LPT_MDA_ADDR); + mda->lpt = device_add_inst(&lpt_port_device, 1); + lpt_port_setup(mda->lpt, LPT_MDA_ADDR); + lpt_set_3bc_used(1); return mda; } @@ -330,7 +463,7 @@ mda_standalone_init(UNUSED(const device_t *info)) void mda_setcol(int chr, int blink, int fg, uint8_t cga_ink) { - mdacols[chr][blink][fg] = 16 + cga_ink; + mda_attr_to_color_table[chr][blink][fg] = CGAPAL_CGA_START + cga_ink; } void @@ -351,7 +484,7 @@ mda_speed_changed(void *priv) } static const device_config_t mda_config[] = { - // clang-format off + // clang-format off { .name = "rgb_type", .description = "Display type", @@ -360,17 +493,38 @@ static const device_config_t mda_config[] = { .default_int = 0, .file_filter = NULL, .spinner = { 0 }, - .selection = { - { .description = "Default", .value = 0 }, - { .description = "Green", .value = 1 }, - { .description = "Amber", .value = 2 }, - { .description = "Gray", .value = 3 }, - { .description = "" } + .selection = + { + { .description = "Default", .value = MDA_MONITOR_TYPE_DEFAULT }, + { .description = "Green", .value = MDA_MONITOR_TYPE_GREEN }, + { .description = "Amber", .value = MDA_MONITOR_TYPE_AMBER }, + { .description = "Gray", .value = MDA_MONITOR_TYPE_GRAY }, + { .description = "Generic RGBI color monitor", .value = MDA_MONITOR_TYPE_RGBI }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "font", + .description = "Font", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = + { + { .description = "US (CP 437)", .value = 0 }, + { .description = "IBM Nordic (CP 437-Nordic)", .value = 1 }, + { .description = "Czech Kamenicky (CP 895) #1", .value = 2 }, + { .description = "Czech Kamenicky (CP 895) #2", .value = 3 }, + { .description = "Tulip DGA", .value = 4 }, + { .description = "" } }, .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on + // clang-format on }; const device_t mda_device = { @@ -386,3 +540,4 @@ const device_t mda_device = { .force_redraw = NULL, .config = mda_config }; + diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 00570bd9f..eded49cf6 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -35,6 +35,7 @@ #include <86box/video.h> #include <86box/i2c.h> #include <86box/vid_ddc.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> @@ -736,7 +737,7 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if ((svga->crtcreg & 0x3f) < 0xE || (svga->crtcreg & 0x3f) > 0x10) { if (((svga->crtcreg & 0x3f) == 0xc) || ((svga->crtcreg & 0x3f) == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -768,24 +769,24 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (!(mystique->type >= MGA_2164W)) svga->rowoffset <<= 1; - svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | + svga->memaddr_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; + svga->memaddr_latch <<= 1; } if (!(mystique->type >= MGA_2164W)) - svga->ma_latch <<= 1; + svga->memaddr_latch <<= 1; - if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->memaddr_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); + svga->memaddr_backup = (svga->memaddr_backup - (mystique->ma_latch_old << 2)) + + (svga->memaddr_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; + svga->memaddr_backup = (svga->memaddr_backup - (mystique->ma_latch_old << 2)) + + (svga->memaddr_latch << 2); + mystique->ma_latch_old = svga->memaddr_latch; } } @@ -895,9 +896,9 @@ 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]; + svga->memaddr_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; + svga->memaddr_latch <<= 1; } } @@ -984,29 +985,29 @@ mystique_recalctimings(svga_t *svga) 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]; + svga->memaddr_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; if (mystique->type >= MGA_1064SG) - svga->ma_latch <<= 1; + svga->memaddr_latch <<= 1; } if (mystique->type >= MGA_1064SG) { /*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 + svga->memaddr_latch <<= 1; + /* Only change memaddr_backup so the new display start will take effect on the next horizontal retrace. */ - if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->memaddr_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); + svga->memaddr_backup = (svga->memaddr_backup - (mystique->ma_latch_old << 2)) + + (svga->memaddr_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; + svga->memaddr_backup = (svga->memaddr_backup - (mystique->ma_latch_old << 2)) + + (svga->memaddr_latch << 2); + mystique->ma_latch_old = svga->memaddr_latch; } if (!(mystique->type >= MGA_2164W)) @@ -1042,6 +1043,9 @@ mystique_recalctimings(svga_t *svga) } } else { switch (svga->bpp) { + case 4: + svga->render = svga_render_4bpp_highres; + break; case 8: svga->render = svga_render_8bpp_highres; break; @@ -1061,6 +1065,9 @@ mystique_recalctimings(svga_t *svga) } } else { switch (svga->bpp) { + case 4: + svga->render = svga_render_4bpp_highres; + break; case 8: svga->render = svga_render_8bpp_highres; break; @@ -1104,6 +1111,7 @@ static void mystique_recalc_mapping(mystique_t *mystique) { svga_t *svga = &mystique->svga; + xga_t *xga = (xga_t *) svga->xga; io_removehandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); if ((mystique->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) && (mystique->pci_regs[0x41] & 1)) @@ -1141,6 +1149,10 @@ mystique_recalc_mapping(mystique_t *mystique) case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) { + xga->on = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + } break; case 0x8: /*32k at B0000*/ mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index ce44ef890..3ea935b06 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -30,6 +30,7 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #include <86box/plat_unused.h> +#include "cpu.h" #define BIOS_037C_PATH "roms/video/oti/bios.bin" #define BIOS_067_AMA932J_PATH "roms/machines/ama932j/OTI067.BIN" @@ -38,13 +39,13 @@ #define BIOS_077_PATH "roms/video/oti/oti077.vbi" #define BIOS_077_ACER100T_PATH "roms/machines/acer100t/oti077_acer100t.BIN" - enum { - OTI_037C = 0, - OTI_067 = 2, - OTI_067_AMA932J = 3, - OTI_067_M300 = 4, - OTI_077 = 5, + OTI_037C = 0, + OTI_037_PBL300SX = 1, + OTI_067 = 2, + OTI_067_AMA932J = 3, + OTI_067_M300 = 4, + OTI_077 = 5, OTI_077_ACER100T = 6 }; @@ -54,6 +55,7 @@ typedef struct { rom_t bios_rom; int index; + int en_map; uint8_t regs[32]; uint8_t chip_id; @@ -76,16 +78,23 @@ oti_out(uint16_t addr, uint8_t val, void *priv) uint8_t idx; uint8_t enable; - if (!oti->chip_id && !(oti->enable_register & 1) && (addr != 0x3C3)) + if (!oti->chip_id && !(oti->enable_register & 1) && (addr != 0x3c3)) return; - if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + if (((((addr & 0xfff0) == 0x3d0) || ((addr & 0xfff0) == 0x3b0)) && (addr < 0x3de)) && + !(svga->miscout & 1)) addr ^= 0x60; switch (addr) { - case 0x3C3: + case 0x3c3: if (!oti->chip_id) { oti->enable_register = val & 1; + if ((val & 0x01) && oti->en_map) + mem_mapping_enable(&svga->mapping); + else if (!(val & 0x01)) { + oti->en_map = svga->mapping.enable; + mem_mapping_disable(&svga->mapping); + } return; } svga_out(addr, val, svga); @@ -95,20 +104,20 @@ oti_out(uint16_t addr, uint8_t val, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: - if (oti->chip_id == OTI_077 || oti->chip_id == OTI_077_ACER100T) + if ((oti->chip_id == OTI_077) || (oti->chip_id == OTI_077_ACER100T)) sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); else svga_out(addr, val, svga); return; - case 0x3D4: + case 0x3d4: if (oti->chip_id) svga->crtcreg = val & 0x3f; else svga->crtcreg = val; /* FIXME: The BIOS wants to set the test bit? */ return; - case 0x3D5: + case 0x3d5: if (oti->chip_id && (svga->crtcreg & 0x20)) return; idx = svga->crtcreg; @@ -124,7 +133,8 @@ oti_out(uint16_t addr, uint8_t val, void *priv) if ((idx < 0x0e) || (idx > 0x10)) { if (idx == 0x0c || idx == 0x0d) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -133,14 +143,14 @@ oti_out(uint16_t addr, uint8_t val, void *priv) } break; - case 0x3DE: + case 0x3de: if (oti->chip_id) oti->index = val & 0x1f; else oti->index = val; return; - case 0x3DF: + case 0x3df: idx = oti->index; if (!oti->chip_id) idx &= 0x1f; @@ -223,14 +233,14 @@ oti_in(uint16_t addr, void *priv) addr ^= 0x60; switch (addr) { - case 0x3C2: + case 0x3c2: if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) temp = 0; else temp = 0x10; break; - case 0x3C3: + case 0x3c3: if (oti->chip_id) temp = svga_in(addr, svga); else @@ -242,17 +252,20 @@ oti_in(uint16_t addr, void *priv) case 0x3c8: case 0x3c9: if (oti->chip_id == OTI_077 || oti->chip_id == OTI_077_ACER100T) - return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); - return svga_in(addr, svga); + temp = sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); + else + temp = svga_in(addr, svga); + break; case 0x3CF: - return svga->gdcreg[svga->gdcaddr & 0xf]; + temp = svga->gdcreg[svga->gdcaddr & 0xf]; + break; - case 0x3D4: + case 0x3d4: temp = svga->crtcreg; break; - case 0x3D5: + case 0x3d5: if (oti->chip_id) { if (svga->crtcreg & 0x20) temp = 0xff; @@ -262,17 +275,19 @@ oti_in(uint16_t addr, void *priv) temp = svga->crtc[svga->crtcreg & 0x1f]; break; - case 0x3DA: + case 0x3da: if (oti->chip_id) { temp = svga_in(addr, svga); break; } svga->attrff = 0; - /*The OTI-037C BIOS waits for bits 0 and 3 in 0x3da to go low, then reads 0x3da again - and expects the diagnostic bits to equal the current border colour. As I understand - it, the 0x3da active enable status does not include the border time, so this may be - an area where OTI-037C is not entirely VGA compatible.*/ + /* + The OTI-037C BIOS waits for bits 0 and 3 in 0x3da to go low, then reads 0x3da again + and expects the diagnostic bits to equal the current border colour. As I understand + it, the 0x3da active enable status does not include the border time, so this may be + an area where OTI-037C is not entirely VGA compatible. + */ svga->cgastat &= ~0x30; /* copy color diagnostic info from the overscan color register */ switch (svga->attrregs[0x12] & 0x30) { @@ -307,13 +322,13 @@ oti_in(uint16_t addr, void *priv) temp = svga->cgastat; break; - case 0x3DE: + case 0x3de: temp = oti->index; if (oti->chip_id) temp |= (oti->chip_id << 5); break; - case 0x3DF: + case 0x3df: idx = oti->index; if (!oti->chip_id) idx &= 0x1f; @@ -393,9 +408,9 @@ oti_recalctimings(svga_t *svga) if (oti->chip_id > 0) { if (oti->regs[0x14] & 0x08) - svga->ma_latch |= 0x10000; + svga->memaddr_latch |= 0x10000; if (oti->regs[0x16] & 0x08) - svga->ma_latch |= 0x20000; + svga->memaddr_latch |= 0x20000; if (oti->regs[0x14] & 0x01) svga->vtotal += 0x400; @@ -441,6 +456,13 @@ oti_init(const device_t *info) #endif break; + case OTI_037_PBL300SX: + romfn = NULL; + oti->chip_id = 0; + oti->vram_size = 256; + oti->regs[0] = 0x08; /* FIXME: The BIOS wants to read this at index 0? This index is undocumented. */ + break; + case OTI_067_AMA932J: romfn = BIOS_067_AMA932J_PATH; oti->chip_id = 2; @@ -478,26 +500,25 @@ oti_init(const device_t *info) break; } - if (romfn != NULL) { + if (romfn != NULL) rom_init(&oti->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - } oti->vram_mask = (oti->vram_size << 10) - 1; - if (oti->chip_id == OTI_077_ACER100T){ - /* josephillips: Required to show all BIOS - information on Acer 100T only + if (oti->chip_id == OTI_077_ACER100T) { + /* + josephillips: Required to show all BIOS + information on Acer 100T only */ - video_inform(0x1,&timing_oti); - }else{ + video_inform(0x1, &timing_oti); + } else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_oti); - } svga_init(info, &oti->svga, oti, oti->vram_size << 10, oti_recalctimings, oti_in, oti_out, NULL, NULL); - if (oti->chip_id == OTI_077 || oti->chip_id == OTI_077_ACER100T) + if ((oti->chip_id == OTI_077) || (oti->chip_id == OTI_077_ACER100T)) oti->svga.ramdac = device_add(&sc11487_ramdac_device); /*Actually a 82c487, probably a clone.*/ io_sethandler(0x03c0, 32, @@ -662,6 +683,20 @@ const device_t oti037c_device = { .config = NULL }; +const device_t oti037_pbl300sx_device = { + .name = "Oak OTI-037 (Packard Bell Legend 300SX)", + .internal_name = "oti037_pbl300sx", + .flags = DEVICE_ISA, + .local = 1, + .init = oti_init, + .close = oti_close, + .reset = NULL, + .available = NULL, + .speed_changed = oti_speed_changed, + .force_redraw = oti_force_redraw, + .config = NULL +}; + const device_t oti067_device = { .name = "Oak OTI-067", .internal_name = "oti067", @@ -676,20 +711,6 @@ const device_t oti067_device = { .config = oti067_config }; -const device_t oti067_m300_device = { - .name = "Oak OTI-067 (Olivetti M300-08/15)", - .internal_name = "oti067_m300", - .flags = DEVICE_ISA, - .local = 4, - .init = oti_init, - .close = oti_close, - .reset = NULL, - .available = oti067_m300_available, - .speed_changed = oti_speed_changed, - .force_redraw = oti_force_redraw, - .config = oti067_config -}; - const device_t oti067_ama932j_device = { .name = "Oak OTI-067 (AMA-932J)", .internal_name = "oti067_ama932j", @@ -704,21 +725,20 @@ const device_t oti067_ama932j_device = { .config = oti067_ama932j_config }; -const device_t oti077_acer100t_device = { - .name = "Oak OTI-077 (Acer 100T)", - .internal_name = "oti077_acer100t", +const device_t oti067_m300_device = { + .name = "Oak OTI-067 (Olivetti M300-08/15)", + .internal_name = "oti067_m300", .flags = DEVICE_ISA, - .local = 6, + .local = 4, .init = oti_init, .close = oti_close, .reset = NULL, - .available = oti077_acer100t_available, + .available = oti067_m300_available, .speed_changed = oti_speed_changed, .force_redraw = oti_force_redraw, - .config = oti077_acer100t_config + .config = oti067_config }; - const device_t oti077_device = { .name = "Oak OTI-077", .internal_name = "oti077", @@ -732,3 +752,17 @@ const device_t oti077_device = { .force_redraw = oti_force_redraw, .config = oti077_config }; + +const device_t oti077_acer100t_device = { + .name = "Oak OTI-077 (Acer 100T)", + .internal_name = "oti077_acer100t", + .flags = DEVICE_ISA, + .local = 6, + .init = oti_init, + .close = oti_close, + .reset = NULL, + .available = oti077_acer100t_available, + .speed_changed = oti_speed_changed, + .force_redraw = oti_force_redraw, + .config = oti077_acer100t_config +}; diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index da8bb9aa6..ff1013232 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -30,9 +30,18 @@ #include <86box/rom.h> #include <86box/device.h> #include <86box/video.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#define VAR_BYTE_MODE (0 << 0) +#define VAR_WORD_MODE_MA13 (1 << 0) +#define VAR_WORD_MODE_MA15 (2 << 0) +#define VAR_DWORD_MODE (3 << 0) +#define VAR_MODE_MASK (3 << 0) +#define VAR_ROW0_MA13 (1 << 2) +#define VAR_ROW1_MA14 (1 << 3) + typedef struct paradise_t { svga_t svga; @@ -77,6 +86,7 @@ paradise_in(uint16_t addr, void *priv) { paradise_t *paradise = (paradise_t *) priv; svga_t *svga = ¶dise->svga; + uint8_t max_sr = (paradise->type >= WD90C30) ? 0x15 : 0x12; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -86,7 +96,7 @@ paradise_in(uint16_t addr, void *priv) if (svga->seqaddr > 7) { if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) return 0xff; - if (svga->seqaddr > 0x12) + if (svga->seqaddr > max_sr) return 0xff; return svga->seqregs[svga->seqaddr & 0x1f]; } @@ -134,6 +144,7 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) { paradise_t *paradise = (paradise_t *) priv; svga_t *svga = ¶dise->svga; + xga_t *xga = (xga_t *) svga->xga; uint8_t old; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) @@ -179,6 +190,10 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) { + xga->on = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + } break; case 0x8: /*32k at B0000*/ mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); @@ -212,6 +227,20 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) else svga->gdcreg[0x0b] |= 0x40; + if (svga->crtc[0x2f] & 0x02) + svga->decode_mask = 0x3ffff; + else switch (svga->gdcreg[0x0b] & 0xc0) { + case 0x00: case 0x40: + svga->decode_mask = 0x3ffff; + break; + case 0x80: + svga->decode_mask = 0x7ffff; + break; + case 0xc0: + svga->decode_mask = 0xfffff; + break; + } + paradise_remap(paradise); return; case 0x0e: @@ -243,9 +272,24 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) if (old != val) { if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if (svga->crtcreg == 0x2f) { + if (svga->crtc[0x2f] & 0x02) + svga->decode_mask = 0x3ffff; + else switch (svga->gdcreg[0x0b] & 0xc0) { + case 0x00: case 0x40: + svga->decode_mask = 0x3ffff; + break; + case 0x80: + svga->decode_mask = 0x7ffff; + break; + case 0xc0: + svga->decode_mask = 0xfffff; + break; + } + } if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -267,30 +311,92 @@ paradise_remap(paradise_t *paradise) svga_t *svga = ¶dise->svga; if (svga->seqregs[0x11] & 0x80) { - paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[9] << 12; - paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[0x0a] << 12; - paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[0x0a] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } else if (svga->gdcreg[0x0b] & 0x08) { - if (svga->gdcreg[6] & 0x0c) { - paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[0x0a] << 12; - paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[0x0a] << 12; - paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } else { - paradise->read_bank[0] = paradise->write_bank[0] = svga->gdcreg[0x0a] << 12; - paradise->read_bank[1] = paradise->write_bank[1] = (svga->gdcreg[0xa] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->read_bank[2] = paradise->write_bank[2] = svga->gdcreg[9] << 12; - paradise->read_bank[3] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } - } else { - paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[9] << 12; - paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[9] << 12; - paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } + paradise->read_bank[0] = svga->gdcreg[9] << 12; + paradise->read_bank[1] = paradise->read_bank[0] + 0x8000; - /*There are separate drivers for 1M and 512K/256K versions of the PVGA chips.*/ + paradise->write_bank[0] = svga->gdcreg[0x0a] << 12; + paradise->write_bank[1] = paradise->write_bank[0] + 0x8000; + + if ((svga->gdcreg[6] & 0x0c) == 0x00) { + paradise->read_bank[2] = paradise->read_bank[1] + 0x8000; + paradise->read_bank[3] = paradise->read_bank[2] + 0x8000; + + paradise->write_bank[2] = paradise->write_bank[1] + 0x8000; + paradise->write_bank[3] = paradise->write_bank[2] + 0x8000; + } else { + if (svga->gdcreg[6] & 0x08) { + paradise->read_bank[1] = paradise->read_bank[0]; + + paradise->write_bank[1] = paradise->write_bank[0]; + } + + paradise->read_bank[2] = paradise->read_bank[0]; + paradise->read_bank[3] = paradise->read_bank[1]; + + paradise->write_bank[2] = paradise->write_bank[0]; + paradise->write_bank[3] = paradise->write_bank[1]; + } + } else if (svga->gdcreg[0x0b] & 0x08) { + if ((svga->gdcreg[6] & 0x0c) == 0x00) { + paradise->read_bank[0] = svga->gdcreg[0x0a] << 12; + paradise->read_bank[1] = paradise->read_bank[0] + 0x8000; + paradise->read_bank[2] = svga->gdcreg[9] << 12; + paradise->read_bank[3] = paradise->read_bank[2] + 0x8000; + + paradise->write_bank[0] = svga->gdcreg[0x0a] << 12; + paradise->write_bank[1] = paradise->write_bank[0] + 0x8000; + paradise->write_bank[2] = svga->gdcreg[9] << 12; + paradise->write_bank[3] = paradise->write_bank[2] + 0x8000; + } else if ((svga->gdcreg[6] & 0x0c) == 0x04) { + paradise->read_bank[0] = svga->gdcreg[0x0a] << 12; + paradise->read_bank[1] = (svga->gdcreg[9] << 12) + 0x8000; + paradise->read_bank[2] = paradise->read_bank[0]; + paradise->read_bank[3] = paradise->read_bank[1]; + + paradise->write_bank[0] = svga->gdcreg[0x0a] << 12; + paradise->write_bank[1] = (svga->gdcreg[9] << 12) + 0x8000; + paradise->write_bank[2] = paradise->write_bank[0]; + paradise->write_bank[3] = paradise->write_bank[1]; + } else { + paradise->read_bank[0] = svga->gdcreg[0x0a] << 12; + paradise->read_bank[1] = paradise->read_bank[0]; + paradise->read_bank[2] = paradise->read_bank[0]; + paradise->read_bank[3] = paradise->read_bank[0]; + + paradise->write_bank[0] = svga->gdcreg[0x0a] << 12; + paradise->write_bank[1] = paradise->write_bank[0]; + paradise->write_bank[2] = paradise->write_bank[0]; + paradise->write_bank[3] = paradise->write_bank[0]; + } + } else { + paradise->read_bank[0] = svga->gdcreg[9] << 12; + paradise->read_bank[1] = paradise->read_bank[0] + 0x8000; + + paradise->write_bank[0] = svga->gdcreg[9] << 12; + paradise->write_bank[1] = paradise->write_bank[0] + 0x8000; + + if ((svga->gdcreg[6] & 0x0c) == 0x00) { + paradise->read_bank[2] = paradise->read_bank[1] + 0x8000; + paradise->read_bank[3] = paradise->read_bank[2] + 0x8000; + + paradise->write_bank[2] = paradise->write_bank[1] + 0x8000; + paradise->write_bank[3] = paradise->write_bank[2] + 0x8000; + } else { + if (svga->gdcreg[6] & 0x08) { + paradise->read_bank[1] = paradise->read_bank[0]; + + paradise->write_bank[1] = paradise->write_bank[0]; + } + + paradise->read_bank[2] = paradise->read_bank[0]; + paradise->read_bank[3] = paradise->read_bank[1]; + + paradise->write_bank[2] = paradise->write_bank[0]; + paradise->write_bank[3] = paradise->write_bank[1]; + } + } + + /* There are separate drivers for 1M and 512K/256K versions of the PVGA chips. */ if ((svga->gdcreg[0x0b] & 0xc0) < 0xc0) { paradise->read_bank[1] &= 0x7ffff; paradise->write_bank[1] &= 0x7ffff; @@ -300,6 +406,85 @@ paradise_remap(paradise_t *paradise) } } +void +paradise_render_4bpp_word_highres(svga_t *svga) +{ + 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; + + changed_addr = ((svga->memaddr & 0x3fffc) << 1); + + 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->memaddr & 0x3fffc) << 1); + oddeven = 0; + + oddeven = (svga->memaddr & 2) ? 1 : 0; + *(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr | oddeven]) & 0x00ff00ff; + svga->memaddr = (svga->memaddr + 2) & 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; + } + } +} + +static int +paradise_mode_is_word(svga_t *svga) +{ + int func_nr; + + if (svga->fb_only) + func_nr = 0; + else { + if (svga->force_dword_mode) + func_nr = VAR_DWORD_MODE; + else if (svga->crtc[0x14] & 0x40) + func_nr = svga->packed_chain4 ? VAR_BYTE_MODE : VAR_DWORD_MODE; + else if (svga->crtc[0x17] & 0x40) + func_nr = VAR_BYTE_MODE; + else if (svga->crtc[0x17] & 0x20) + func_nr = VAR_WORD_MODE_MA15; + else + func_nr = VAR_WORD_MODE_MA13; + + if (!(svga->crtc[0x17] & 0x01)) + func_nr |= VAR_ROW0_MA13; + if (!(svga->crtc[0x17] & 0x02)) + func_nr |= VAR_ROW1_MA14; + } + + return (func_nr == 2); +} + void paradise_recalctimings(svga_t *svga) { @@ -318,17 +503,30 @@ paradise_recalctimings(svga_t *svga) svga->vblankstart |= 0x400; if (svga->crtc[0x3e] & 0x10) svga->split |= 0x400; - - svga->interlace = !!(svga->crtc[0x2d] & 0x20); } + if (paradise->type >= WD90C11) + svga->interlace = !!(svga->crtc[0x2d] & 0x20); + if (paradise->type < WD90C30) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { if ((svga->bpp >= 8) && !svga->lowres) { svga->render = svga_render_8bpp_highres; - svga->vram_display_mask = (svga->crtc[0x2f] & 0x02) ? 0x3ffff : paradise->vram_mask; + if (paradise->type < WD90C11) + svga->vram_display_mask = (svga->crtc[0x2f] & 0x02) ? 0x3ffff : paradise->vram_mask; } } + if (paradise->type >= WD90C11) switch (svga->crtc[0x2f] & 0x60) { + case 0x60: case 0x40: + svga->vram_display_mask = 0x3ffff; + break; + case 0x20: + svga->vram_display_mask = 0x7ffff; + break; + case 0x00: + svga->vram_display_mask = 0xfffff; + break; + } } else { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { if ((svga->bpp >= 8) && !svga->lowres) { @@ -352,6 +550,51 @@ paradise_recalctimings(svga_t *svga) a windowed DOS box in Win3.x*/ } } + + /* + Yes, this is basically hack but I'm going to look at a proper rewrite in + 86Box 6.0. + */ + if ((paradise->type == WD90C11) && (svga->hdisp == 1024) && + (svga->render == svga_render_4bpp_highres) && paradise_mode_is_word(svga)) + svga->render = paradise_render_4bpp_word_highres; +} + +uint32_t +paradise_decode_addr(paradise_t *paradise, uint32_t addr, int write) +{ + svga_t *svga = ¶dise->svga; + 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 (write) + addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; + else + addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; + + + return addr; } static void @@ -362,7 +605,9 @@ paradise_write(uint32_t addr, uint8_t val, void *priv) uint32_t prev_addr; uint32_t prev_addr2; - addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; + addr = paradise_decode_addr(paradise, addr, 1); + if (addr == 0xffffffff) + return; /*Could be done in a better way but it works.*/ if (!svga->lowres || (svga->attrregs[0x10] & 0x40)) { @@ -395,7 +640,9 @@ paradise_writew(uint32_t addr, uint16_t val, void *priv) uint32_t prev_addr; uint32_t prev_addr2; - addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; + addr = paradise_decode_addr(paradise, addr, 1); + if (addr == 0xffffffff) + return; /*Could be done in a better way but it works.*/ if (!svga->lowres || (svga->attrregs[0x10] & 0x40)) { @@ -428,7 +675,9 @@ paradise_read(uint32_t addr, void *priv) uint32_t prev_addr; uint32_t prev_addr2; - addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; + addr = paradise_decode_addr(paradise, addr, 0); + if (addr == 0xffffffff) + return 0xff; /*Could be done in a better way but it works.*/ if (!svga->lowres || (svga->attrregs[0x10] & 0x40)) { @@ -461,7 +710,9 @@ paradise_readw(uint32_t addr, void *priv) uint32_t prev_addr; uint32_t prev_addr2; - addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; + addr = paradise_decode_addr(paradise, addr, 0); + if (addr == 0xffffffff) + return 0xffff; /*Could be done in a better way but it works.*/ if (!svga->lowres || (svga->attrregs[0x10] & 0x40)) { diff --git a/src/video/vid_pcjr.c b/src/video/vid_pcjr.c new file mode 100644 index 000000000..b4a2d24db --- /dev/null +++ b/src/video/vid_pcjr.c @@ -0,0 +1,722 @@ +/* + * 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. + * + * IBM PCjr video subsystem emulation + * + * + * Authors: Sarah Walker, + * Miran Grca, + * Connor Hyde / starfrost + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2025 starfrost + */ + +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/mem.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/video.h> +#include <86box/vid_cga.h> +#include <86box/vid_cga_comp.h> +#include <86box/plat_unused.h> +#include "cpu.h" + +#include <86box/m_pcjr.h> + +static video_timings_t timing_dram = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*No additional waitstates*/ + +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 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[(masked_memctrl & 0x06) << 14]; + pcjr->b8000 = &ram[(masked_memctrl & 0x30) << 11]; + } else { + pcjr->vram = &ram[(masked_memctrl & 0x07) << 14]; + pcjr->b8000 = &ram[(masked_memctrl & 0x38) << 11]; + } +} + +void +pcjr_recalc_timings(pcjr_t *pcjr) +{ + double _dispontime; + double _dispofftime; + double disptime; + + if (pcjr->array[0] & 1) { + disptime = pcjr->crtc[0] + 1; + _dispontime = pcjr->crtc[1]; + } else { + disptime = (pcjr->crtc[0] + 1) << 1; + _dispontime = pcjr->crtc[1] << 1; + } + + _dispofftime = disptime - _dispontime; + _dispontime *= CGACONST; + _dispofftime *= CGACONST; + pcjr->dispontime = (uint64_t) (_dispontime); + pcjr->dispofftime = (uint64_t) (_dispofftime); +} + +static int +vid_get_h_overscan_size(pcjr_t *pcjr) +{ + int ret; + + if (pcjr->array[0] & 1) + ret = 128; + else + ret = 256; + + return ret; +} + +static void +vid_out(uint16_t addr, uint8_t val, void *priv) +{ + pcjr_t *pcjr = (pcjr_t *) priv; + uint8_t old; + + switch (addr) { + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + pcjr->crtcreg = val & 0x1f; + return; + + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + old = pcjr->crtc[pcjr->crtcreg]; + pcjr->crtc[pcjr->crtcreg] = val & crtcmask[pcjr->crtcreg]; + if (pcjr->crtcreg == 2) + overscan_x = vid_get_h_overscan_size(pcjr); + if (old != val) { + if (pcjr->crtcreg < 0xe || pcjr->crtcreg > 0x10) { + pcjr->fullchange = changeframecount; + pcjr_recalc_timings(pcjr); + } + } + return; + + case 0x3da: + if (!pcjr->array_ff) + pcjr->array_index = val & 0x1f; + else { + if (pcjr->array_index & 0x10) + val &= 0x0f; + pcjr->array[pcjr->array_index & 0x1f] = val; + if (!(pcjr->array_index & 0x1f)) + update_cga16_color(val); + } + pcjr->array_ff = !pcjr->array_ff; + break; + + case 0x3df: + pcjr->memctrl = val; + pcjr->pa = val; /* The PCjr BIOS expects the value written to 3DF to + then be readable from port 60, others it errors out + with only 64k RAM set (but somehow, still works with + 128k or more RAM). */ + pcjr->addr_mode = val >> 6; + recalc_address(pcjr); + break; + + default: + break; + } +} + +static uint8_t +vid_in(uint16_t addr, void *priv) +{ + pcjr_t *pcjr = (pcjr_t *) priv; + uint8_t ret = 0xff; + + switch (addr) { + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + ret = pcjr->crtcreg; + break; + + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + ret = pcjr->crtc[pcjr->crtcreg]; + break; + + case 0x3da: + pcjr->array_ff = 0; + pcjr->status ^= 0x10; + ret = pcjr->status; + break; + + default: + break; + } + + return ret; +} + +void +pcjr_waitstates(UNUSED(void *priv)) +{ + int ws_array[16] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5 }; + int ws; + + ws = ws_array[cycles & 0xf]; + cycles -= ws; +} + +static void +vid_write(uint32_t addr, uint8_t val, void *priv) +{ + pcjr_t *pcjr = (pcjr_t *) priv; + + if (pcjr->memctrl == -1) + return; + + pcjr_waitstates(NULL); + + pcjr->b8000[addr & 0x3fff] = val; +} + +static uint8_t +vid_read(uint32_t addr, void *priv) +{ + const pcjr_t *pcjr = (pcjr_t *) priv; + + if (pcjr->memctrl == -1) + return 0xff; + + pcjr_waitstates(NULL); + + return (pcjr->b8000[addr & 0x3fff]); +} + +static int +vid_get_h_overscan_delta(pcjr_t *pcjr) +{ + int def; + int coef; + int ret; + + switch ((pcjr->array[0] & 0x13) | ((pcjr->array[3] & 0x08) << 5)) { + case 0x13: /*320x200x16*/ + def = 0x56; + coef = 8; + break; + case 0x12: /*160x200x16*/ + def = 0x2c; /* I'm going to assume a datasheet erratum here. */ + coef = 16; + break; + case 0x03: /*640x200x4*/ + def = 0x56; + coef = 8; + break; + case 0x01: /*80 column text*/ + def = 0x5a; + coef = 8; + break; + case 0x00: /*40 column text*/ + default: + def = 0x2c; + coef = 16; + break; + case 0x02: /*320x200x4*/ + def = 0x2b; + coef = 16; + break; + case 0x102: /*640x200x2*/ + def = 0x2b; + coef = 16; + break; + } + + ret = pcjr->crtc[0x02] - def; + + if (ret < -8) + ret = -8; + + if (ret > 8) + ret = 8; + + return ret * coef; +} + +static void +vid_blit_h_overscan(pcjr_t *pcjr) +{ + int cols = (pcjr->array[2] & 0xf) + 16;; + int y0 = pcjr->firstline << 1; + int y = (pcjr->lastline << 1) + 16; + int ho_s = vid_get_h_overscan_size(pcjr); + int i; + int x; + + if (pcjr->array[0] & 1) + x = (pcjr->crtc[1] << 3) + ho_s; + else + x = (pcjr->crtc[1] << 4) + ho_s; + + for (i = 0; i < 16; i++) { + hline(buffer32, 0, y0 + i, x, cols); + hline(buffer32, 0, y + i, x, cols); + + if (pcjr->composite) { + Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[y0 + i]); + Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[y + i]); + } else { + video_process_8(x, y0 + i); + video_process_8(x, y + i); + } + } +} + +static void +vid_poll(void *priv) +{ + pcjr_t *pcjr = (pcjr_t *) priv; + uint16_t cursoraddr = (pcjr->crtc[15] | (pcjr->crtc[14] << 8)) & 0x3fff; + int drawcursor; + int x; + int xs_temp; + int ys_temp; + int oldvc; + uint8_t chr; + uint8_t attr; + uint16_t dat; + int cols[4]; + int scanline_old; + int l = (pcjr->displine << 1) + 16; + int ho_s = vid_get_h_overscan_size(pcjr); + int ho_d = vid_get_h_overscan_delta(pcjr) + (ho_s / 2); + + if (!pcjr->linepos) { + timer_advance_u64(&pcjr->timer, pcjr->dispofftime); + pcjr->status &= ~1; + pcjr->linepos = 1; + scanline_old = pcjr->scanline; + if ((pcjr->crtc[8] & 3) == 3) + pcjr->scanline = (pcjr->scanline << 1) & 7; + if (pcjr->dispon) { + uint16_t offset = 0; + uint16_t mask = 0x1fff; + + if (pcjr->displine < pcjr->firstline) { + pcjr->firstline = pcjr->displine; + video_wait_for_buffer(); + } + pcjr->lastline = pcjr->displine; + cols[0] = (pcjr->array[2] & 0xf) + 16; + + if (pcjr->array[0] & 1) { + hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, cols[0]); + hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, cols[0]); + } else { + hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, cols[0]); + hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, cols[0]); + } + + switch (pcjr->addr_mode) { + case 0: /*Alpha*/ + offset = 0; + mask = 0x3fff; + break; + case 1: /*Low resolution graphics*/ + offset = (pcjr->scanline & 1) * 0x2000; + break; + case 3: /*High resolution graphics*/ + offset = (pcjr->scanline & 3) * 0x2000; + break; + default: + break; + } + switch ((pcjr->array[0] & 0x13) | ((pcjr->array[3] & 0x08) << 5)) { + case 0x13: /*320x200x16*/ + for (x = 0; x < pcjr->crtc[1]; x++) { + int ef_x = (x << 3) + ho_d; + dat = (pcjr->vram[((pcjr->memaddr << 1) & mask) + offset] << 8) | + pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1]; + pcjr->memaddr++; + buffer32->line[l][ef_x] = buffer32->line[l][ef_x + 1] = + buffer32->line[l + 1][ef_x] = buffer32->line[l + 1][ef_x + 1] = + pcjr->array[((dat >> 12) & pcjr->array[1] & 0x0f) + 16] + 16; + buffer32->line[l][ef_x + 2] = buffer32->line[l][ef_x + 3] = + buffer32->line[l + 1][ef_x + 2] = buffer32->line[l + 1][ef_x + 3] = + pcjr->array[((dat >> 8) & pcjr->array[1] & 0x0f) + 16] + 16; + buffer32->line[l][ef_x + 4] = buffer32->line[l][ef_x + 5] = + buffer32->line[l + 1][ef_x + 4] = buffer32->line[l + 1][ef_x + 5] = + pcjr->array[((dat >> 4) & pcjr->array[1] & 0x0f) + 16] + 16; + buffer32->line[l][ef_x + 6] = buffer32->line[l][ef_x + 7] = + buffer32->line[l + 1][ef_x + 6] = buffer32->line[l + 1][ef_x + 7] = + pcjr->array[(dat & pcjr->array[1] & 0x0f) + 16] + 16; + } + break; + case 0x12: /*160x200x16*/ + for (x = 0; x < pcjr->crtc[1]; x++) { + int ef_x = (x << 4) + ho_d; + dat = (pcjr->vram[((pcjr->memaddr << 1) & mask) + offset] << 8) | + pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1]; + pcjr->memaddr++; + buffer32->line[l][ef_x] = buffer32->line[l][ef_x + 1] = + buffer32->line[l][ef_x + 2] = buffer32->line[l][ef_x + 3] = + buffer32->line[l + 1][ef_x] = buffer32->line[l + 1][ef_x + 1] = + buffer32->line[l + 1][ef_x + 2] = buffer32->line[l + 1][ef_x + 3] = + pcjr->array[((dat >> 12) & pcjr->array[1] & 0x0f) + 16] + 16; + buffer32->line[l][ef_x + 4] = buffer32->line[l][ef_x + 5] = + buffer32->line[l][ef_x + 6] = buffer32->line[l][ef_x + 7] = + buffer32->line[l + 1][ef_x + 4] = buffer32->line[l + 1][ef_x + 5] = + buffer32->line[l + 1][ef_x + 6] = buffer32->line[l + 1][ef_x + 7] = + pcjr->array[((dat >> 8) & pcjr->array[1] & 0x0f) + 16] + 16; + buffer32->line[l][ef_x + 8] = buffer32->line[l][ef_x + 9] = + buffer32->line[l][ef_x + 10] = buffer32->line[l][ef_x + 11] = + buffer32->line[l + 1][ef_x + 8] = buffer32->line[l + 1][ef_x + 9] = + buffer32->line[l + 1][ef_x + 10] = buffer32->line[l + 1][ef_x + 11] = + pcjr->array[((dat >> 4) & pcjr->array[1] & 0x0f) + 16] + 16; + buffer32->line[l][ef_x + 12] = buffer32->line[l][ef_x + 13] = + buffer32->line[l][ef_x + 14] = buffer32->line[l][ef_x + 15] = + buffer32->line[l + 1][ef_x + 12] = buffer32->line[l + 1][ef_x + 13] = + buffer32->line[l + 1][ef_x + 14] = buffer32->line[l + 1][ef_x + 15] = + pcjr->array[(dat & pcjr->array[1] & 0x0f) + 16] + 16; + } + break; + case 0x03: /*640x200x4*/ + for (x = 0; x < pcjr->crtc[1]; x++) { + int ef_x = (x << 3) + ho_d; + dat = (pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1] << 8) | + pcjr->vram[((pcjr->memaddr << 1) & mask) + offset]; + pcjr->memaddr++; + for (uint8_t c = 0; c < 8; c++) { + chr = (dat >> 7) & 1; + chr |= ((dat >> 14) & 2); + buffer32->line[l][ef_x + c] = buffer32->line[l + 1][ef_x + c] = + pcjr->array[(chr & pcjr->array[1] & 0x0f) + 16] + 16; + dat <<= 1; + } + } + break; + case 0x01: /*80 column text*/ + for (x = 0; x < pcjr->crtc[1]; x++) { + int ef_x = (x << 3) + ho_d; + chr = pcjr->vram[((pcjr->memaddr << 1) & mask) + offset]; + attr = pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1]; + drawcursor = ((pcjr->memaddr == cursoraddr) && pcjr->cursorvisible && pcjr->cursoron); + if (pcjr->array[3] & 4) { + cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16; + cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1] & 0x0f) + 16] + 16; + if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16; + cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1] & 0x0f) + 16] + 16; + } + if (pcjr->scanline & 8) + for (uint8_t c = 0; c < 8; c++) + buffer32->line[l][ef_x + c] = + buffer32->line[l + 1][ef_x + c] = cols[0]; + else + for (uint8_t c = 0; c < 8; c++) + buffer32->line[l][ef_x + c] = + buffer32->line[l + 1][ef_x + c] = + cols[(fontdat[chr][pcjr->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0]; + if (drawcursor) + for (uint8_t c = 0; c < 8; c++) { + buffer32->line[l][ef_x + c] ^= 15; + buffer32->line[l + 1][ef_x + c] ^= 15; + } + pcjr->memaddr++; + } + break; + case 0x00: /*40 column text*/ + for (x = 0; x < pcjr->crtc[1]; x++) { + int ef_x = (x << 4) + ho_d; + chr = pcjr->vram[((pcjr->memaddr << 1) & mask) + offset]; + attr = pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1]; + drawcursor = ((pcjr->memaddr == cursoraddr) && pcjr->cursorvisible && pcjr->cursoron); + if (pcjr->array[3] & 4) { + cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16; + cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1] & 0x0f) + 16] + 16; + if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = pcjr->array[((attr & 15) & pcjr->array[1] & 0x0f) + 16] + 16; + cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1] & 0x0f) + 16] + 16; + } + pcjr->memaddr++; + if (pcjr->scanline & 8) + for (uint8_t c = 0; c < 8; c++) + buffer32->line[l][ef_x + (c << 1)] = + buffer32->line[l][ef_x + (c << 1) + 1] = + buffer32->line[l + 1][ef_x + (c << 1)] = + buffer32->line[l + 1][ef_x + (c << 1) + 1] = cols[0]; + else + for (uint8_t c = 0; c < 8; c++) + buffer32->line[l][ef_x + (c << 1)] = + buffer32->line[l][ef_x + (c << 1) + 1] = + buffer32->line[l + 1][ef_x + (c << 1)] = + buffer32->line[l + 1][ef_x + (c << 1) + 1] = + cols[(fontdat[chr][pcjr->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0]; + if (drawcursor) + for (uint8_t c = 0; c < 16; c++) { + buffer32->line[l][ef_x + c] ^= 15; + buffer32->line[l + 1][ef_x + c] ^= 15; + } + } + break; + case 0x02: /*320x200x4*/ + cols[0] = pcjr->array[0 + 16] + 16; + cols[1] = pcjr->array[1 + 16] + 16; + cols[2] = pcjr->array[2 + 16] + 16; + cols[3] = pcjr->array[3 + 16] + 16; + for (x = 0; x < pcjr->crtc[1]; x++) { + int ef_x = (x << 4) + ho_d; + dat = (pcjr->vram[((pcjr->memaddr << 1) & mask) + offset] << 8) | + pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1]; + pcjr->memaddr++; + for (uint8_t c = 0; c < 8; c++) { + buffer32->line[l][ef_x + (c << 1)] = + buffer32->line[l][ef_x + (c << 1) + 1] = + buffer32->line[l + 1][ef_x + (c << 1)] = + buffer32->line[l + 1][ef_x + (c << 1) + 1] = cols[dat >> 14]; + dat <<= 2; + } + } + break; + case 0x102: /*640x200x2*/ + cols[0] = pcjr->array[0 + 16] + 16; + cols[1] = pcjr->array[1 + 16] + 16; + for (x = 0; x < pcjr->crtc[1]; x++) { + int ef_x = (x << 4) + ho_d; + dat = (pcjr->vram[((pcjr->memaddr << 1) & mask) + offset] << 8) | + pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1]; + pcjr->memaddr++; + for (uint8_t c = 0; c < 16; c++) { + buffer32->line[l][ef_x + c] = buffer32->line[l + 1][ef_x + c] = + cols[dat >> 15]; + dat <<= 1; + } + } + break; + + default: + break; + } + } else { + if (pcjr->array[3] & 4) { + if (pcjr->array[0] & 1) { + hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, (pcjr->array[2] & 0xf) + 16); + hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, (pcjr->array[2] & 0xf) + 16); + } else { + hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, (pcjr->array[2] & 0xf) + 16); + hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, (pcjr->array[2] & 0xf) + 16); + } + } else { + cols[0] = pcjr->array[0 + 16] + 16; + if (pcjr->array[0] & 1) { + hline(buffer32, 0, l, (pcjr->crtc[1] << 3) + ho_s, cols[0]); + hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 3) + ho_s, cols[0]); + } else { + hline(buffer32, 0, l, (pcjr->crtc[1] << 4) + ho_s, cols[0]); + hline(buffer32, 0, l + 1, (pcjr->crtc[1] << 4) + ho_s, cols[0]); + } + } + } + if (pcjr->array[0] & 1) + x = (pcjr->crtc[1] << 3) + ho_s; + else + x = (pcjr->crtc[1] << 4) + ho_s; + if (pcjr->composite) { + Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[l]); + Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[l + 1]); + } else { + video_process_8(x, l); + video_process_8(x, l + 1); + } + pcjr->scanline = scanline_old; + if (pcjr->vc == pcjr->crtc[7] && !pcjr->scanline) { + pcjr->status |= 8; + } + pcjr->displine++; + if (pcjr->displine >= 360) + pcjr->displine = 0; + } else { + timer_advance_u64(&pcjr->timer, pcjr->dispontime); + if (pcjr->dispon) + pcjr->status |= 1; + pcjr->linepos = 0; + if (pcjr->vsynctime) { + pcjr->vsynctime--; + if (!pcjr->vsynctime) { + pcjr->status &= ~8; + } + } + if (pcjr->scanline == (pcjr->crtc[11] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->scanline == ((pcjr->crtc[11] & 31) >> 1))) { + pcjr->cursorvisible = 0; + } + if (pcjr->vadj) { + pcjr->scanline++; + pcjr->scanline &= 31; + pcjr->memaddr = pcjr->memaddr_backup; + pcjr->vadj--; + if (!pcjr->vadj) { + pcjr->dispon = 1; + pcjr->memaddr = pcjr->memaddr_backup = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff; + pcjr->scanline = 0; + } + } else if (pcjr->scanline == pcjr->crtc[9] || ((pcjr->crtc[8] & 3) == 3 && pcjr->scanline == (pcjr->crtc[9] >> 1))) { + pcjr->memaddr_backup = pcjr->memaddr; + pcjr->scanline = 0; + oldvc = pcjr->vc; + pcjr->vc++; + pcjr->vc &= 127; + if (pcjr->vc == pcjr->crtc[6]) + pcjr->dispon = 0; + if (oldvc == pcjr->crtc[4]) { + pcjr->vc = 0; + pcjr->vadj = pcjr->crtc[5]; + if (!pcjr->vadj) + pcjr->dispon = 1; + if (!pcjr->vadj) + pcjr->memaddr = pcjr->memaddr_backup = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff; + if ((pcjr->crtc[10] & 0x60) == 0x20) + pcjr->cursoron = 0; + else + pcjr->cursoron = pcjr->blink & 16; + } + if (pcjr->vc == pcjr->crtc[7]) { + pcjr->dispon = 0; + pcjr->displine = 0; + pcjr->vsynctime = 16; + picint(1 << 5); + if (pcjr->crtc[7]) { + if (pcjr->array[0] & 1) + x = (pcjr->crtc[1] << 3) + ho_s; + else + x = (pcjr->crtc[1] << 4) + ho_s; + pcjr->lastline++; + + xs_temp = x; + ys_temp = (pcjr->lastline - pcjr->firstline) << 1; + + if ((xs_temp > 0) && (ys_temp > 0)) { + int actual_ys = ys_temp; + + if (xs_temp < 64) + xs_temp = 656; + if (ys_temp < 32) + ys_temp = 400; + if (!enable_overscan) + xs_temp -= ho_s; + + if ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get()) { + xsize = xs_temp; + ysize = ys_temp; + + set_screen_size(xsize, ysize + (enable_overscan ? 32 : 0)); + + if (video_force_resize_get()) + video_force_resize_set(0); + } + + vid_blit_h_overscan(pcjr); + + if (enable_overscan) { + video_blit_memtoscreen(0, pcjr->firstline << 1, + xsize, actual_ys + 32); + } else if (pcjr->apply_hd) { + video_blit_memtoscreen(ho_s / 2, (pcjr->firstline << 1) + 16, + xsize, actual_ys); + } else { + video_blit_memtoscreen(ho_d, (pcjr->firstline << 1) + 16, + xsize, actual_ys); + } + } + + frames++; + video_res_x = xsize; + video_res_y = ysize; + } + pcjr->firstline = 1000; + pcjr->lastline = 0; + pcjr->blink++; + } + } else { + pcjr->scanline++; + pcjr->scanline &= 31; + pcjr->memaddr = pcjr->memaddr_backup; + } + if (pcjr->scanline == (pcjr->crtc[10] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->scanline == ((pcjr->crtc[10] & 31) >> 1))) + pcjr->cursorvisible = 1; + } +} + + +void +pcjr_vid_init(pcjr_t *pcjr) +{ + int display_type; + + video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram); + + pcjr->memctrl = -1; + if (mem_size < 128) + pcjr->memctrl &= ~0x24; + + display_type = device_get_config_int("display_type"); + pcjr->composite = (display_type == PCJR_COMPOSITE); + pcjr->apply_hd = device_get_config_int("apply_hd"); + overscan_x = 256; + overscan_y = 32; + + mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, + vid_read, NULL, NULL, + vid_write, NULL, NULL, NULL, 0, pcjr); + io_sethandler(0x03d0, 16, + vid_in, NULL, NULL, vid_out, NULL, NULL, pcjr); + timer_add(&pcjr->timer, vid_poll, pcjr, 1); + + if (pcjr->composite) + cga_palette = 0; + else + cga_palette = (display_type << 1); + cgapal_rebuild(); +} diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index 5cb35dc4e..63126955c 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -2342,23 +2342,23 @@ pgc_cga_text(pgc_t *dev, int w) 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; + uint16_t scanline = (dev->displine & 0x0f) % pitch; + uint16_t memaddr = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; + uint16_t cursoraddr = (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; + addr = &dev->cga_vram[((memaddr + ((dev->displine / pitch) * w)) * 2) & 0x3ffe]; + memaddr += (dev->displine / pitch) * w; for (int x = 0; x < w; x++) { chr = *addr++; attr = *addr++; /* Cursor enabled? */ - if (ma == ca && (dev->cgablink & 8) && (dev->mapram[0x3ea] & 0x60) != 0x20) { - drawcursor = ((dev->mapram[0x3ea] & 0x1f) <= (sc >> 1)) && ((dev->mapram[0x3eb] & 0x1f) >= (sc >> 1)); + if (memaddr == cursoraddr && (dev->cgablink & 8) && (dev->mapram[0x3ea] & 0x60) != 0x20) { + drawcursor = ((dev->mapram[0x3ea] & 0x1f) <= (scanline >> 1)) && ((dev->mapram[0x3eb] & 0x1f) >= (scanline >> 1)); } else drawcursor = 0; @@ -2374,9 +2374,9 @@ pgc_cga_text(pgc_t *dev, int w) for (int c = 0; c < cw; c++) { if (drawcursor) - val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f; + val = cols[(fontdatm[chr + dev->fontbase][scanline] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f; else - val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; + val = cols[(fontdatm[chr + dev->fontbase][scanline] & (1 << (c ^ 7))) ? 1 : 0]; if (cw == 8) /* 80x25 CGA text screen. */ buffer32->line[dev->displine][(x * cw) + c] = val; else { /* 40x25 CGA text screen. */ @@ -2385,7 +2385,7 @@ pgc_cga_text(pgc_t *dev, int w) } } - ma++; + memaddr++; } } @@ -2395,7 +2395,7 @@ pgc_cga_gfx40(pgc_t *dev) { uint32_t cols[4]; int col; - uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; + uint16_t memaddr = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; const uint8_t *addr; uint16_t dat; @@ -2422,9 +2422,9 @@ pgc_cga_gfx40(pgc_t *dev) } for (uint8_t x = 0; x < 40; x++) { - addr = &dev->cga_vram[(ma + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff]; + addr = &dev->cga_vram[(memaddr + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff]; dat = (addr[0] << 8) | addr[1]; - dev->ma++; + dev->memaddr++; for (uint8_t c = 0; c < 8; c++) { buffer32->line[dev->displine][(x << 4) + (c << 1)] = buffer32->line[dev->displine][(x << 4) + (c << 1) + 1] = cols[dat >> 14]; dat <<= 2; @@ -2437,7 +2437,7 @@ void pgc_cga_gfx80(pgc_t *dev) { uint32_t cols[2]; - uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; + uint16_t memaddr = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; const uint8_t *addr; uint16_t dat; @@ -2445,9 +2445,9 @@ pgc_cga_gfx80(pgc_t *dev) cols[1] = (dev->mapram[0x3d9] & 15) + 16; for (uint8_t x = 0; x < 40; x++) { - addr = &dev->cga_vram[(ma + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff]; + addr = &dev->cga_vram[(memaddr + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff]; dat = (addr[0] << 8) | addr[1]; - dev->ma++; + dev->memaddr++; for (uint8_t c = 0; c < 16; c++) { buffer32->line[dev->displine][(x << 4) + c] = cols[dat >> 15]; dat <<= 1; diff --git a/src/video/vid_ps55da2.c b/src/video/vid_ps55da2.c index 9a95e6ce6..938e4bf6b 100644 --- a/src/video/vid_ps55da2.c +++ b/src/video/vid_ps55da2.c @@ -310,16 +310,16 @@ typedef struct da2_t { uint8_t fctl[32]; uint16_t crtc[32]; uint16_t crtc_vpreg[128]; - uint8_t crtc_vpsel; + uint8_t crtc_vpsel; uint8_t gdcreg[64]; uint8_t reg3ee[16]; int gdcaddr; uint8_t attrc[0x40]; int attraddr, attrff; int attr_palette_enable; - int outflipflop; - int inflipflop; - int iolatch; + int outflipflop; + int inflipflop; + int iolatch; int ioctladdr; int fctladdr; @@ -349,7 +349,7 @@ typedef struct da2_t { int lowres; int rowcount; double clock; - uint32_t ma_latch, ca_adj; + uint32_t memaddr_latch, ca_adj; uint64_t dispontime, dispofftime; pc_timer_t timer; @@ -358,11 +358,11 @@ typedef struct da2_t { int dispon; int hdisp_on; - uint32_t ma, maback, ca; + uint32_t memaddr, memaddr_backup, cursoraddr; int vc; - int sc; + int scanline; int linepos, vslines, linecountff; - int con, cursoron, blink, blinkconf; + int cursorvisible, cursoron, blink, blinkconf; int scrollcache; int char_width; @@ -385,8 +385,7 @@ typedef struct da2_t { card should not attempt to display anything */ int override; - struct - { + struct { int enable; mem_mapping_t mapping; uint8_t ram[DA2_SIZE_GAIJIRAM]; @@ -435,9 +434,9 @@ typedef struct da2_t { uint32_t mmrdbg_vidaddr; #endif - uint8_t pos_regs[8]; - svga_t *mb_vga; - uint8_t monitorid; + uint8_t pos_regs[8]; + svga_t *mb_vga; + uint8_t monitorid; pc_timer_t timer_vidupd; int old_pos2; @@ -520,7 +519,7 @@ da2_WritePlaneDataWithBitmask(uint32_t destaddr, const uint16_t mask, pixel32 *s da2->changedvram[(DA2_MASK_VRAMPLANE & destaddr) >> 9] = changeframecount; destaddr <<= 3; /* read destination data with big endian order */ - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) writepx[i] = da2_vram_r((destaddr + 24) | i, da2) | (da2_vram_r((destaddr + 16) | i, da2) << 8) | (da2_vram_r((destaddr + 8) | i, da2) << 16) @@ -532,7 +531,7 @@ da2_WritePlaneDataWithBitmask(uint32_t destaddr, const uint16_t mask, pixel32 *s mask32.b[3] = mask32in.b[0]; mask32.b[2] = mask32in.b[1]; mask32.d &= 0xffff0000; - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { if (da2->bitblt.bitshift_destr > 0) srcpx->p8[i] <<= 16 - da2->bitblt.bitshift_destr; // #ifdef ENABLE_DA2_DEBUGBLT @@ -560,7 +559,7 @@ da2_WritePlaneDataWithBitmask(uint32_t destaddr, const uint16_t mask, pixel32 *s break; } } - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { da2_vram_w(destaddr | i, (writepx[i] >> 24) & 0xff, da2); da2_vram_w((destaddr + 8) | i, (writepx[i] >> 16) & 0xff, da2); } @@ -571,7 +570,7 @@ da2_DrawColorWithBitmask(uint32_t destaddr, uint8_t color, uint16_t mask, da2_t { pixel32 srcpx; /* fill data with input color */ - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) srcpx.p8[i] = (color & (1 << i)) ? 0xffffffff : 0; /* read in word */ da2_WritePlaneDataWithBitmask(destaddr, mask, &srcpx, da2); @@ -582,7 +581,7 @@ da2_CopyPlaneDataWithBitmask(uint32_t srcaddr, uint32_t destaddr, uint16_t mask, pixel32 srcpx; srcaddr &= 0xfffffffe; srcaddr <<= 3; - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) srcpx.p8[i] = da2_vram_r((srcaddr + 24) | i, da2) | (da2_vram_r((srcaddr + 16) | i, da2) << 8) | (da2_vram_r((srcaddr + 8) | i, da2) << 16) @@ -592,9 +591,9 @@ da2_CopyPlaneDataWithBitmask(uint32_t srcaddr, uint32_t destaddr, uint16_t mask, } /* get font data for bitblt operation */ static uint32_t -getRAMFont(int32_t code, int line, int x, void *p) +getRAMFont(int32_t code, int line, int x, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; uint32_t font = 0; #ifdef RESERVED_FOR_FUTURE_USE int fline = line - 2; /* Start line of drawing character (line >= 1 AND line < 24 + 1 ) */ @@ -617,8 +616,7 @@ getRAMFont(int32_t code, int line, int x, void *p) font |= da2->mmio.ram[code + 2]; font <<= 8; font |= da2->mmio.ram[code + 3]; - } - else + } else font = 0; return font; } @@ -641,12 +639,12 @@ da2_PutcharWithBitmask(uint32_t codeIBMJ, int width, uint16_t attr, int line, ui uint32_t fontinv; if (width <= 2) { fontinv = ~font; - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { srcpx.p8[i] = (fg & (1 << i)) ? font >> 16 : 0; srcpx.p8[i] |= (bg & (1 << i)) ? fontinv >> 16 : 0; } da2_WritePlaneDataWithBitmask(destaddr, maskl, &srcpx, da2); - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { srcpx.p8[i] = (fg & (1 << i)) ? font : 0; srcpx.p8[i] |= (bg & (1 << i)) ? fontinv : 0; } @@ -654,12 +652,12 @@ da2_PutcharWithBitmask(uint32_t codeIBMJ, int width, uint16_t attr, int line, ui } else { font = (font & 0xfff80000) | ((font & 0x0000ffff) << 3); fontinv = ~font; - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { srcpx.p8[i] = (fg & (1 << i)) ? font >> 16 : 0; srcpx.p8[i] |= (bg & (1 << i)) ? fontinv >> 16 : 0; } da2_WritePlaneDataWithBitmask(destaddr, maskl, &srcpx, da2); - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { srcpx.p8[i] = (fg & (1 << i)) ? font : 0; srcpx.p8[i] |= (bg & (1 << i)) ? fontinv : 0; } @@ -667,7 +665,7 @@ da2_PutcharWithBitmask(uint32_t codeIBMJ, int width, uint16_t attr, int line, ui da2_WritePlaneDataWithBitmask(destaddr + 2, maskr, &srcpx, da2); } else { da2_WritePlaneDataWithBitmask(destaddr + 2, 0xffff, &srcpx, da2); - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { srcpx.p8[i] = (fg & (1 << i)) ? font << 16 : 0; srcpx.p8[i] |= (bg & (1 << i)) ? fontinv << 16 : 0; } @@ -680,8 +678,8 @@ static uint8_t pixel1tohex(uint32_t addr, int index, da2_t *da2) { uint8_t pixeldata = 0; - for (int j = 0; j < 8; j++) { - if (da2_vram_r(((addr << 3) | j) & (1 << (7 - index)), da2)) + for (uint8_t i = 0; i < 8; j++) { + if (da2_vram_r(((addr << 3) | i) & (1 << (7 - index)), da2)) pixeldata++; } return pixeldata; @@ -689,14 +687,14 @@ pixel1tohex(uint32_t addr, int index, da2_t *da2) static void print_pixelbyte(uint32_t addr, da2_t *da2) { - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { pclog("%X", pixel1tohex(addr, i, da2)); } } static void print_bytetobin(uint8_t b) { - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { if (b & 0x80) pclog("1"); else @@ -723,13 +721,13 @@ IBMJtoSJIS(uint16_t knj) knj -= 0x100; if (knj <= 0x1f7d) ; /* do nothing */ - else if (knj >= 0xb700 && knj <= 0xb75f) { + else if (knj >= 0xb700 && knj <= 0xb75f) knj -= 0x90ec; - } else if (knj >= 0xb3f0 && knj <= 0xb67f) { + else if (knj >= 0xb3f0 && knj <= 0xb67f) knj -= 0x906c; - } else if (knj >= 0x8000 && knj <= 0x8183) { + else if (knj >= 0x8000 && knj <= 0x8183) knj -= 0x5524; - } else + else return 0xffff; uint32_t knj1 = knj / 0xBC; uint32_t knj2 = knj - (knj1 * 0xBC); @@ -850,8 +848,7 @@ da2_bitblt_load(da2_t *da2) DOS/V Extension 1040x725 some DBCS uses 0xB0 others 0x90 */ da2->bitblt.destoption = da2->bitblt.reg[0x2F]; - if (da2->bitblt.destoption & 0x10) /* destaddr -= 2, length += 1; */ - { + if (da2->bitblt.destoption & 0x10) { /* destaddr -= 2, length += 1; */ da2->bitblt.destaddr -= 2; da2->bitblt.size_x += 1; da2->bitblt.destpitch -= 2; @@ -892,9 +889,9 @@ da2_bitblt_load(da2_t *da2) da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), da2->bitblt.size_x, da2->bitblt.size_y); #endif - } + /* Draw a line */ - else if (da2->bitblt.reg[0x5] == 0x43) { + } else if (da2->bitblt.reg[0x5] == 0x43) { da2->bitblt.exec = DA2_BLT_CLINE; da2->bitblt.dest_x = (da2->bitblt.reg[0x32] & 0xffff); da2->bitblt.dest_y = (da2->bitblt.reg[0x34] & 0xffff); @@ -922,17 +919,17 @@ da2_bitblt_load(da2_t *da2) da2_log(" ux1=%d,ux2=%d,uy1=%d,uy2=%d\n", (da2->bitblt.reg[0x32] >> 16) & 0x7ff, (da2->bitblt.reg[0x33] >> 16) & 0x7ff, (da2->bitblt.reg[0x34] >> 16) & 0x7ff, (da2->bitblt.reg[0x35] >> 16) & 0x7ff); - } + /* Fill a rectangle (or draw a horizontal / vertical line) */ - else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x40 && da2->bitblt.reg[0x3D] == 0) { + } else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x40 && da2->bitblt.reg[0x3D] == 0) { da2_log("fillrect x=%d, y=%d, w=%d, h=%d, c=%d, 2f=%x, rowcount=%x\n", da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), da2->bitblt.size_x, da2->bitblt.size_y, da2->bitblt.reg[0x0], da2->bitblt.reg[0x2F], da2->rowoffset * 2); da2->bitblt.exec = DA2_BLT_CFILLRECT; da2->bitblt.destaddr += 2; - } + /* Tiling a rectangle ??(transfer tile data multiple times) os/2 only */ - else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x0040 && da2->bitblt.reg[0x3D] == 0x40) { + } else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x0040 && da2->bitblt.reg[0x3D] == 0x40) { da2->bitblt.exec = DA2_BLT_CFILLTILE; da2->bitblt.destaddr += 2; da2->bitblt.srcaddr = da2->bitblt.reg[0x2B]; @@ -942,9 +939,9 @@ da2_bitblt_load(da2_t *da2) da2->bitblt.reg[0x2B] % (da2->rowoffset * 2), da2->bitblt.reg[0x2B] / (da2->rowoffset * 2), da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), da2->bitblt.size_x, da2->bitblt.size_y); - } + /* Tiling a rectangle (transfer tile data multiple times) */ - else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x1040 && da2->bitblt.reg[0x3D] == 0x40) { + } else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x1040 && da2->bitblt.reg[0x3D] == 0x40) { da2->bitblt.exec = DA2_BLT_CFILLTILE; da2->bitblt.destaddr += 2; da2->bitblt.srcaddr = da2->bitblt.reg[0x2B]; @@ -954,9 +951,9 @@ da2_bitblt_load(da2_t *da2) da2->bitblt.reg[0x2B] % (da2->rowoffset * 2), da2->bitblt.reg[0x2B] / (da2->rowoffset * 2), da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), da2->bitblt.size_x, da2->bitblt.size_y); - } + /* Block copy */ - else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x1040 && da2->bitblt.reg[0x3D] == 0x00) { + } else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x1040 && da2->bitblt.reg[0x3D] == 0x00) { da2->bitblt.exec = DA2_BLT_CCOPYF; da2->bitblt.srcaddr = da2->bitblt.reg[0x2A]; da2->bitblt.destaddr += 2; @@ -965,9 +962,9 @@ da2_bitblt_load(da2_t *da2) da2->bitblt.reg[0x2A] % (da2->rowoffset * 2), da2->bitblt.reg[0x2A] / (da2->rowoffset * 2), da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), da2->bitblt.size_x, da2->bitblt.size_y); - } + /* Block copy but reversed direction */ - else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x1140 && da2->bitblt.reg[0x3D] == 0x00) { + } else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x1140 && da2->bitblt.reg[0x3D] == 0x00) { da2->bitblt.exec = DA2_BLT_CCOPYR; da2->bitblt.srcaddr = da2->bitblt.reg[0x2A]; da2->bitblt.destaddr -= 2; @@ -980,9 +977,9 @@ da2_bitblt_load(da2_t *da2) } } static void -da2_bitblt_exec(void *p) +da2_bitblt_exec(void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; // timer_set_delay_u64(&da2->bitblt.timer, da2->bitblt.timerspeed); #ifdef ENABLE_DA2_DEBUGBLT_DETAIL if (!(da2->bitblt.debug_exesteps & 0xff)) @@ -1180,9 +1177,9 @@ da2_bitblt_dopayload(void *priv) } } static void -da2_bitblt_addpayload(uint8_t val, void *p) +da2_bitblt_addpayload(uint8_t val, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; da2->bitblt.indata = 1; if (da2->bitblt.payload_addr >= DA2_BLT_MEMSIZE) da2_log("da2_mmio_write payload overflow! addr %x, val %x\n", da2->bitblt.payload_addr, val); @@ -1222,9 +1219,9 @@ da2_bitblt_addpayload(uint8_t val, void *p) } static void -da2_out(uint16_t addr, uint16_t val, void *p) +da2_out(uint16_t addr, uint16_t val, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; int oldval; /* 3E0 3E1 Sequencer Registers (undoc) @@ -1403,7 +1400,7 @@ da2_out(uint16_t addr, uint16_t val, void *p) if (da2->attraddr < 16) da2->fullchange = changeframecount; if (da2->attraddr == LV_MODE_CONTROL || da2->attraddr < 0x10) { - for (int c = 0; c < 16; c++) { + for (uint8_t c = 0; c < 16; c++) { // if (da2->attrc[LV_MODE_CONTROL] & 0x80) da2->egapal[c] = (da2->attrc[c] & 0xf) | ((da2->attrc[0x14] & 0xf) << 4); // else da2->egapal[c] = (da2->attrc[c] & 0x3f) | ((da2->attrc[0x14] & 0xc) << 4); if (da2->attrc[LV_MODE_CONTROL] & 0x80) @@ -1486,9 +1483,9 @@ da2_out(uint16_t addr, uint16_t val, void *p) } static uint16_t -da2_in(uint16_t addr, void *p) +da2_in(uint16_t addr, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; uint16_t temp = 0xff; switch (addr) { @@ -1620,9 +1617,9 @@ da2_in(uint16_t addr, void *p) * out b(idx), in w(data) */ static void -da2_outb(uint16_t addr, uint8_t val, void *p) +da2_outb(uint16_t addr, uint8_t val, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; da2_iolog("DA2 Outb addr %03X val %02X %04X:%04X es:di=%x:%x ds:si=%x:%x\n", addr, val, cs >> 4, cpu_state.pc, ES, DI, DS, SI); da2->inflipflop = 0; switch (addr) { @@ -1651,10 +1648,10 @@ da2_outb(uint16_t addr, uint8_t val, void *p) da2_out(addr, da2->iolatch, da2); } void -da2_outw(uint16_t addr, uint16_t val, void *p) +da2_outw(uint16_t addr, uint16_t val, void *priv) { da2_iolog("DA2 Outw addr %03X val %04X\n", addr, val); - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; da2->inflipflop = 0; switch (addr) { case LS_INDEX: @@ -1703,10 +1700,10 @@ da2_outw(uint16_t addr, uint16_t val, void *p) } } static uint8_t -da2_inb(uint16_t addr, void *p) +da2_inb(uint16_t addr, void *priv) { uint8_t temp; - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; da2->outflipflop = 0; switch (addr) { case LC_DATA: @@ -1736,10 +1733,10 @@ da2_inb(uint16_t addr, void *p) return temp; } static uint16_t -da2_inw(uint16_t addr, void *p) +da2_inw(uint16_t addr, void *priv) { uint16_t temp; - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; da2->inflipflop = 0; da2->outflipflop = 0; temp = da2_in(addr, da2); @@ -1748,9 +1745,9 @@ da2_inw(uint16_t addr, void *p) } /* IO 03DAh : Input Status Register 2 for DOSSHELL used by DOS J4.0 */ static uint8_t -da2_in_ISR(uint16_t addr, void *p) +da2_in_ISR(uint16_t addr, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; uint8_t temp = 0; if (addr == 0x3da) { if (da2->cgastat & 0x01) @@ -1764,9 +1761,9 @@ da2_in_ISR(uint16_t addr, void *p) } static void -da2_out_ISR(uint16_t addr, uint8_t val, void *p) +da2_out_ISR(uint16_t addr, uint8_t val, void *priv) { - // da2_t* da2 = (da2_t*)p; + // da2_t* da2 = (da2_t*) priv; da2_iolog("DA2D Out %04X %04X %04X:%04X\n", addr, val, cs >> 4, cpu_state.pc); } @@ -1872,9 +1869,9 @@ The Font ROM can be accessed via 128 KB memory window located at A0000-BFFFFh. /* Get character line pattern from jfont rom or gaiji volatile memory */ static uint32_t -getfont_ps55dbcs(int32_t code, int32_t line, void *p) +getfont_ps55dbcs(int32_t code, int32_t line, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; uint32_t font = 0; int32_t fline = line - 2; /* Start line of drawing character (line >= 1 AND line < 24 + 1 ) */ if (code >= 0x8000 && code <= 0x8183) @@ -1963,10 +1960,10 @@ da2_render_text(da2_t *da2) uint32_t chr_dbcs; int chr_wide = 0; int colormode = ((da2->attrc[LV_PAS_STATUS_CNTRL] & 0x80) == 0x80); - // da2_log("\nda2ma: %x, da2sc: %x\n", da2->ma, da2->sc); + // da2_log("\nda2ma: %x, da2sc: %x\n", da2->memaddr, da2->scanline); for (x = 0; x < da2->hdisp; x += 13) { - chr = da2->cram[(da2->ma) & DA2_MASK_CRAM]; - attr = da2->cram[(da2->ma + 1) & DA2_MASK_CRAM]; + chr = da2->cram[(da2->memaddr) & DA2_MASK_CRAM]; + attr = da2->cram[(da2->memaddr + 1) & DA2_MASK_CRAM]; // if(chr!=0x20) da2_log("chr: %x, attr: %x ", chr, attr); if (colormode) /* IO 3E8h, Index 1Dh */ { /* --Parse attribute byte in color mode-- */ @@ -2006,11 +2003,11 @@ da2_render_text(da2_t *da2) /* Stay drawing If the char code is DBCS and not at last column. */ if (chr_wide) { /* Get high DBCS code from the next video address */ - chr_dbcs = da2->cram[(da2->ma + 2) & DA2_MASK_CRAM]; + chr_dbcs = da2->cram[(da2->memaddr + 2) & DA2_MASK_CRAM]; chr_dbcs <<= 8; chr_dbcs |= chr; /* Get the font pattern */ - uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->sc, da2); + uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->scanline, da2); /* Draw 13 dots */ for (uint32_t n = 0; n < 13; n++) { p[n] = da2->pallook[da2->egapal[(font & 0x80000000) ? fg : bg]]; @@ -2023,10 +2020,10 @@ da2_render_text(da2_t *da2) fontbase = DA2_GAIJIRAM_SBEX; else fontbase = DA2_GAIJIRAM_SBCS; - uint16_t font = da2->mmio.ram[fontbase + chr * 0x40 + da2->sc * 2]; /* w13xh29 font */ + uint16_t font = da2->mmio.ram[fontbase + chr * 0x40 + da2->scanline * 2]; /* w13xh29 font */ font <<= 8; - font |= da2->mmio.ram[fontbase + chr * 0x40 + da2->sc * 2 + 1]; /* w13xh29 font */ - // if(chr!=0x20) da2_log("ma: %x, sc: %x, chr: %x, font: %x ", da2->ma, da2->sc, chr, font); + font |= da2->mmio.ram[fontbase + chr * 0x40 + da2->scanline * 2 + 1]; /* w13xh29 font */ + // if(chr!=0x20) da2_log("memaddr: %x, scanline: %x, chr: %x, font: %x ", da2->memaddr, da2->scanline, chr, font); /* Draw 13 dots */ for (uint32_t n = 0; n < 13; n++) { p[n] = da2->pallook[da2->egapal[(font & 0x8000) ? fg : bg]]; @@ -2036,7 +2033,7 @@ da2_render_text(da2_t *da2) } /* right half of DBCS */ else { - uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->sc, da2); + uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->scanline, da2); /* Draw 13 dots */ for (uint32_t n = 0; n < 13; n++) { p[n] = da2->pallook[da2->egapal[(font & 0x8000) ? fg : bg]]; @@ -2045,7 +2042,7 @@ da2_render_text(da2_t *da2) chr_wide = 0; } /* Line 28 (Underscore) Note: Draw this first to display blink + vertical + underline correctly. */ - if (da2->sc == da2->crtc[LC_UNDERLINE_LOCATION] && attr & 0x40 && !colormode) { /* Underscore only in monochrome mode */ + if (da2->scanline == da2->crtc[LC_UNDERLINE_LOCATION] && attr & 0x40 && !colormode) { /* Underscore only in monochrome mode */ for (uint32_t n = 0; n < 13; n++) p[n] = da2->pallook[da2->egapal[fg]]; /* under line (white) */ } @@ -2053,13 +2050,13 @@ da2_render_text(da2_t *da2) if (attr & 0x10) { p[0] = da2->pallook[da2->egapal[(colormode) ? IRGBtoBGRI(da2->attrc[LV_GRID_COLOR_0]) : 2]]; /* vertical line (white) */ } - if (da2->sc == 0 && attr & 0x20 && ~da2->attrc[LV_PAS_STATUS_CNTRL]) { /* HGrid */ + if (da2->scanline == 0 && attr & 0x20 && ~da2->attrc[LV_PAS_STATUS_CNTRL]) { /* HGrid */ for (uint32_t n = 0; n < 13; n++) p[n] = da2->pallook[da2->egapal[(colormode) ? IRGBtoBGRI(da2->attrc[LV_GRID_COLOR_0]) : 2]]; /* horizontal line (white) */ } /* Drawing text cursor */ - drawcursor = ((da2->ma == da2->ca) && da2->con && da2->cursoron); - if (drawcursor && da2->sc >= da2->crtc[LC_CURSOR_ROW_START] && da2->sc <= da2->crtc[LC_CURSOR_ROW_END]) { + drawcursor = ((da2->memaddr == da2->cursoraddr) && da2->cursorvisible && da2->cursoron); + if (drawcursor && da2->scanline >= da2->crtc[LC_CURSOR_ROW_START] && da2->scanline <= da2->crtc[LC_CURSOR_ROW_END]) { int cursorwidth = (da2->crtc[LC_COMPATIBILITY] & 0x20 ? 26 : 13); int cursorcolor = (colormode) ? IRGBtoBGRI(da2->attrc[LV_CURSOR_COLOR]) : 2; /* Choose color 2 if mode 8 */ fg = (colormode) ? getPS55ForeColor(attr, da2) : ((attr & 0x08) ? 3 : 2); @@ -2074,10 +2071,10 @@ da2_render_text(da2_t *da2) else p[n] = (p[n] == da2->pallook[da2->egapal[bg]]) ? da2->pallook[da2->egapal[cursorcolor]] : p[n]; } - da2->ma += 2; + da2->memaddr += 2; p += 13; } - // da2->ma &= DA2_MASK_CRAM; + // da2->memaddr &= DA2_MASK_CRAM; // da2->writelines++; } } @@ -2099,12 +2096,12 @@ da2_render_textm3(da2_t *da2) int fg, bg; uint32_t chr_dbcs; int chr_wide = 0; - // da2_log("\nda2ma: %x, da2sc: %x\n", da2->ma, da2->sc); + // da2_log("\nda2ma: %x, da2sc: %x\n", da2->memaddr, da2->scanline); for (x = 0; x < da2->hdisp; x += 13) { - chr = da2_vram_r(DA2_VM03_BASECHR + da2->ma, da2); - attr = da2_vram_r(DA2_VM03_BASECHR + da2->ma + 1, da2); - extattr = da2_vram_r(DA2_VM03_BASEEXATTR + da2->ma + 1, da2); - // if(chr!=0x20) da2_log("addr: %x, chr: %x, attr: %x ", (DA2_VM03_BASECHR + da2->ma << 1) & da2->vram_mask, chr, attr); + chr = da2_vram_r(DA2_VM03_BASECHR + da2->memaddr, da2); + attr = da2_vram_r(DA2_VM03_BASECHR + da2->memaddr + 1, da2); + extattr = da2_vram_r(DA2_VM03_BASEEXATTR + da2->memaddr + 1, da2); + // if(chr!=0x20) da2_log("addr: %x, chr: %x, attr: %x ", (DA2_VM03_BASECHR + da2->memaddr << 1) & da2->vram_mask, chr, attr); bg = attr >> 4; // if (da2->blink) bg &= ~0x8; // fg = (da2->blink || (!(attr & 0x80))) ? (attr & 0xf) : bg; @@ -2121,11 +2118,11 @@ da2_render_textm3(da2_t *da2) /* Stay drawing if the char code is DBCS and not at last column. */ if (chr_wide) { /* Get high DBCS code from the next video address */ - chr_dbcs = da2_vram_r(DA2_VM03_BASECHR + da2->ma + 2, da2); + chr_dbcs = da2_vram_r(DA2_VM03_BASECHR + da2->memaddr + 2, da2); chr_dbcs <<= 8; chr_dbcs |= chr; /* Get the font pattern */ - uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->sc, da2); + uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->scanline, da2); /* Draw 13 dots */ for (uint32_t n = 0; n < 13; n++) { p[n] = da2->pallook[da2->egapal[(font & 0x80000000) ? fg : bg]]; @@ -2138,10 +2135,10 @@ da2_render_textm3(da2_t *da2) fontbase = DA2_GAIJIRAM_SBEX; else fontbase = DA2_GAIJIRAM_SBCS; - uint16_t font = da2->mmio.ram[fontbase+ chr * 0x40 + da2->sc * 2]; /* w13xh29 font */ + uint16_t font = da2->mmio.ram[fontbase+ chr * 0x40 + da2->scanline * 2]; /* w13xh29 font */ font <<= 8; - font |= da2->mmio.ram[fontbase + chr * 0x40 + da2->sc * 2 + 1]; /* w13xh29 font */ - // if(chr!=0x20) da2_log("ma: %x, sc: %x, chr: %x, font: %x ", da2->ma, da2->sc, chr, font); + font |= da2->mmio.ram[fontbase + chr * 0x40 + da2->scanline * 2 + 1]; /* w13xh29 font */ + // if(chr!=0x20) da2_log("memaddr: %x, scanline: %x, chr: %x, font: %x ", da2->memaddr, da2->scanline, chr, font); for (uint32_t n = 0; n < 13; n++) { p[n] = da2->pallook[da2->egapal[(font & 0x8000) ? fg : bg]]; font <<= 1; @@ -2150,7 +2147,7 @@ da2_render_textm3(da2_t *da2) } /* right half of DBCS */ else { - uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->sc, da2); + uint32_t font = getfont_ps55dbcs(chr_dbcs, da2->scanline, da2); /* Draw 13 dots */ for (uint32_t n = 0; n < 13; n++) { p[n] = da2->pallook[da2->egapal[(font & 0x8000) ? fg : bg]]; @@ -2158,8 +2155,8 @@ da2_render_textm3(da2_t *da2) } chr_wide = 0; } - drawcursor = ((da2->ma == da2->ca) && da2->con && da2->cursoron); - if (drawcursor && da2->sc >= da2->crtc[LC_CURSOR_ROW_START] && da2->sc <= da2->crtc[LC_CURSOR_ROW_END]) { + drawcursor = ((da2->memaddr == da2->cursoraddr) && da2->cursorvisible && da2->cursoron); + if (drawcursor && da2->scanline >= da2->crtc[LC_CURSOR_ROW_START] && da2->scanline <= da2->crtc[LC_CURSOR_ROW_END]) { // int cursorwidth = (da2->crtc[0x1f] & 0x20 ? 26 : 13); // int cursorcolor = (colormode) ? IRGBtoBGRI(da2->attrc[0x1a]) : 2;/* Choose color 2 if mode 8 */ // fg = (colormode) ? getPS55ForeColor(attr, da2) : (attr & 0x08) ? 3 : 2; @@ -2171,10 +2168,10 @@ da2_render_textm3(da2_t *da2) for (uint32_t n = 0; n < 13; n++) p[n] = da2->pallook[da2->egapal[fg]]; } - da2->ma += 2; + da2->memaddr += 2; p += 13; } - // da2->ma &= DA2_MASK_CRAM; + // da2->memaddr &= DA2_MASK_CRAM; // da2->writelines++; } } @@ -2182,8 +2179,8 @@ da2_render_textm3(da2_t *da2) static void da2_render_color_4bpp(da2_t *da2) { - int changed_offset = da2->ma >> 9; - // da2_log("ma %x cf %x\n", da2->ma, changed_offset); + int changed_offset = da2->memaddr >> 9; + // da2_log("memaddr %x cf %x\n", da2->memaddr, changed_offset); da2->plane_mask &= 0x0f; /*safety */ if (da2->changedvram[changed_offset] || da2->changedvram[changed_offset + 1] || da2->fullchange) { @@ -2194,7 +2191,7 @@ da2_render_color_4bpp(da2_t *da2) if (da2->firstline_draw == 2000) da2->firstline_draw = da2->displine; da2->lastline_draw = da2->displine; - // da2_log("d %X\n", da2->ma); + // da2_log("d %X\n", da2->memaddr); for (x = 0; x <= da2->hdisp; x += 8) /* hdisp = 1024 */ { @@ -2202,9 +2199,9 @@ da2_render_color_4bpp(da2_t *da2) uint8_t dat; /* get 8 pixels from vram */ - da2->ma &= da2->vram_display_mask; - *(uint32_t *) (&edat[0]) = *(uint32_t *) (&da2->vram[da2->ma << 3]); - da2->ma += 1; + da2->memaddr &= da2->vram_display_mask; + *(uint32_t *) (&edat[0]) = *(uint32_t *) (&da2->vram[da2->memaddr << 3]); + da2->memaddr += 1; dat = ((edat[0] >> 7) & (1 << 0)) | ((edat[1] >> 6) & (1 << 1)) | ((edat[2] >> 5) & (1 << 2)) | ((edat[3] >> 4) & (1 << 3)); p[0] = da2->pallook[da2->egapal[dat & da2->plane_mask]]; @@ -2231,8 +2228,8 @@ da2_render_color_4bpp(da2_t *da2) static void da2_render_color_8bpp(da2_t *da2) { - int changed_offset = da2->ma >> 9; - // da2_log("ma %x cf %x\n", da2->ma, changed_offset); + int changed_offset = da2->memaddr >> 9; + // da2_log("memaddr %x cf %x\n", da2->memaddr, changed_offset); if (da2->changedvram[changed_offset] || da2->changedvram[changed_offset + 1] || da2->fullchange) { int x; @@ -2242,7 +2239,7 @@ da2_render_color_8bpp(da2_t *da2) if (da2->firstline_draw == 2000) da2->firstline_draw = da2->displine; da2->lastline_draw = da2->displine; - // da2_log("d %X\n", da2->ma); + // da2_log("d %X\n", da2->memaddr); for (x = 0; x <= da2->hdisp; x += 8) /* hdisp = 1024 */ { @@ -2250,10 +2247,10 @@ da2_render_color_8bpp(da2_t *da2) uint8_t dat; /* get 8 pixels from vram */ - da2->ma &= da2->vram_display_mask; - *(uint32_t *) (&edat[0]) = *(uint32_t *) (&da2->vram[da2->ma << 3]); - *(uint32_t *) (&edat[4]) = *(uint32_t *) (&da2->vram[(da2->ma << 3) + 4]); - da2->ma += 1; + da2->memaddr &= da2->vram_display_mask; + *(uint32_t *) (&edat[0]) = *(uint32_t *) (&da2->vram[da2->memaddr << 3]); + *(uint32_t *) (&edat[4]) = *(uint32_t *) (&da2->vram[(da2->memaddr << 3) + 4]); + da2->memaddr += 1; dat = ((edat[0] >> 7) & (1 << 0)) | ((edat[1] >> 6) & (1 << 1)) | ((edat[2] >> 5) & (1 << 2)) | ((edat[3] >> 4) & (1 << 3)) | ((edat[4] >> 3) & (1 << 4)) | ((edat[5] >> 2) & (1 << 5)) | ((edat[6] >> 1) & (1 << 6)) | ((edat[7] >> 0) & (1 << 7)); p[0] = da2->pallook[dat]; @@ -2346,9 +2343,9 @@ da2_recalctimings(da2_t *da2) if (da2->rowoffset == 0) da2->rowoffset = 64 * 2; /* To avoid causing a DBZ error */ if (da2->split == 0) /* To avoid a glitch in MODE 1 of OS/2 J1.3 DOSBox. */ - da2->ma_latch = 0; + da2->memaddr_latch = 0; else - da2->ma_latch = ((da2->crtc[LC_START_ADDRESS_HIGH] & 0x3ff) << 8) | da2->crtc[LC_START_ADDRESS_LOW]; + da2->memaddr_latch = ((da2->crtc[LC_START_ADDRESS_HIGH] & 0x3ff) << 8) | da2->crtc[LC_START_ADDRESS_LOW]; da2->ca_adj = 0; da2->rowcount = da2->crtc[LC_MAXIMUM_SCAN_LINE]; @@ -2424,7 +2421,7 @@ da2_mapping_update(da2_t *da2) // da2_recalc_mapping(da2); if (da2->pos_regs[2] & 0x01) { da2_log("DA2 enable registers\n"); - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) da2_log("DA2 POS[%d]: %x\n", i, da2->pos_regs[i]); io_sethandler(0x03c0, 0x000a, da2_inb, da2_inw, NULL, da2_outb, da2_outw, NULL, da2); io_sethandler(0x03e0, 0x0010, da2_inb, da2_inw, NULL, da2_outb, da2_outw, NULL, da2); @@ -2444,16 +2441,16 @@ da2_mapping_update(da2_t *da2) } static uint8_t -da2_mca_read(int port, void *p) +da2_mca_read(int port, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; return da2->pos_regs[port & 7]; } static void -da2_mca_write(int port, uint8_t val, void *p) +da2_mca_write(int port, uint8_t val, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; da2_log("da2_mca_write: port=%04x val=%02x\n", port, val); @@ -2473,9 +2470,9 @@ da2_mca_feedb(void *priv) } static void -da2_mca_reset(void *p) +da2_mca_reset(void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; da2_log("da2_mca_reset called.\n"); da2_reset(da2); da2_mca_write(0x102, 0, da2); @@ -2485,7 +2482,7 @@ da2_mca_reset(void *p) static void da2_gdcropB(uint32_t addr,uint8_t bitmask, da2_t *da2) { - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { if (da2->planemask & (1 << i)) { // da2_log("da2_gdcropB o%x a%x d%x p%d m%x\n", da2->gdcreg[LG_COMMAND] & 0x03, addr, da2->gdcinput[i], i, bitmask); switch (da2->gdcreg[LG_COMMAND] & 0x03) { @@ -2518,7 +2515,7 @@ da2_gdcropW(uint32_t addr, uint16_t bitmask, da2_t *da2) // if((addr & 8)) bitmask = da2_rightrotate(bitmask, 8); uint8_t bitmask_l = bitmask & 0xff; uint8_t bitmask_h = bitmask >> 8; - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { if (da2->planemask & (1 << i)) { // da2_log("da2_gdcropW m%x a%x d%x i%d ml%x mh%x\n", da2->gdcreg[LG_COMMAND] & 0x03, addr, da2->gdcinput[i], i, da2->gdcreg[LG_BIT_MASK_LOW], da2->gdcreg[LG_BIT_MASK_HIGH]); switch (da2->gdcreg[LG_COMMAND] & 0x03) { @@ -2556,9 +2553,9 @@ da2_gdcropW(uint32_t addr, uint16_t bitmask, da2_t *da2) } static uint8_t -da2_mmio_read(uint32_t addr, void *p) +da2_mmio_read(uint32_t addr, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; uint32_t index = 0; addr &= DA2_MASK_MMIO; if (da2->ioctl[LS_MMIO] & 0x10) { @@ -2604,14 +2601,14 @@ da2_mmio_read(uint32_t addr, void *p) } } else if (!(da2->ioctl[LS_MODE] & 1)) { /* 16 or 256 color mode */ cycles -= video_timing_read_b; - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) da2->gdcla[i] = da2->vram[(addr << 3) | i]; /* read in byte */ #ifdef ENABLE_DA2_DEBUGVRAM da2_log("da2_Rb: %05x=%02x\n", addr, da2->gdcla[da2->readplane]); #endif if (da2->gdcreg[LG_MODE] & 0x08) { /* compare data across planes if the read mode bit (3EB 05, bit 3) is 1 */ uint8_t ret = 0; - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { if (~da2->gdcreg[LG_COLOR_DONT_CARE] & (1 << i)) /* color don't care register */ ret |= da2->gdcla[i] ^ ((da2->gdcreg[LG_COLOR_COMPAREJ] & (1 << i)) ? 0xff : 0); } @@ -2624,9 +2621,9 @@ da2_mmio_read(uint32_t addr, void *p) } } static uint16_t -da2_mmio_readw(uint32_t addr, void *p) +da2_mmio_readw(uint32_t addr, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; // da2_log("da2_readW: %x %x %x %x %x\n", da2->ioctl[LS_MMIO], da2->fctl[LF_MMIO_SEL], da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr); // da2_log("da2_readW: %x %x %x %x %x CS:PC=%4x:%4x\n", da2->ioctl[LS_MMIO], da2->fctl[LF_MMIO_SEL], da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr, CS, cpu_state.pc); @@ -2635,7 +2632,7 @@ da2_mmio_readw(uint32_t addr, void *p) } else if (!(da2->ioctl[LS_MODE] & 1)) {/* 16 color or 256 color mode */ cycles -= video_timing_read_w; addr &= DA2_MASK_MMIO; - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) da2->gdcla[i] = (uint16_t) (da2->vram[(addr << 3) | i]) | ((uint16_t) (da2->vram[((addr << 3) + 8) | i]) << 8); /* read vram into latch */ #ifdef ENABLE_DA2_DEBUGVRAM @@ -2643,10 +2640,10 @@ da2_mmio_readw(uint32_t addr, void *p) // if (((int)addr - (int)da2->mmrdbg_vidaddr) > 2 || (((int)da2->mmrdbg_vidaddr - (int)addr) > 2) || da2->mmrdbg_vidaddr == addr) //{ // fprintf(da2->mmrdbg_fp, "\nR %x ", addr); - // for (int i = 0; i <= 0xb; i++) + // for (uint8_t i = 0; i <= 0xb; i++) // fprintf(da2->mmrdbg_fp, "%02x ", da2->gdcreg[i]); // } - // for (int i = 0; i < 16; i++) + // for (uint8_t i = 0; i < 16; i++) //{ // int pixeldata = 0; // if (da2->gdcla[da2->readplane] & (1 << (15 - i))) pixeldata = 1; @@ -2658,7 +2655,7 @@ da2_mmio_readw(uint32_t addr, void *p) if (da2->gdcreg[LG_MODE] & 0x08) { /* compare data across planes if the read mode bit (3EB 05, bit 3) is 1 */ uint16_t ret = 0; - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { if (~da2->gdcreg[LG_COLOR_DONT_CARE] & (1 << i)) /* color don't care register */ ret |= da2->gdcla[i] ^ ((da2->gdcreg[LG_COLOR_COMPAREJ] & (1 << i)) ? 0xffff : 0); } @@ -2674,9 +2671,9 @@ da2_mmio_readw(uint32_t addr, void *p) } } static void -da2_mmio_write(uint32_t addr, uint8_t val, void *p) +da2_mmio_write(uint32_t addr, uint8_t val, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; uint32_t index = 0; // da2_log("da2_mmio_write %x %x\n", addr, val); // if ((addr & ~DA2_MASK_MMIO) != 0xA0000) @@ -2735,10 +2732,10 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) //{ if (((int) addr - (int) da2->mmdbg_vidaddr) > 2 || (((int) da2->mmdbg_vidaddr - (int) addr) > 2) || da2->mmdbg_vidaddr == addr) { fprintf(da2->mmdbg_fp, "\nB %x %02x ", addr, val); - for (int i = 0; i <= 0xb; i++) + for (uint8_t i = 0; i <= 0xb; i++) fprintf(da2->mmdbg_fp, "%02x ", da2->gdcreg[i]); } - for (int i = 0; i < 8; i++) { + for (uint8_t i = 0; i < 8; i++) { int pixeldata = 0; if (val & (1 << (7 - i))) pixeldata = (da2->planemask & 0xf); @@ -2751,14 +2748,14 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) da2->changedvram[addr >> 9] = changeframecount;/* 0x1FFFF -> 0x1F */ addr <<= 3; - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) da2->gdcsrc[i] = da2->gdcla[i]; /* use latch */ // da2_log("da2_Wb m%02x r%02x %05x:%02x %x:%x\n", da2->gdcreg[0x5], da2->gdcreg[LG_COMMAND], addr >> 3, val, cs >> 4, cpu_state.pc); // da2_log("da2_Wb m%02x r%02x %05x:%02x=%02x%02x%02x%02x->", da2->gdcreg[0x5], da2->gdcreg[LG_COMMAND], addr >> 3, val, da2->vram[addr + 0], da2->vram[addr + 1], da2->vram[addr + 2], da2->vram[addr + 3]); if (!(da2->gdcreg[LG_COMMAND] & 0x08)) { - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) if (da2->gdcreg[LG_ENABLE_SRJ] & (1 << i)) da2->gdcinput[i] = (da2->gdcreg[LG_SET_RESETJ] & (1 << i)) ? 0xff : 0; else if (da2->gdcreg[LG_SET_RESETJ] & (1 << i)) @@ -2771,7 +2768,7 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) switch (da2->writemode) { case 2: /* equiv to vga write mode 1 */ - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) if (da2->planemask & (1 << i)) da2_vram_w(addr | i, da2->gdcsrc[i], da2); break; @@ -2779,11 +2776,11 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) if (da2->gdcreg[LG_DATA_ROTATION] & 7) val = svga_rotate[da2->gdcreg[LG_DATA_ROTATION] & 7][val]; if (bitmask == 0xff && !(da2->gdcreg[LG_COMMAND] & 0x03) && (!da2->gdcreg[LG_ENABLE_SRJ])) { - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) if (da2->planemask & (1 << i)) da2_vram_w(addr | i, val, da2); } else { - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) if (da2->gdcreg[LG_ENABLE_SRJ] & (1 << i)) da2->gdcinput[i] = (da2->gdcreg[LG_SET_RESETJ] & (1 << i)) ? 0xff : 0; else @@ -2792,7 +2789,7 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) } break; case 1:/* equiv to vga write mode 2 */ - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) da2->gdcinput[i] = ((val & (1 << i)) ? 0xff : 0); da2_gdcropB(addr, bitmask, da2); break; @@ -2801,7 +2798,7 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) val = svga_rotate[da2->gdcreg[LG_DATA_ROTATION] & 7][val]; bitmask &= val; - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) da2->gdcinput[i] = (da2->gdcreg[LG_SET_RESETJ] & (1 << i)) ? 0xff : 0; da2_gdcropB(addr, bitmask, da2); break; @@ -2818,9 +2815,9 @@ da2_rightrotate(uint16_t data, uint8_t count) return (data >> count) | (data << (sizeof(data) * 8 - count)); } static void -da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *p) +da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; uint16_t bitmask; addr &= DA2_MASK_MMIO; bitmask = da2->gdcreg[LG_BIT_MASK_HIGH]; @@ -2832,10 +2829,10 @@ da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *p) if (((int) addr - (int) da2->mmdbg_vidaddr) > 2 || (((int) da2->mmdbg_vidaddr - (int) addr) > 2) || da2->mmdbg_vidaddr == addr) { fprintf(da2->mmdbg_fp, "\nW %x %x ", addr, val); - for (int i = 0; i <= 0xb; i++) + for (uint8_t i = 0; i <= 0xb; i++) fprintf(da2->mmdbg_fp, "%02x ", da2->gdcreg[i]); } - for (int i = 0; i < 16; i++) { + for (uint8_t i = 0; i < 16; i++) { int pixeldata = 0; if (val & (1 << (15 - i))) pixeldata = (da2->planemask & 0xf); @@ -2851,11 +2848,11 @@ da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *p) da2->changedvram[addr >> 9] = changeframecount; addr <<= 3; - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) da2->gdcsrc[i] = da2->gdcla[i]; /* use latch */ if (!(da2->gdcreg[LG_COMMAND] & 0x08)) { - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) if (da2->gdcreg[LG_ENABLE_SRJ] & (1 << i)) da2->gdcinput[i] = (da2->gdcreg[LG_SET_RESETJ] & (1 << i)) ? 0xffff : 0; else if (da2->gdcreg[LG_SET_RESETJ] & (1 << i)) @@ -2869,7 +2866,7 @@ da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *p) // , da2->vram[addr + 8], da2->vram[addr + 9], da2->vram[addr + 10], da2->vram[addr + 11]); switch (da2->writemode) { case 2: - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) if (da2->planemask & (1 << i)) { da2_vram_w(addr | i, da2->gdcsrc[i] & 0xff, da2); da2_vram_w((addr + 8) | i, da2->gdcsrc[i] >> 8, da2); @@ -2879,13 +2876,13 @@ da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *p) if (da2->gdcreg[LG_DATA_ROTATION] & 15) val = da2_rightrotate(val, da2->gdcreg[LG_DATA_ROTATION] & 15); if (bitmask == 0xffff && !(da2->gdcreg[LG_COMMAND] & 0x03) && (!da2->gdcreg[LG_ENABLE_SRJ])) { - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) if (da2->planemask & (1 << i)) { da2_vram_w(addr | i, val & 0xff, da2); da2_vram_w((addr + 8) | i, val >> 8, da2); } } else { - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) if (da2->gdcreg[LG_ENABLE_SRJ] & (1 << i)) da2->gdcinput[i] = (da2->gdcreg[LG_SET_RESETJ] & (1 << i)) ? 0xffff : 0; else @@ -2895,7 +2892,7 @@ da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *p) } break; case 1: - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) da2->gdcinput[i] = ((val & (1 << i)) ? 0xffff : 0); da2_gdcropW(addr, bitmask, da2); break; @@ -2904,7 +2901,7 @@ da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *p) val = da2_rightrotate(val, da2->gdcreg[LG_DATA_ROTATION] & 15); bitmask &= val; - for (int i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) da2->gdcinput[i] = (da2->gdcreg[LG_SET_RESETJ] & (1 << i)) ? 0xffff : 0; da2_gdcropW(addr, bitmask, da2); break; @@ -2913,9 +2910,9 @@ da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *p) // , da2->vram[addr + 8], da2->vram[addr + 9], da2->vram[addr + 10], da2->vram[addr + 11]); } static void -da2_mmio_writew(uint32_t addr, uint16_t val, void *p) +da2_mmio_writew(uint32_t addr, uint16_t val, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; // if (da2->bitblt.exec != DA2_BLT_CIDLE) /* Bitblt is in operation. */ // return; // if ((addr & ~0x1ffff) != 0xA0000) return; @@ -2941,52 +2938,52 @@ da2_mmio_writew(uint32_t addr, uint16_t val, void *p) } static void -da2_code_write(uint32_t addr, uint8_t val, void *p) +da2_code_write(uint32_t addr, uint8_t val, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; // if ((addr & ~0xfff) != 0xE0000) return; addr &= DA2_MASK_CRAM; da2->cram[addr] = val; da2->fullchange = 2; } static void -da2_code_writeb(uint32_t addr, uint8_t val, void *p) +da2_code_writeb(uint32_t addr, uint8_t val, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; // da2_log("DA2_code_writeb: Write to %x, val %x\n", addr, val); cycles -= video_timing_write_b; da2_code_write(addr, val, da2); } static void -da2_code_writew(uint32_t addr, uint16_t val, void *p) +da2_code_writew(uint32_t addr, uint16_t val, void *priv) { // da2_log("DA2_code_writ ew: Write to %x, val %x\n", addr, val); - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; cycles -= video_timing_write_w; da2_code_write(addr, val & 0xff, da2); da2_code_write(addr + 1, val >> 8, da2); } static uint8_t -da2_code_read(uint32_t addr, void *p) +da2_code_read(uint32_t addr, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; // if ((addr & ~DA2_MASK_CRAM) != 0xE0000) // return DA2_INVALIDACCESS8; addr &= DA2_MASK_CRAM; return da2->cram[addr]; } static uint8_t -da2_code_readb(uint32_t addr, void *p) +da2_code_readb(uint32_t addr, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; cycles -= video_timing_read_b; return da2_code_read(addr, da2); } static uint16_t -da2_code_readw(uint32_t addr, void *p) +da2_code_readw(uint32_t addr, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; cycles -= video_timing_read_w; return da2_code_read(addr, da2) | (da2_code_read(addr + 1, da2) << 8); } @@ -3025,7 +3022,7 @@ da2_poll(void *priv) if (da2->dispon) { da2->hdisp_on = 1; - da2->ma &= da2->vram_display_mask; + da2->memaddr &= da2->vram_display_mask; if (da2->firstline == 2000) { da2->firstline = da2->displine; video_wait_for_buffer(); @@ -3038,7 +3035,7 @@ da2_poll(void *priv) da2->lastline = da2->displine; } - // da2_log("%03i %06X %06X\n", da2->displine, da2->ma,da2->vram_display_mask); + // da2_log("%03i %06X %06X\n", da2->displine, da2->memaddr,da2->vram_display_mask); da2->displine++; if ((da2->cgastat & 8) && ((da2->displine & 0xf) == (da2->crtc[LC_VERTICAL_SYNC_END] & 0xf)) && da2->vslines) { // da2_log("Vsync off at line %i\n",displine); @@ -3048,9 +3045,9 @@ da2_poll(void *priv) if (da2->displine > 1200) da2->displine = 0; // da2_log("Col is %08X %08X %08X %i %i %08X\n",((uint32_t *)buffer32->line[displine])[320],((uint32_t *)buffer32->line[displine])[321],((uint32_t *)buffer32->line[displine])[322], - // displine, vc, ma); + // displine, vc, memaddr); } else { - // da2_log("VC %i ma %05X\n", da2->vc, da2->ma); + // da2_log("VC %i memaddr %05X\n", da2->vc, da2->memaddr); timer_advance_u64(&da2->timer, da2->dispontime); if (da2->dispon) @@ -3058,20 +3055,20 @@ da2_poll(void *priv) da2->hdisp_on = 0; da2->linepos = 0; - if (da2->sc == (da2->crtc[LC_CURSOR_ROW_END] & 31)) - da2->con = 0; + if (da2->scanline == (da2->crtc[LC_CURSOR_ROW_END] & 31)) + da2->cursorvisible = 0; if (da2->dispon) { - if (da2->sc == da2->rowcount) { + if (da2->scanline == da2->rowcount) { da2->linecountff = 0; - da2->sc = 0; + da2->scanline = 0; - da2->maback += (da2->rowoffset << 1); /* color = 0x50(80), mono = 0x40(64) */ - da2->maback &= da2->vram_display_mask; - da2->ma = da2->maback; + da2->memaddr_backup += (da2->rowoffset << 1); /* color = 0x50(80), mono = 0x40(64) */ + da2->memaddr_backup &= da2->vram_display_mask; + da2->memaddr = da2->memaddr_backup; } else { - da2->sc++; - da2->sc &= 31; - da2->ma = da2->maback; + da2->scanline++; + da2->scanline &= 31; + da2->memaddr = da2->memaddr_backup; } } @@ -3079,9 +3076,9 @@ da2_poll(void *priv) da2->vc &= 2047; if (da2->vc == da2->split) { - // da2->ma = da2->maback = da2->hblank_sub; - da2->ma = da2->maback = 0; - da2->sc = 0; + // da2->memaddr = da2->memaddr_backup = da2->hblank_sub; + da2->memaddr = da2->memaddr_backup = 0; + da2->scanline = 0; // da2->displine = 0; } @@ -3131,31 +3128,31 @@ da2_poll(void *priv) changeframecount = 2; da2->vslines = 0; - da2->ma - = da2->maback = da2->ma_latch << 1; - da2->ca = ((da2->crtc[LC_CURSOR_LOC_HIGH] << 8) | da2->crtc[LC_CURSOR_LOC_LOWJ]) + da2->ca_adj; - da2->ca <<= 1; + da2->memaddr + = da2->memaddr_backup = da2->memaddr_latch << 1; + da2->cursoraddr = ((da2->crtc[LC_CURSOR_LOC_HIGH] << 8) | da2->crtc[LC_CURSOR_LOC_LOWJ]) + da2->ca_adj; + da2->cursoraddr <<= 1; - // da2_log("Addr %08X vson %03X vsoff %01X\n",da2->ma,da2->vsyncstart,da2->crtc[0x11]&0xF); + // da2_log("Addr %08X vson %03X vsoff %01X\n",da2->memaddr,da2->vsyncstart,da2->crtc[0x11]&0xF); } if (da2->vc == da2->vtotal) { // da2_log("VC vtotal\n"); // printf("Frame over at line %i %i %i %i\n",displine,vc,da2_vsyncstart,da2_dispend); da2->vc = 0; - da2->sc = da2->crtc[LC_PRESET_ROW_SCANJ] & 0x1f; + da2->scanline = da2->crtc[LC_PRESET_ROW_SCANJ] & 0x1f; da2->dispon = 1; da2->displine = 0; da2->scrollcache = da2->attrc[LV_PANNING] & 7; } - if (da2->sc == (da2->crtc[LC_CURSOR_ROW_START] & 31)) - da2->con = 1; + if (da2->scanline == (da2->crtc[LC_CURSOR_ROW_START] & 31)) + da2->cursorvisible = 1; } } static void -da2_loadfont(char *fname, void *p) +da2_loadfont(char *fname, void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; uint8_t buf; uint64_t fsize; if (!fname) @@ -3234,12 +3231,12 @@ da2_reset(void *priv) da2->attrc[LV_CURSOR_COLOR] = 0x0f; /* cursor color */ da2->crtc[LC_HORIZONTAL_TOTAL] = 63; /* Horizontal Total */ da2->crtc[LC_VERTICAL_TOTALJ] = 255; /* Vertical Total (These two must be set before the timer starts.) */ - da2->ma_latch = 0; + da2->memaddr_latch = 0; da2->attrc[LV_CURSOR_CONTROL] = 0x13; /* cursor options */ da2->attr_palette_enable = 0; /* disable attribute generator */ /* Set default color palette (Windows 3.1 display driver won't reset palette) */ - for (int i = 0; i < 256; i++) { + for (uint16_t i = 0; i < 256; i++) { da2->vgapal[i].r = ps55_palette_color[i & 0x3F][0]; da2->vgapal[i].g = ps55_palette_color[i & 0x3F][1]; da2->vgapal[i].b = ps55_palette_color[i & 0x3F][2]; @@ -3320,95 +3317,95 @@ da2_available(void) } static void -da2_close(void *p) +da2_close(void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; /* dump mem for debug */ #ifdef ENABLE_DA2_LOG - FILE *f; - f = fopen("da2_cram.dmp", "wb"); - if (f != NULL) { - fwrite(da2->cram, DA2_SIZE_CRAM, 1, f); - fclose(f); + FILE *fp; + fp = fopen("da2_cram.dmp", "wb"); + if (fp != NULL) { + fwrite(da2->cram, DA2_SIZE_CRAM, 1, fp); + fclose(fp); } - f = fopen("da2_vram.dmp", "wb"); - if (f != NULL) { - fwrite(da2->vram, DA2_SIZE_VRAM, 1, f); - fclose(f); + fp = fopen("da2_vram.dmp", "wb"); + if (fp != NULL) { + fwrite(da2->vram, DA2_SIZE_VRAM, 1, fp); + fclose(fp); } - f = fopen("da2_gram.dmp", "wb"); - if (f != NULL) { - fwrite(da2->mmio.ram, DA2_SIZE_GAIJIRAM, 1, f); - fclose(f); + fp = fopen("da2_gram.dmp", "wb"); + if (fp != NULL) { + fwrite(da2->mmio.ram, DA2_SIZE_GAIJIRAM, 1, fp); + fclose(fp); } - f = fopen("da2_attrpal.dmp", "wb"); - if (f != NULL) { - fwrite(da2->attrc, 32, 1, f); - fclose(f); + fp = fopen("da2_attrpal.dmp", "wb"); + if (fp != NULL) { + fwrite(da2->attrc, 32, 1, fp); + fclose(fp); } - f = fopen("da2_dacrgb.dmp", "wb"); - if (f != NULL) { - fwrite(da2->vgapal, 3 * 256, 1, f); - fclose(f); + fp = fopen("da2_dacrgb.dmp", "wb"); + if (fp != NULL) { + fwrite(da2->vgapal, 3 * 256, 1, fp); + fclose(fp); } - f = fopen("da2_daregs.txt", "w"); - if (f != NULL) { - for (int i = 0; i < 0x10; i++) - fprintf(f, "3e1(ioctl) %02X: %4X\n", i, da2->ioctl[i]); - for (int i = 0; i < 0x20; i++) - fprintf(f, "3e3(fctl) %02X: %4X\n", i, da2->fctl[i]); - for (int i = 0; i < 0x20; i++) - fprintf(f, "3e5(crtc) %02X: %4X\n", i, da2->crtc[i]); - for (int i = 0; i < 0x40; i++) - fprintf(f, "3e8(attr) %02X: %4X\n", i, da2->attrc[i]); - for (int i = 0; i < 0x10; i++) - fprintf(f, "3eb(gcr) %02X: %4X\n", i, da2->gdcreg[i]); - for (int i = 0; i < 0x10; i++) - fprintf(f, "3ee(?) %02X: %4X\n", i, da2->reg3ee[i]); - for (int i = 0; i < 0x20; i++) { - fprintf(f, "vp %02X: %4X %4X %4X %4X\n", i, + fp = fopen("da2_daregs.txt", "w"); + if (fp != NULL) { + for (uint8_t i = 0; i < 0x10; i++) + fprintf(fp, "3e1(ioctl) %02X: %4X\n", i, da2->ioctl[i]); + for (uint8_t i = 0; i < 0x20; i++) + fprintf(fp, "3e3(fctl) %02X: %4X\n", i, da2->fctl[i]); + for (uint8_t i = 0; i < 0x20; i++) + fprintf(fp, "3e5(crtc) %02X: %4X\n", i, da2->crtc[i]); + for (uint8_t i = 0; i < 0x40; i++) + fprintf(fp, "3e8(attr) %02X: %4X\n", i, da2->attrc[i]); + for (uint8_t i = 0; i < 0x10; i++) + fprintf(fp, "3eb(gcr) %02X: %4X\n", i, da2->gdcreg[i]); + for (uint8_t i = 0; i < 0x10; i++) + fprintf(fp, "3ee(?) %02X: %4X\n", i, da2->reg3ee[i]); + for (uint8_t i = 0; i < 0x20; i++) { + fprintf(fp, "vp %02X: %4X %4X %4X %4X\n", i, da2->crtc_vpreg[0 + i], da2->crtc_vpreg[0x20 + i], da2->crtc_vpreg[0x40 + i], da2->crtc_vpreg[0x60 + i]); } - fclose(f); + fclose(fp); } - f = fopen("ram_low.dmp", "wb"); - if (f != NULL) { - fwrite(&ram[0x0], 0x100000, 1, f); - fclose(f); + fp = fopen("ram_low.dmp", "wb"); + if (fp != NULL) { + fwrite(&ram[0x0], 0x100000, 1, fp); + fclose(fp); } pclog("closed %04X:%04X DS %04X\n", cs >> 4, cpu_state.pc, DS); #endif #ifdef ENABLE_DA2_DEBUGBLT - f = fopen("da2_bltdump.csv", "w"); - if (f != NULL && da2->bitblt.debug_reg_ip > 0) { + fp = fopen("da2_bltdump.csv", "w"); + if (fp != NULL && da2->bitblt.debug_reg_ip > 0) { /* print header */ for (int y = 0; y < DA2_DEBUG_BLTLOG_SIZE; y++) { if (da2->bitblt.debug_reg[(da2->bitblt.debug_reg_ip - 1) * DA2_DEBUG_BLTLOG_SIZE + y] != DA2_DEBUG_BLT_NEVERUSED) - fprintf(f, "\"%02X\"\t", y); + fprintf(fp, "\"%02X\"\t", y); } - fprintf(f, "\n"); + fprintf(fp, "\n"); /* print data */ for (int x = 0; x < da2->bitblt.debug_reg_ip; x++) { for (int y = 0; y < DA2_DEBUG_BLTLOG_SIZE; y++) { if (da2->bitblt.debug_reg[x * DA2_DEBUG_BLTLOG_SIZE + y] == DA2_DEBUG_BLT_NEVERUSED) ; else if (da2->bitblt.debug_reg[x * DA2_DEBUG_BLTLOG_SIZE + y] == DA2_DEBUG_BLT_USEDRESET) - fprintf(f, "\"\"\t"); + fprintf(fp, "\"\"\t"); else { - fprintf(f, "\"%X\"\t", da2->bitblt.debug_reg[x * DA2_DEBUG_BLTLOG_SIZE + y]); + fprintf(fp, "\"%X\"\t", da2->bitblt.debug_reg[x * DA2_DEBUG_BLTLOG_SIZE + y]); if (y == 0x12) { int chr = da2->bitblt.debug_reg[x * DA2_DEBUG_BLTLOG_SIZE + 0x12]; if ((chr >= 0x20) && (chr < 0x7f)) - fprintf(f, "\"%c\"\t", chr); + fprintf(fp, "\"%c\"\t", chr); else - fprintf(f, "\"\"\t"); + fprintf(fp, "\"\"\t"); } } } - fprintf(f, "\n"); + fprintf(fp, "\n"); } - fclose(f); + fclose(fp); } free(da2->bitblt.debug_reg); #endif @@ -3426,28 +3423,28 @@ da2_close(void *p) } static void -da2_speed_changed(void *p) +da2_speed_changed(void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; da2->da2const = (uint64_t) ((cpuclock / DA2_PIXELCLOCK) * (double) (1ull << 32)); da2_recalctimings(da2); } static void -da2_force_redraw(void *p) +da2_force_redraw(void *priv) { - da2_t *da2 = (da2_t *) p; + da2_t *da2 = (da2_t *) priv; da2->fullchange = changeframecount; } static const device_config_t da2_configuration[] = { // clang-format off { - .name = "charset", - .description = "Charset", - .type = CONFIG_SELECTION, + .name = "charset", + .description = "Character set", + .type = CONFIG_SELECTION, .default_int = DA2_DCONFIG_CHARSET_JPAN, - .selection = { + .selection = { { .description = "932 (Japanese)", .value = DA2_DCONFIG_CHARSET_JPAN @@ -3460,11 +3457,11 @@ static const device_config_t da2_configuration[] = { } }, { - .name = "montype", + .name = "montype", .description = "Monitor type", - .type = CONFIG_SELECTION, + .type = CONFIG_SELECTION, .default_int = DA2_DCONFIG_MONTYPE_COLOR, - .selection = { + .selection = { { .description = "Color", .value = DA2_DCONFIG_MONTYPE_COLOR diff --git a/src/video/vid_rtg310x.c b/src/video/vid_rtg310x.c index ae9475d96..813d30bf3 100644 --- a/src/video/vid_rtg310x.c +++ b/src/video/vid_rtg310x.c @@ -180,7 +180,7 @@ rtg_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -211,7 +211,7 @@ rtg_recalctimings(svga_t *svga) { const rtg_t *dev = (rtg_t *) svga->priv; - svga->ma_latch |= ((svga->crtc[0x19] & 0x10) << 16) | ((svga->crtc[0x19] & 0x40) << 17); + svga->memaddr_latch |= ((svga->crtc[0x19] & 0x10) << 16) | ((svga->crtc[0x19] & 0x40) << 17); svga->interlace = (svga->crtc[0x19] & 1); diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 8fa392891..0cd1caea3 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -37,6 +37,7 @@ #include <86box/video.h> #include <86box/i2c.h> #include <86box/vid_ddc.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #include "cpu.h" @@ -54,6 +55,7 @@ #define ROM_MIROCRYSTAL20SV_964_PCI "roms/video/s3/mirocrystal.VBI" #define ROM_MIROCRYSTAL20SD_864_VLB "roms/video/s3/Miro20SD.BIN" #define ROM_PHOENIX_86C80X "roms/video/s3/805.VBI" +#define ROM_WINNER1000_805 "roms/video/s3/v01_05_00-C.BIN" #define ROM_PARADISE_BAHAMAS64 "roms/video/s3/bahamas64.bin" #define ROM_PHOENIX_VISION864 "roms/video/s3/86c864p.bin" #define ROM_DIAMOND_STEALTH64_964 "roms/video/s3/964_107h.rom" @@ -117,7 +119,8 @@ enum { S3_NUMBER9_9FX_771, S3_SPEA_MERCURY_LITE_PCI, S3_86C805_ONBOARD, - S3_DIAMOND_STEALTH64_968 + S3_DIAMOND_STEALTH64_968, + S3_WINNER1000_805 }; enum { @@ -234,6 +237,8 @@ typedef struct s3_t { uint8_t advfunc_cntl; uint16_t cur_y, cur_y2; uint16_t cur_x, cur_x2; + uint16_t cur_x_overflow; + uint16_t destx_overflow; uint16_t x2, ropmix; uint16_t pat_x, pat_y; int16_t desty_axstp, desty_axstp2; @@ -286,8 +291,11 @@ typedef struct s3_t { int color_16bit_check; int color_16bit_check_pixtrans; int16_t minus; + int16_t minus_src_24bpp; int rd_mask_16bit_check; int start; + int mix_dat_upper; + int overflow; /*For non-threaded FIFO*/ int setup_fifo_slot; @@ -657,22 +665,31 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) val = (val >> 8) | (val << 8); s3->accel_start(16, 1, val | (val << 16), 0, s3); - } else + } else { + if (s3->accel.rd_mask_16bit_check) { + if ((s3->accel.cmd == 0x53f1) || (s3->accel.cmd == 0x53b1)) { + if (s3->accel.cur_x & 0x400) + val = (val >> 8) | (val << 8); + + s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + + val = (val >> 8) | (val << 8); + } + } s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } } else { if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.cmd == 0x53f1) { + if ((s3->accel.cmd == 0x53f1) || (s3->accel.cmd == 0x53b1)) { if (s3->accel.cur_x & 0x400) val = (val >> 8) | (val << 8); s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); val = (val >> 8) | (val << 8); - s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } else - s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } else - s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } + } + s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); } break; case 0x400: @@ -793,6 +810,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x82e9: s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x0f) << 8); s3->accel.poly_cy = s3->accel.cur_y; + s3_log("[%04X:%08X] OUT PORTB=%04x, valy=%d.\n", CS, cpu_state.pc, port - 1, s3->accel.cur_y); break; case 0x814a: case 0x82ea: @@ -808,15 +826,17 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x8548: case 0x86e8: s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; + s3->accel.cur_x_overflow = (s3->accel.cur_x_overflow & 0xff00) | 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 = (s3->accel.cur_x & 0xff) | ((val & 0x0f) << 8); + s3->accel.cur_x_overflow = (s3->accel.cur_x_overflow & 0xff) | (val << 8); s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; s3->accel.poly_x = s3->accel.poly_cx >> 20; - s3_log("[%04X:%08X] OUT PORTB=%04x, val=%04x.\n", CS, cpu_state.pc, port - 1, s3->accel.cur_x); + s3_log("[%04X:%08X] OUT PORTB=%04x, valx=%d, valxover=%d.\n", CS, cpu_state.pc, port - 1, s3->accel.cur_x, s3->accel.cur_x_overflow); break; case 0x854a: case 0x86ea: @@ -859,11 +879,13 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x8d48: case 0x8ee8: s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val; + s3->accel.destx_overflow = (s3->accel.destx_overflow & 0xff00) | val; s3->accel.point_1_updated = 1; break; case 0x8d49: case 0x8ee9: s3->accel.destx_distp = (s3->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); + s3->accel.destx_overflow = (s3->accel.destx_overflow & 0xff) | (val << 8); if (val & 0x20) s3->accel.destx_distp |= ~0x3fff; s3->accel.point_1_updated = 1; @@ -907,6 +929,7 @@ 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); + s3_log("[%04X:%08X] OUT PORTB=%04x, valmajx=%d.\n", CS, cpu_state.pc, port - 1, s3->accel.maj_axis_pcnt); break; case 0x954a: case 0x96ea: @@ -1289,7 +1312,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xb148: case 0xb2e8: s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); - if (s3->accel.multifunc[0xe] & 0x100) { + if ((s3->accel.multifunc[0xe] & 0x100) || (s3->chip >= S3_VISION964)) { s3->accel.b2e8_pix = 0; if (s3->bpp == 3) { if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { @@ -1331,7 +1354,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xb149: case 0xb2e9: s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); - if (s3->accel.multifunc[0xe] & 0x100) { + if ((s3->accel.multifunc[0xe] & 0x100) || (s3->chip >= S3_VISION964)) { s3->accel.b2e8_pix = 0; if (s3->bpp == 3) { if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { @@ -2951,7 +2974,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) break; case 0x40: - s3->enable_8514 = (val & 0x01); + s3->enable_8514 = val & 0x01; break; case 0x50: @@ -3047,6 +3070,8 @@ s3_out(uint16_t addr, uint8_t val, void *priv) svga->hwcursor.x /= 3; else if ((s3->chip <= S3_86C805) && s3->color_16bit) svga->hwcursor.x >>= 1; + else if ((s3->chip == S3_TRIO32) && ((svga->bpp == 15) || (svga->bpp == 16))) + svga->hwcursor.x >>= 1; break; case 0x4a: @@ -3157,9 +3182,9 @@ s3_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); if ((((svga->crtc[0x67] & 0xc) != 0xc) && (s3->chip >= S3_TRIO64V)) || (s3->chip < S3_TRIO64V)) - svga->ma_latch |= (s3->ma_ext << 16); + svga->memaddr_latch |= (s3->ma_ext << 16); } else { svga->fullchange = svga->monitor->mon_changeframecount; svga_recalctimings(svga); @@ -3481,7 +3506,7 @@ s3_recalctimings(svga_t *svga) } svga->hdisp = svga->hdisp_old; - svga->ma_latch |= (s3->ma_ext << 16); + svga->memaddr_latch |= (s3->ma_ext << 16); svga->lowres = (!!(svga->attrregs[0x10] & 0x40) && !(svga->crtc[0x3a] & 0x10)); @@ -3762,6 +3787,7 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_MIROCRYSTAL8S_805: case S3_MIROCRYSTAL10SD_805: + case S3_WINNER1000_805: case S3_PHOENIX_86C805: case S3_86C805_ONBOARD: svga->hdisp >>= 1; @@ -3930,6 +3956,7 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_MIROCRYSTAL8S_805: case S3_MIROCRYSTAL10SD_805: + case S3_WINNER1000_805: case S3_PHOENIX_86C805: case S3_86C805_ONBOARD: svga->hdisp >>= 1; @@ -4102,6 +4129,7 @@ s3_recalctimings(svga_t *svga) switch (s3->card_type) { case S3_MIROCRYSTAL8S_805: case S3_MIROCRYSTAL10SD_805: + case S3_WINNER1000_805: case S3_PHOENIX_86C805: case S3_SPEA_MIRAGE_86C805: case S3_86C805_ONBOARD: @@ -4354,7 +4382,7 @@ s3_trio64v_recalctimings(svga_t *svga) if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ { - svga->ma_latch |= (s3->ma_ext << 16); + svga->memaddr_latch |= (s3->ma_ext << 16); if (svga->crtc[0x51] & 0x30) svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; else if (svga->crtc[0x43] & 0x04) @@ -4402,9 +4430,9 @@ s3_trio64v_recalctimings(svga_t *svga) } else /*Streams mode*/ { if (s3->streams.buffer_ctrl & 1) - svga->ma_latch = s3->streams.pri_fb1 >> 2; + svga->memaddr_latch = s3->streams.pri_fb1 >> 2; else - svga->ma_latch = s3->streams.pri_fb0 >> 2; + svga->memaddr_latch = s3->streams.pri_fb0 >> 2; svga->hdisp = s3->streams.pri_w + 1; if (s3->streams.pri_h < svga->dispend) @@ -4463,6 +4491,7 @@ static void s3_updatemapping(s3_t *s3) { svga_t *svga = &s3->svga; + xga_t *xga = (xga_t *) svga->xga; if (s3->pci && !(s3->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { mem_mapping_disable(&svga->mapping); @@ -4479,6 +4508,10 @@ s3_updatemapping(s3_t *s3) /* Enhanced mode forces 64kb at 0xa0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) { + xga->on = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + } } else switch (svga->gdcreg[6] & 0xc) { /*VGA mapping*/ case 0x0: /*128k at A0000*/ @@ -4488,6 +4521,10 @@ s3_updatemapping(s3_t *s3) case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) { + xga->on = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + } break; case 0x8: /*32k at B0000*/ mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); @@ -5763,6 +5800,8 @@ 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 temp1 = 0x0000; + uint16_t temp2 = 0x0000; const uint16_t *vram_w = (uint16_t *) svga->vram; if (!s3->enable_8514) @@ -5774,7 +5813,7 @@ s3_accel_in_w(uint16_t port, void *priv) switch (s3->accel.cmd & 0x600) { case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 0x02)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) temp = (temp >> 8) | (temp << 8); @@ -5782,33 +5821,51 @@ s3_accel_in_w(uint16_t port, void *priv) s3->accel_start(8, 1, temp | (temp << 16), 0, s3); } else { if ((s3->bpp == 0) && s3->color_16bit) { - if (s3->accel.cur_x & 0x400) - temp = ((temp >> 8) | (temp << 8)) & 0xffff; - + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.cur_x & 0x400) + temp = (temp >> 8) | (temp << 8); + } s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } else s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); } } else { if ((s3->bpp == 0) && s3->color_16bit) { - if (s3->accel.cur_x & 0x400) - temp = ((temp >> 8) | (temp << 8)) & 0xffff; - + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.cur_x & 0x400) + temp = (temp >> 8) | (temp << 8); + } s3->accel_start(2, 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.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 0x02)) { 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); } else s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } else { - s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.cmd == 0x53b0) { + temp1 = vram_w[dword_remap_w(svga, s3->accel.dest + s3->accel.cx - s3->accel.minus) & (s3->vram_mask >> 1)]; + temp2 = vram_w[dword_remap_w(svga, s3->accel.dest + s3->accel.cx - s3->accel.minus + 1) & (s3->vram_mask >> 1)]; + if (s3->accel.cur_x & 0x400) { + temp = temp1 >> 8; + temp |= (temp2 >> 8) << 8; + } else { + temp = temp1 & 0xff; + temp |= ((temp2 & 0xff) << 8); + } + s3->accel_start(4, 1, 0xffffffff, temp | (temp << 16), s3); + } else + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + } else + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } break; @@ -7878,7 +7935,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi /*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)*/ - s3_log("CMD=%d, full=%04x, s3bpp=%x, clr=%d, clb=%d, sourcedisplay=%x, mmio=%02x, srcbase=%08x, dstbase=%08x, cpu=%04x, mix=%04x, count=%d, rd_mask=%04x, wrt_mask=%04x, width=%d, s=%d,%d, c=%d,%d, d=%d,%d, 16bitcolor=%x, frgdcolor=%04x, bkgdcolor=%04x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, curx=%d, cury=%d, cll=%d, b2e8pix=%x.\n", cmd, s3->accel.cmd, s3->bpp, clip_r, clip_b, vram_mask, svga->crtc[0x53] & 0x18, srcbase, dstbase, cpu_dat & 0xffff, mix_dat & 0xffff, count, rd_mask, wrt_mask, s3->width, s3->accel.sx, s3->accel.sy, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->color_16bit, frgd_color, bkgd_color, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.cur_x, s3->accel.cur_y, clip_l, s3->accel.b2e8_pix); + s3_log("CMD=%d, full=%04x, s3bpp=%x, clr=%d, clb=%d, sourcedisplay=%02x, mmio=%02x, srcbase=%08x, dstbase=%08x, cpu=%04x, mix=%04x, count=%d, rd_mask=%04x, wrt_mask=%04x, width=%d, s=%d,%d, c=%d,%d, d=%d,%d, 16bitcolor=%x, frgdcolor=%04x, bkgdcolor=%04x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, curx=%d, cury=%d, cll=%d, b2e8pix=%x.\n", cmd, s3->accel.cmd, s3->bpp, clip_r, clip_b, s3->accel.multifunc[0x0a] & 0xc4, svga->crtc[0x53] & 0x18, srcbase, dstbase, cpu_dat & 0xffff, mix_dat & 0xffff, count, rd_mask, wrt_mask, s3->width, s3->accel.sx, s3->accel.sy, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->color_16bit, frgd_color, bkgd_color, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.cur_x, s3->accel.cur_y, clip_l, s3->accel.b2e8_pix); switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ @@ -7989,18 +8046,30 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi case 1: /*Draw line*/ if (!cpu_input) { + s3->accel.rd_mask_16bit_check = 0; s3->accel.minus = 0; s3->accel.color_16bit_check_pixtrans = 0; 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->bpp == 0) && s3->color_16bit) - s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00); - else - s3->accel.rd_mask_16bit_check = 0; - if ((s3->bpp == 0) && s3->color_16bit && (s3->accel.cur_x & 0x400) && s3->accel.rd_mask_16bit_check) - s3->accel.minus = 0x400; + s3->accel.sy = s3->accel.maj_axis_pcnt; + if ((s3->bpp == 0) && s3->color_16bit) { + s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask; + if (s3->accel.rd_mask_16bit_check) { + if ((s3->accel.cur_x_overflow & 0xc00) == 0xc00) + s3->accel.start = 1; + else { + if (s3->accel.start) { + s3->accel.start = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.start = 0; + if (s3->accel.cur_x_overflow & 0x400) + s3->accel.minus = 0x400; + } + } + } + } if (s3_cpu_src(s3)) return; /*Wait for data from CPU*/ @@ -8009,7 +8078,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (s3->accel.cmd & 0x08) { /*Radial*/ if ((s3->bpp == 0) && s3->color_16bit) { if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.cur_x & 0x400) { + if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); frgd_color = (s3->accel.frgd_color_actual[1] << 8); bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); @@ -8076,11 +8145,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi cpu_dat >>= 16; if (!s3->accel.sy) { - if ((s3->bpp == 0) && s3->color_16bit) { - if (!(s3->accel.cur_x & 0x400)) - s3->accel.color_16bit_check = 1; - else + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) s3->accel.color_16bit_check = 0; + else + s3->accel.color_16bit_check = 1; } break; } @@ -8130,7 +8199,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.temp_cnt = 16; if ((s3->bpp == 0) && s3->color_16bit) { if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.cur_x & 0x400) { + if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); frgd_color = (s3->accel.frgd_color_actual[1] << 8); bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); @@ -8146,7 +8215,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } else { if ((s3->bpp == 0) && s3->color_16bit) { if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.cur_x & 0x400) { + if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); frgd_color = (s3->accel.frgd_color_actual[1] << 8); bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); @@ -8161,12 +8230,18 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } } - while (count-- && s3->accel.sy >= 0) { + if (!s3->accel.b2e8_pix) + s3_log("CMDFULL=%04x, FRGDMIX=%x, FRGDCOLR=%04x, RDMASK=%04x, MINUS=%d, WRTMASK=%04X, MIX=%04x, CX=%d, CY=%d, SX=%d, SY=%d, PIXCNTL=%02x, 16BITCOLOR=%x, RDCHECK=%x, CLIPL=%d, CLIPR=%d, CLIPT=%d, CLIPB=%d.\n", s3->accel.cmd, frgd_mix, s3->accel.frgd_color, rd_mask, s3->accel.minus, wrt_mask, mix_dat & 0xffff, s3->accel.cx, s3->accel.cy, s3->accel.sx, s3->accel.sy, s3->accel.multifunc[0x0a] & 0xc4, s3->accel.color_16bit_check, s3->accel.rd_mask_16bit_check, clip_l, clip_r, clip_t, clip_b); + + 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.minus) + s3_log("Total pixel cx=%d, cy=%d.\n", s3->accel.cx - s3->accel.minus, s3->accel.cy); + 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: @@ -8228,11 +8303,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi cpu_dat >>= 16; if (!s3->accel.sy) { - if ((s3->bpp == 0) && s3->color_16bit) { - if (!(s3->accel.cur_x & 0x400)) - s3->accel.color_16bit_check = 1; - else + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) s3->accel.color_16bit_check = 0; + else + s3->accel.color_16bit_check = 1; } break; } @@ -8279,8 +8354,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi case 2: /*Rectangle fill*/ if (!cpu_input) /*!cpu_input is trigger to start operation*/ { - s3->accel.start = 0; s3->accel.minus = 0; + s3->accel.mix_dat_upper = 0; s3->accel.color_16bit_check_pixtrans = 0; s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; @@ -8290,17 +8365,43 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.dest = dstbase + s3->accel.cy * s3->width; if ((s3->bpp == 0) && s3->color_16bit) { - s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00); + s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask; if (s3->accel.rd_mask_16bit_check) { - s3->accel.start = 1; - if (s3->accel.cur_x & 0x400) { - s3->accel.minus = 0x400; - if ((s3->accel.cmd == 0x41b3) && (frgd_mix == 0)) - s3->accel.minus = 0; + if (s3->accel.cmd == 0x41b3) { + if (frgd_mix == 0) { + if (!(s3->accel.cur_x & 0x400)) + s3->accel.color_16bit_check = 0; + } else { + if ((s3->accel.cur_x_overflow & 0xc00) == 0xc00) + s3->accel.start = 1; + else { + if (s3->accel.start) { + s3->accel.start = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.start = 0; + if (s3->accel.cur_x_overflow & 0x400) + s3->accel.minus = 0x400; + } + } + } + } else { + if ((s3->accel.cur_x_overflow & 0xc00) == 0xc00) + s3->accel.start = 1; + else { + if (s3->accel.start) { + s3->accel.start = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.start = 0; + if (s3->accel.cur_x_overflow & 0x400) + s3->accel.minus = 0x400; + } + } } } else { if (s3->accel.cmd & 0x100) { - if (!(s3->accel.cmd & 0x200)) { + if (mix_mask == 0x80) { if (s3->accel.cur_x & 0x400) s3->accel.minus = 0x400; else @@ -8325,24 +8426,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } } - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Pattern on pixtrans (911/924)*/ count = s3->accel.maj_axis_pcnt + 1; s3->accel.temp_cnt = 16; if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.cur_x & 0x400) { - if (s3->accel.start) { - s3->accel.minus = 0x400; - s3->accel.start = 0; - } + if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); frgd_color = (s3->accel.frgd_color_actual[1] << 8); bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); } else { - if (s3->accel.start) { - s3->accel.minus = 0; - s3->accel.start = 0; - } wrt_mask = s3->accel.wrt_mask_actual[0]; frgd_color = s3->accel.frgd_color_actual[0]; bkgd_color = s3->accel.bkgd_color_actual[0]; @@ -8355,7 +8447,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (s3->accel.cmd == 0x41b3) { if (frgd_mix != 0) { if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.cur_x & 0x400) { + if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); frgd_color = (s3->accel.frgd_color_actual[1] << 8); bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); @@ -8367,46 +8459,41 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi rd_mask &= 0x00ff; } else if (!s3->accel.rd_mask_16bit_check && (s3->accel.cur_x & 0x400)) break; + } else { + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) { + wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); + frgd_color = (s3->accel.frgd_color_actual[1] << 8); + bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); + } else { + wrt_mask = s3->accel.wrt_mask_actual[0]; + frgd_color = s3->accel.frgd_color_actual[0]; + bkgd_color = s3->accel.bkgd_color_actual[0]; + s3->accel.mix_dat_upper = !!(mix_dat & 0xff00); + } + rd_mask &= 0x00ff; + } } } else { if (s3->accel.rd_mask_16bit_check) { - rd_mask &= 0x00ff; - if (s3->accel.cmd == 0x53b3) { - if (clip_l & 0x400) { - if (s3->accel.start) { - s3->accel.minus = 0x400; - s3->accel.start = 0; - } - wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); - frgd_color = (s3->accel.frgd_color_actual[1] << 8); - bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); - } else { - if (s3->accel.start) { - s3->accel.minus = 0; - s3->accel.start = 0; - } - wrt_mask = s3->accel.wrt_mask_actual[0]; - frgd_color = s3->accel.frgd_color_actual[0]; - bkgd_color = s3->accel.bkgd_color_actual[0]; - } + if (s3->accel.minus) { + wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); + frgd_color = (s3->accel.frgd_color_actual[1] << 8); + bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); } else { - if (s3->accel.cur_x & 0x400) { - wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); - frgd_color = (s3->accel.frgd_color_actual[1] << 8); - bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); - } else { - wrt_mask = s3->accel.wrt_mask_actual[0]; - frgd_color = s3->accel.frgd_color_actual[0]; - bkgd_color = s3->accel.bkgd_color_actual[0]; - } + wrt_mask = s3->accel.wrt_mask_actual[0]; + frgd_color = s3->accel.frgd_color_actual[0]; + bkgd_color = s3->accel.bkgd_color_actual[0]; } + rd_mask &= 0x00ff; } else { if ((s3_cpu_src(s3)) && !(s3->accel.cmd & 0x200)) { s3_log("FIXME: S3 911/924 15/16bpp documentation needed.\n"); } else { - if (!cpu_input && (s3->accel.cur_x & 0x400)) + if (!cpu_input && (s3->accel.cur_x & 0x400)) { + s3_log("No Input.\n"); break; - else if (cpu_input && (s3->accel.cmd == 0x53b3) && (s3->accel.cur_x & 0x400)) + } else if (cpu_input && (s3->accel.cmd == 0x53b3) && (s3->accel.cur_x & 0x400)) break; } } @@ -8414,6 +8501,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } } + s3_log("CMDFULL=%04x, FRGDSEL=%x, BKGDSEL=%x, FRGDMIX=%02x, BKGDMIX=%02x, MASKCHECK=%x, RDMASK=%04x, MINUS=%d, WRTMASK=%04X, MIX=%04x, CX=%d, CY=%d, DX=%d, DY=%d, SX=%d, SY=%d, PIXCNTL=%02x, 16BITCOLOR=%x, RDCHECK=%x, CLIPL=%d, CLIPR=%d, OVERFLOW=%d, pitch=%d.\n", s3->accel.cmd, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.bkgd_mix & 0x0f, s3->accel.rd_mask_16bit_check, rd_mask, s3->accel.minus, wrt_mask, mix_dat & 0xffff, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->accel.sx, s3->accel.sy, s3->accel.multifunc[0x0a] & 0xc4, s3->accel.color_16bit_check, s3->accel.rd_mask_16bit_check, clip_l, clip_r, (s3->accel.destx_overflow & 0xc00) == 0xc00, s3->width); + while (count-- && (s3->accel.sy >= 0)) { if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { mix_dat >>= 16; @@ -8535,15 +8624,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (cpu_input) { if (s3->accel.sy < 0) { if ((s3->bpp == 0) && s3->color_16bit) { - if ((s3->accel.cmd == 0x53b3) && !s3->accel.b2e8_pix) { - if (!(clip_l & 0x400)) - s3->accel.color_16bit_check = 1; - else + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) s3->accel.color_16bit_check = 0; - } else { - if (!(s3->accel.cur_x & 0x400)) - s3->accel.color_16bit_check = 1; else + s3->accel.color_16bit_check = 1; + + if ((s3->accel.cmd == 0x41b3) && (frgd_mix == 0)) s3->accel.color_16bit_check = 0; } } @@ -8556,10 +8643,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } if (s3->accel.sy < 0) { if ((s3->bpp == 0) && s3->color_16bit) { - if (!(s3->accel.cur_x & 0x400)) - s3->accel.color_16bit_check = 1; - else - s3->accel.color_16bit_check = 0; + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) + s3->accel.color_16bit_check = 0; + else + s3->accel.color_16bit_check = 1; + } } s3->accel.cur_x = s3->accel.cx; s3->accel.cur_y = s3->accel.cy; @@ -8669,25 +8758,39 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi case 6: /*BitBlt*/ if (!cpu_input) { /*!cpu_input is trigger to start operation*/ s3->accel.minus = 0; + s3->accel.minus_src_24bpp = 0; 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.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00); - if ((s3->bpp == 0) && s3->color_16bit && (s3->accel.destx_distp & 0x400) && s3->accel.rd_mask_16bit_check) - s3->accel.minus = 0x400; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + + if ((s3->bpp == 0) && s3->color_16bit) { + s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask; + if (s3->accel.rd_mask_16bit_check) { + if (!(clip_r & 0x400)) + s3->accel.start = 1; + else { + if (s3->accel.start) { + s3->accel.start = 0; + s3->accel.minus = 0x400; + } else { + s3->accel.start = 0; + if (s3->accel.destx_distp & 0x400) + s3->accel.minus = 0x400; + } + } + } + } if (s3->accel.destx_distp & 0x400) { s3_log("BitBLT + 1024 FULLCMD=%04x: frgdcolor=%04x, s=%d,%d, d=%d,%d, frmix=%x, bkmix=%x, pixcntl=%02x.\n", s3->accel.cmd, frgd_color, s3->accel.sx, s3->accel.sy, s3->accel.dx, s3->accel.dy, frgd_mix, bkgd_mix, s3->accel.multifunc[0xa] & 0xc0); } else { s3_log("BitBLT + 0 FULLCMD=%04x: frgdcolor=%04x, s=%d,%d, d=%d,%d, frmix=%x, bkmix=%x, pixcntl=%02x.\n", s3->accel.cmd, frgd_color, s3->accel.sx, s3->accel.sy, s3->accel.dx, s3->accel.dy, frgd_mix, bkgd_mix, s3->accel.multifunc[0xa] & 0xc0); } - - 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; s3_log("BitBLT: D(%d,%d).\n", s3->accel.dx, s3->accel.dy); @@ -8698,7 +8801,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->bpp == 0) && s3->color_16bit) { if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.destx_distp & 0x400) { + if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); frgd_color = (s3->accel.frgd_color_actual[1] << 8); bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); @@ -8712,7 +8815,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } + s3_log("CMDFULL=%04x, FRGDSEL=%x, BKGDSEL=%x, FRGDMIX=%02x, BKGDMIX=%02x, MASKCHECK=%x, RDMASK=%04x, MINUS=%d, WRTMASK=%04X, MIX=%04x, CX=%d, CY=%d, DX=%d, DY=%d, SX=%d, SY=%d, PIXCNTL=%02x, 16BITCOLOR=%x, RDCHECK=%x, CLIPL=%d, CLIPR=%d, OVERFLOW=%d, pitch=%d.\n", s3->accel.cmd, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.bkgd_mix & 0x0f, s3->accel.rd_mask_16bit_check, rd_mask, s3->accel.minus, wrt_mask, mix_dat & 0xffff, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->accel.sx, s3->accel.sy, s3->accel.multifunc[0x0a] & 0xc4, s3->accel.color_16bit_check, s3->accel.rd_mask_16bit_check, clip_l, clip_r, (s3->accel.destx_overflow & 0xc00) == 0xc00, s3->width); + if (!cpu_input && (frgd_mix == 3) && !vram_mask && !(s3->accel.multifunc[0xe] & 0x100) && ((s3->accel.cmd & 0xa0) == 0xa0) && ((s3->accel.frgd_mix & 0xf) == 7) && ((s3->accel.bkgd_mix & 0xf) == 7)) { + s3_log("Special BitBLT.\n"); while (1) { if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) { READ(s3->accel.src + s3->accel.cx - s3->accel.minus, src_dat); @@ -8728,6 +8834,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi 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; @@ -8742,11 +8849,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.sy--; if (s3->accel.sy < 0) { - if ((s3->bpp == 0) && s3->color_16bit) { - if (!(s3->accel.destx_distp & 0x400)) - s3->accel.color_16bit_check = 1; - else + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) s3->accel.color_16bit_check = 0; + else + s3->accel.color_16bit_check = 1; } s3->accel.destx_distp = s3->accel.dx; s3->accel.desty_axstp = s3->accel.dy; @@ -8755,6 +8862,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } } } else { + s3_log("Normal blit, srcbase=%08x, dstbase=%08x, full=%04x, wrt_mask=%08x, extmultifunc0e=%03x, frgdmixval=%02x.\n", srcbase, dstbase, s3->accel.cmd, wrt_mask, s3->accel.multifunc[0x0e] & 0x180, s3->accel.frgd_mix); while (count-- && (s3->accel.sy >= 0)) { if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) { if (vram_mask && (s3->accel.cmd & 0x10)) { @@ -8824,7 +8932,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cx--; s3->accel.dx--; } - s3->accel.dx &= 0xfff; + if (s3->accel.rd_mask_16bit_check) + s3->accel.dx &= 0x7ff; + else + s3->accel.dx &= 0xfff; + s3->accel.sx--; if (s3->accel.sx < 0) { if (s3->accel.cmd & 0x20) { @@ -8843,6 +8955,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cy--; s3->accel.dy--; } + s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; @@ -8850,21 +8963,24 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (cpu_input) { if (s3->accel.sy < 0) { - if ((s3->bpp == 0) && s3->color_16bit) { - if (!(s3->accel.destx_distp & 0x400)) - s3->accel.color_16bit_check = 1; - else + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) s3->accel.color_16bit_check = 0; + else + s3->accel.color_16bit_check = 1; } } return; } if (s3->accel.sy < 0) { - if ((s3->bpp == 0) && s3->color_16bit) { - if (!(s3->accel.destx_distp & 0x400)) - s3->accel.color_16bit_check = 1; + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) + s3->accel.color_16bit_check = 0; else + s3->accel.color_16bit_check = 1; + + if (s3->accel.mix_dat_upper && !vram_mask && (frgd_mix == 3)) s3->accel.color_16bit_check = 0; } s3->accel.destx_distp = s3->accel.dx; @@ -9735,6 +9851,11 @@ s3_init(const device_t *info) chip = S3_86C801; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); break; + case S3_WINNER1000_805: + bios_fn = ROM_WINNER1000_805; + chip = S3_86C801; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); + break; case S3_86C805_ONBOARD: bios_fn = NULL; chip = S3_86C805; @@ -10034,6 +10155,12 @@ s3_init(const device_t *info) NULL); } } + svga->read = s3_read; + svga->readw = s3_readw; + svga->readl = s3_readl; + svga->write = s3_write; + svga->writew = s3_writew; + svga->writel = s3_writel; mem_mapping_set_handler(&svga->mapping, s3_read, s3_readw, s3_readl, s3_write, s3_writew, s3_writel); mem_mapping_set_p(&svga->mapping, s3); @@ -10187,6 +10314,7 @@ s3_init(const device_t *info) case S3_SPEA_MIRAGE_86C801: case S3_SPEA_MIRAGE_86C805: + case S3_WINNER1000_805: svga->decode_mask = (2 << 20) - 1; stepping = 0xa2; /*86C801/86C805*/ s3->id = stepping; @@ -10485,6 +10613,12 @@ s3_phoenix_86c80x_available(void) return rom_present(ROM_PHOENIX_86C80X); } +static int +s3_winner1000_805_available(void) +{ + return rom_present(ROM_WINNER1000_805); +} + static int s3_mirocrystal_8s_805_available(void) { @@ -10874,6 +11008,20 @@ const device_t s3_spea_mirage_86c801_isa_device = { .config = s3_9fx_config }; +const device_t s3_winner1000_805_isa_device = { + .name = "S3 86c805 ISA (ELSA Winner 1000)", + .internal_name = "winner1000_805_isa", + .flags = DEVICE_ISA16, + .local = S3_WINNER1000_805, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + .available = s3_winner1000_805_available, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_9fx_config +}; + const device_t s3_86c805_onboard_vlb_device = { .name = "S3 86c805 VLB On-Board", .internal_name = "px_s3_805_onboard_vlb", diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 1b61c02d5..87c2b4cd6 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -37,6 +37,7 @@ #include <86box/video.h> #include <86box/i2c.h> #include <86box/vid_ddc.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> @@ -211,6 +212,7 @@ typedef struct virge_t { uint8_t pci_regs[256]; uint8_t pci_slot; + uint8_t type; int chip; int bilinear_enabled; @@ -688,10 +690,10 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); if ((svga->crtc[0x67] & 0xc) != 0xc) - svga->ma_latch |= (virge->ma_ext << 16); + svga->memaddr_latch |= (virge->ma_ext << 16); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -890,7 +892,7 @@ s3_virge_recalctimings(svga_t *svga) } if ((svga->crtc[0x67] & 0xc) != 0xc) { /*VGA mode*/ - svga->ma_latch |= (virge->ma_ext << 16); + svga->memaddr_latch |= (virge->ma_ext << 16); if (svga->crtc[0x51] & 0x30) svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; else if (svga->crtc[0x43] & 0x04) @@ -935,9 +937,9 @@ s3_virge_recalctimings(svga_t *svga) } else { /*Streams mode*/ if (virge->chip < S3_VIRGEGX2) { if (virge->streams.buffer_ctrl & 1) - svga->ma_latch = virge->streams.pri_fb1 >> 2; + svga->memaddr_latch = virge->streams.pri_fb1 >> 2; else - svga->ma_latch = virge->streams.pri_fb0 >> 2; + svga->memaddr_latch = virge->streams.pri_fb0 >> 2; svga->hdisp = virge->streams.pri_w + 1; if (virge->streams.pri_h < svga->dispend) @@ -946,7 +948,7 @@ s3_virge_recalctimings(svga_t *svga) svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x; svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y; } else { - svga->ma_latch |= (virge->ma_ext << 16); + svga->memaddr_latch |= (virge->ma_ext << 16); if (svga->crtc[0x51] & 0x30) svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; else if (svga->crtc[0x43] & 0x04) @@ -1035,6 +1037,7 @@ static void s3_virge_updatemapping(virge_t *virge) { svga_t *svga = &virge->svga; + xga_t *xga = (xga_t *) svga->xga; if (!(virge->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { mem_mapping_disable(&svga->mapping); @@ -1052,6 +1055,10 @@ s3_virge_updatemapping(virge_t *virge) case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) { + xga->on = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + } break; case 0x8: /*32k at B0000*/ mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); @@ -5140,9 +5147,11 @@ s3_virge_init(const device_t *info) virge_t *virge = (virge_t *) calloc(1, sizeof(virge_t)); reset_state = calloc(1, sizeof(virge_t)); + virge->type = (info->local & 0xff); + virge->bilinear_enabled = device_get_config_int("bilinear"); virge->dithering_enabled = device_get_config_int("dithering"); - if (info->local >= S3_VIRGE_GX2) + if (virge->type >= S3_VIRGE_GX2) virge->memory_size = 4; else virge->memory_size = device_get_config_int("memory"); @@ -5150,7 +5159,7 @@ s3_virge_init(const device_t *info) virge->onboard = !!(info->local & 0x100); if (!virge->onboard) - switch (info->local) { + switch (virge->type) { case S3_VIRGE_325: bios_fn = ROM_VIRGE_325; break; @@ -5197,7 +5206,7 @@ s3_virge_init(const device_t *info) virge->svga.hwcursor.cur_ysize = 64; if (bios_fn != NULL) { - if (info->local == S3_VIRGE_GX2) + if (virge->type == S3_VIRGE_GX2) rom_init(&virge->bios_rom, bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); else rom_init(&virge->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -5251,7 +5260,7 @@ s3_virge_init(const device_t *info) virge->virge_id = 0xe1; virge->is_agp = !!(info->flags & DEVICE_AGP); - switch (info->local) { + switch (virge->type) { case S3_VIRGE_325: case S3_DIAMOND_STEALTH3D_2000: case S3_MIROCRYSTAL_3D: @@ -5356,7 +5365,7 @@ s3_virge_init(const device_t *info) default: break; } - if (info->local == S3_VIRGE_GX) + if (virge->type == S3_VIRGE_GX) virge->svga.crtc[0x36] |= (1 << 2); } diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index d771260ed..d67b13c0d 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -151,14 +151,14 @@ typedef struct sigma_t { uint8_t sigmamode; /* Mode control register [0x2D8] */ - uint16_t ma, maback; + uint16_t memaddr, memaddr_backup; int crtcreg; /* CRTC: Real selected register */ int linepos, displine; - int sc, vc; + int scanline, vc; int cgadispon; - int con, coff, cursoron, cgablink; + int cursorvisible, cursoron, cgablink; int vsynctime, vadj; int oddeven; @@ -414,23 +414,23 @@ 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); + uint16_t cursoraddr = (sigma->crtc[15] | (sigma->crtc[14] << 8)); + uint16_t memaddr = ((sigma->memaddr & 0x3FFF) << 1); int drawcursor; uint32_t cols[4]; - const uint8_t *vram = sigma->vram + (ma << 1); + const uint8_t *vram = sigma->vram + (memaddr << 1); - ca = ca << 1; + cursoraddr = cursoraddr << 1; if (sigma->sigma_ctl & CTL_CURSOR) - ++ca; - ca &= 0x3fff; + ++cursoraddr; + cursoraddr &= 0x3fff; /* The Sigma 400 seems to use screen widths stated in words (40 for 80-column, 20 for 40-column) */ for (uint32_t x = 0; x < (sigma->crtc[1] << 1); x++) { chr = vram[x << 1]; attr = vram[(x << 1) + 1]; - drawcursor = ((ma == ca) && sigma->con && sigma->cursoron); + drawcursor = ((memaddr == cursoraddr) && sigma->cursorvisible && sigma->cursoron); if (!(sigma->sigmamode & MODE_NOBLINK)) { cols[1] = (attr & 15) | 16; @@ -445,22 +445,22 @@ sigma_text80(sigma_t *sigma) if (drawcursor) { for (uint8_t c = 0; c < 8; c++) { if (sigma->sigmamode & MODE_FONT16) - buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xf; + buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][sigma->scanline & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xf; else - buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdat[chr][sigma->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xf; + buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdat[chr][sigma->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xf; } } else { for (uint8_t c = 0; c < 8; c++) { if (sigma->sigmamode & MODE_FONT16) - buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][sigma->scanline & 15] & (1 << (c ^ 7))) ? 1 : 0]; else - buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdat[chr][sigma->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdat[chr][sigma->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0]; } } - ++ma; + ++memaddr; } - sigma->ma += sigma->crtc[1]; + sigma->memaddr += sigma->crtc[1]; } /* Render a line in 40-column text mode */ @@ -469,23 +469,23 @@ 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); + uint16_t cursoraddr = (sigma->crtc[15] | (sigma->crtc[14] << 8)); + uint16_t memaddr = ((sigma->memaddr & 0x3FFF) << 1); int drawcursor; uint32_t cols[4]; - const uint8_t *vram = sigma->vram + ((ma << 1) & 0x3FFF); + const uint8_t *vram = sigma->vram + ((memaddr << 1) & 0x3FFF); - ca = ca << 1; + cursoraddr = cursoraddr << 1; if (sigma->sigma_ctl & CTL_CURSOR) - ++ca; - ca &= 0x3fff; + ++cursoraddr; + cursoraddr &= 0x3fff; /* The Sigma 400 seems to use screen widths stated in words (40 for 80-column, 20 for 40-column) */ for (uint32_t x = 0; x < (sigma->crtc[1] << 1); x++) { chr = vram[x << 1]; attr = vram[(x << 1) + 1]; - drawcursor = ((ma == ca) && sigma->con && sigma->cursoron); + drawcursor = ((memaddr == cursoraddr) && sigma->cursorvisible && sigma->cursoron); if (!(sigma->sigmamode & MODE_NOBLINK)) { cols[1] = (attr & 15) | 16; @@ -499,24 +499,24 @@ sigma_text40(sigma_t *sigma) if (drawcursor) { for (uint8_t c = 0; c < 8; c++) { - buffer32->line[sigma->displine][(x << 4) + 2 * c + 8] = buffer32->line[sigma->displine][(x << 4) + 2 * c + 9] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xf; + buffer32->line[sigma->displine][(x << 4) + 2 * c + 8] = buffer32->line[sigma->displine][(x << 4) + 2 * c + 9] = cols[(fontdatm[chr][sigma->scanline & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xf; } } else { for (uint8_t c = 0; c < 8; c++) { - buffer32->line[sigma->displine][(x << 4) + 2 * c + 8] = buffer32->line[sigma->displine][(x << 4) + 2 * c + 9] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; + buffer32->line[sigma->displine][(x << 4) + 2 * c + 8] = buffer32->line[sigma->displine][(x << 4) + 2 * c + 9] = cols[(fontdatm[chr][sigma->scanline & 15] & (1 << (c ^ 7))) ? 1 : 0]; } } - ma++; + memaddr++; } - sigma->ma += sigma->crtc[1]; + sigma->memaddr += sigma->crtc[1]; } /* Draw a line in the 640x400 graphics mode */ static void sigma_gfx400(sigma_t *sigma) { - const uint8_t *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 3) * 0x2000]; + const uint8_t *vram = &sigma->vram[((sigma->memaddr << 1) & 0x1FFF) + (sigma->scanline & 3) * 0x2000]; uint8_t plane[4]; uint8_t col; @@ -532,7 +532,7 @@ sigma_gfx400(sigma_t *sigma) buffer32->line[sigma->displine][(x << 3) + c + 8] = col; } if (x & 1) - ++sigma->ma; + ++sigma->memaddr; } } @@ -544,7 +544,7 @@ sigma_gfx400(sigma_t *sigma) static void sigma_gfx200(sigma_t *sigma) { - const uint8_t *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000]; + const uint8_t *vram = &sigma->vram[((sigma->memaddr << 1) & 0x1FFF) + (sigma->scanline & 2) * 0x1000]; uint8_t plane[4]; uint8_t col; @@ -561,7 +561,7 @@ sigma_gfx200(sigma_t *sigma) } if (x & 1) - ++sigma->ma; + ++sigma->memaddr; } } @@ -569,7 +569,7 @@ sigma_gfx200(sigma_t *sigma) static void sigma_gfx4col(sigma_t *sigma) { - const uint8_t *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000]; + const uint8_t *vram = &sigma->vram[((sigma->memaddr << 1) & 0x1FFF) + (sigma->scanline & 2) * 0x1000]; uint8_t plane[4]; uint8_t mask; uint8_t col; @@ -592,7 +592,7 @@ sigma_gfx4col(sigma_t *sigma) } if (x & 1) - ++sigma->ma; + ++sigma->memaddr; } } @@ -604,15 +604,15 @@ sigma_poll(void *priv) int c; int oldvc; uint32_t cols[4]; - int oldsc; + int scanline_old; if (!sigma->linepos) { timer_advance_u64(&sigma->timer, sigma->dispofftime); sigma->sigmastat |= STATUS_RETR_H; sigma->linepos = 1; - oldsc = sigma->sc; + scanline_old = sigma->scanline; if ((sigma->crtc[8] & 3) == 3) - sigma->sc = ((sigma->sc << 1) + sigma->oddeven) & 7; + sigma->scanline = ((sigma->scanline << 1) + sigma->oddeven) & 7; if (sigma->cgadispon) { if (sigma->displine < sigma->firstline) { sigma->firstline = sigma->displine; @@ -660,8 +660,8 @@ sigma_poll(void *priv) video_process_8(x, sigma->displine); - sigma->sc = oldsc; - if (sigma->vc == sigma->crtc[7] && !sigma->sc) + sigma->scanline = scanline_old; + if (sigma->vc == sigma->crtc[7] && !sigma->scanline) sigma->sigmastat |= STATUS_RETR_V; sigma->displine++; if (sigma->displine >= 560) @@ -674,25 +674,24 @@ sigma_poll(void *priv) if (!sigma->vsynctime) sigma->sigmastat &= ~STATUS_RETR_V; } - if (sigma->sc == (sigma->crtc[11] & 31) || ((sigma->crtc[8] & 3) == 3 && sigma->sc == ((sigma->crtc[11] & 31) >> 1))) { - sigma->con = 0; - sigma->coff = 1; + if (sigma->scanline == (sigma->crtc[11] & 31) || ((sigma->crtc[8] & 3) == 3 && sigma->scanline == ((sigma->crtc[11] & 31) >> 1))) { + sigma->cursorvisible = 0; } - if ((sigma->crtc[8] & 3) == 3 && sigma->sc == (sigma->crtc[9] >> 1)) - sigma->maback = sigma->ma; + if ((sigma->crtc[8] & 3) == 3 && sigma->scanline == (sigma->crtc[9] >> 1)) + sigma->memaddr_backup = sigma->memaddr; if (sigma->vadj) { - sigma->sc++; - sigma->sc &= 31; - sigma->ma = sigma->maback; + sigma->scanline++; + sigma->scanline &= 31; + sigma->memaddr = sigma->memaddr_backup; sigma->vadj--; if (!sigma->vadj) { sigma->cgadispon = 1; - sigma->ma = sigma->maback = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; - sigma->sc = 0; + sigma->memaddr = sigma->memaddr_backup = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; + sigma->scanline = 0; } - } else if (sigma->sc == sigma->crtc[9]) { - sigma->maback = sigma->ma; - sigma->sc = 0; + } else if (sigma->scanline == sigma->crtc[9]) { + sigma->memaddr_backup = sigma->memaddr; + sigma->scanline = 0; oldvc = sigma->vc; sigma->vc++; sigma->vc &= 127; @@ -706,7 +705,7 @@ sigma_poll(void *priv) if (!sigma->vadj) sigma->cgadispon = 1; if (!sigma->vadj) - sigma->ma = sigma->maback = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; + sigma->memaddr = sigma->memaddr_backup = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; if ((sigma->crtc[10] & 0x60) == 0x20) sigma->cursoron = 0; else @@ -769,14 +768,14 @@ sigma_poll(void *priv) sigma->oddeven ^= 1; } } else { - sigma->sc++; - sigma->sc &= 31; - sigma->ma = sigma->maback; + sigma->scanline++; + sigma->scanline &= 31; + sigma->memaddr = sigma->memaddr_backup; } if (sigma->cgadispon) sigma->sigmastat &= ~STATUS_RETR_H; - if (sigma->sc == (sigma->crtc[10] & 31) || ((sigma->crtc[8] & 3) == 3 && sigma->sc == ((sigma->crtc[10] & 31) >> 1))) - sigma->con = 1; + if (sigma->scanline == (sigma->crtc[10] & 31) || ((sigma->crtc[8] & 3) == 3 && sigma->scanline == ((sigma->crtc[10] & 31) >> 1))) + sigma->cursorvisible = 1; } } @@ -890,7 +889,7 @@ device_config_t sigma_config[] = { }, { .name = "bios_addr", - .description = "BIOS Address", + .description = "BIOS address", .type = CONFIG_HEX20, .default_string = NULL, .default_int = 0xc0000, diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 86a57c00e..113a8984f 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -280,9 +280,11 @@ svga_out(uint16_t addr, uint8_t val, void *priv) case 0x3c2: svga->miscout = val; svga->vidclock = val & 4; - io_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->priv); - if (!(val & 1)) - io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->priv); + if (svga->priv_parent == NULL) { + io_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->priv); + if (!(val & 1)) + io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->priv); + } svga_recalctimings(svga); break; case 0x3c3: @@ -402,6 +404,10 @@ svga_out(uint16_t addr, uint8_t val, void *priv) case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) { + xga->on = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + } break; case 0x8: /*32k at B0000*/ mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); @@ -693,15 +699,21 @@ svga_recalctimings(svga_t *svga) double disptime_xga = 0.0; #ifdef ENABLE_SVGA_LOG int vsyncend; - int vblankend; - int hdispstart; int hdispend; + int hdispstart; int hsyncstart; int hsyncend; #endif int old_monitor_overscan_x = svga->monitor->mon_overscan_x; int old_monitor_overscan_y = svga->monitor->mon_overscan_y; + if (svga->adv_flags & FLAG_PRECISETIME) { +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } + svga->vtotal = svga->crtc[6]; svga->dispend = svga->crtc[0x12]; svga->vsyncstart = svga->crtc[0x10]; @@ -754,7 +766,7 @@ svga_recalctimings(svga_t *svga) svga->interlace = 0; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); svga->ca_adj = 0; svga->rowcount = svga->crtc[9] & 0x1f; @@ -781,13 +793,6 @@ svga_recalctimings(svga_t *svga) else svga->render = svga_render_text_80; - if (xga_active && (svga->xga != NULL)) { - if (xga->on) { - svga_log("XGA on=%d, base=%05x, ap=%x.\n", xga->on, svga->mapping.base, xga->aperture_cntl); - if ((svga->mapping.base == 0xb8000) && (xga->aperture_cntl >= 1)) /*Some operating systems reset themselves with ctrl-alt-del by going into text mode.*/ - xga->on = 0; - } - } svga->hdisp_old = svga->hdisp; } else { svga->hdisp_old = svga->hdisp; @@ -801,14 +806,15 @@ svga_recalctimings(svga_t *svga) } else if ((svga->gdcreg[5] & 0x60) == 0x20) { if (svga->seqregs[1] & 8) { /*Low res (320)*/ svga->render = svga_render_2bpp_lowres; - svga_log("2 bpp low res\n"); + svga_log("2 bpp low res.\n"); } else svga->render = svga_render_2bpp_highres; } else { svga->map8 = svga->pallook; - if (svga->lowres) /*Low res (320)*/ + if (svga->lowres) { /*Low res (320)*/ svga->render = svga_render_8bpp_lowres; - else + svga_log("8 bpp low res.\n"); + } else svga->render = svga_render_8bpp_highres; } } else { @@ -911,7 +917,17 @@ svga_recalctimings(svga_t *svga) if (xga_active && (svga->xga != NULL)) xga_recalctimings(svga); - if (!svga->hoverride) { + svga->vblankend = (svga->vblankstart & 0xffffff80) | (svga->crtc[0x16] & 0x7f); + if (svga->vblankend <= svga->vblankstart) + svga->vblankend += 0x00000080; + + if (svga->hoverride || svga->override) { + if (svga->hdisp >= 2048) + svga->monitor->mon_overscan_x = 0; + + svga->y_add = (svga->monitor->mon_overscan_y >> 1); + svga->left_overscan = svga->x_add = (svga->monitor->mon_overscan_x >> 1); + } else { uint32_t dot = svga->hblankstart; uint32_t adj_dot = svga->hblankstart; /* Verified with both the Voodoo 3 and the S3 cards: compare 7 bits if bit 7 is set, @@ -919,7 +935,9 @@ svga_recalctimings(svga_t *svga) uint32_t eff_mask = (svga->hblank_end_val & ~0x0000003f) ? svga->hblank_end_mask : 0x0000003f; svga->hblank_sub = 0; - svga_log("HDISP=%d, CRTC1+1=%d, Blank: %04i-%04i, Total: %04i, Mask: %02X, ADJ_DOT=%04i.\n", svga->hdisp, svga->crtc[1] + 1, svga->hblankstart, svga->hblank_end_val, + svga_log("HDISP=%d, CRTC1+1=%d, Blank: %04i-%04i, Total: %04i, " + "Mask: %02X, ADJ_DOT=%04i.\n", svga->hdisp, svga->crtc[1] + 1, + svga->hblankstart, svga->hblank_end_val, svga->htotal, eff_mask, adj_dot); while (adj_dot < (svga->htotal << 1)) { @@ -929,7 +947,10 @@ svga_recalctimings(svga_t *svga) if (adj_dot >= svga->htotal) svga->hblank_sub++; - svga_log("Loop: adjdot=%d, htotal=%d, dotmask=%02x, hblankendvalmask=%02x, blankendval=%02x.\n", adj_dot, svga->htotal, dot & eff_mask, svga->hblank_end_val & eff_mask, svga->hblank_end_val); + svga_log("Loop: adjdot=%d, htotal=%d, dotmask=%02x, " + "hblankendvalmask=%02x, blankendval=%02x.\n", adj_dot, + svga->htotal, dot & eff_mask, svga->hblank_end_val & eff_mask, + svga->hblank_end_val); if ((dot & eff_mask) == (svga->hblank_end_val & eff_mask)) break; @@ -937,42 +958,85 @@ svga_recalctimings(svga_t *svga) adj_dot++; } + uint32_t hd = svga->hdisp; svga->hdisp -= (svga->hblank_sub * svga->dots_per_clock); + + svga->left_overscan = svga->x_add = (svga->htotal - adj_dot - 1) * svga->dots_per_clock; + svga->monitor->mon_overscan_x = svga->x_add + (svga->hblankstart * svga->dots_per_clock) - hd + svga->dots_per_clock; + /* Compensate for the HDISP code above. */ + if (svga->crtc[1] & 1) + svga->monitor->mon_overscan_x++; + + if ((svga->hdisp >= 2048) || (svga->left_overscan < 0)) { + svga->left_overscan = svga->x_add = 0; + svga->monitor->mon_overscan_x = 0; + } + + /* - 1 because + 1 but also - 2 to compensate for the + 2 added to vtotal above. */ + svga->y_add = svga->vtotal - svga->vblankend - 1; + svga->monitor->mon_overscan_y = svga->y_add + abs(svga->vblankstart - svga->dispend); + + if ((svga->dispend >= 2048) || (svga->y_add < 0)) { + svga->y_add = 0; + svga->monitor->mon_overscan_y = 0; + } } -#ifdef TBD +#if TBD if (ibm8514_active && (svga->dev8514 != NULL)) { if (dev->on) { - uint32_t dot8514 = dev->h_blankstart; - uint32_t adj_dot8514 = dev->h_blankstart; - uint32_t eff_mask8514 = 0x0000001f; - dev->hblank_sub = 0; + uint32_t _8514_dot = dev->h_sync_start; + uint32_t _8514_adj_dot = dev->h_sync_start; + uint32_t _8514_eff_mask = (dev->h_blank_end_val & ~0x0000001f) ? dev->h_blank_end_mask : 0x0000001f; + dev->h_blank_sub = 0; - while (adj_dot8514 < (dev->h_total << 1)) { - if (dot8514 == dev->h_total) - dot8514 = 0; + mach_log("8514/A: HDISP=%d, HDISPED=%d, Blank: %04i-%04i, Total: %04i, " + "Mask: %02X, ADJ_DOT=%04i.\n", dev->hdisp, (dev->hdisped + 1) << 3, + dev->h_sync_start, dev->h_blank_end_val, + dev->h_total, _8514_eff_mask, _8514_adj_dot); - if (adj_dot8514 >= dev->h_total) - dev->hblank_sub++; + while (_8514_adj_dot < (dev->h_total << 1)) { + if (_8514_dot == dev->h_total) + _8514_dot = 0; - if ((dot8514 & eff_mask8514) == (dev->h_blank_end_val & eff_mask8514)) + if (_8514_adj_dot >= dev->h_total) + dev->h_blank_sub++; + + mach_log("8514/A: Loop: adjdot=%d, htotal=%d, dotmask=%02x, " + "hblankendvalmask=%02x, blankendval=%02x.\n", adj_dot, + dev->h_total, _8514_dot & _8514_eff_mask, dev->h_blank_end_val & _8514_eff_mask, + dev->h_blank_end_val); + if ((_8514_dot & _8514_eff_mask) == (dev->h_blank_end_val & _8514_eff_mask)) break; - dot8514++; - adj_dot8514++; + _8514_dot++; + _8514_adj_dot++; } - dev->h_disp -= dev->hblank_sub; + uint32_t _8514_hd = dev->hdisp; + dev->hdisp -= dev->h_blank_sub; + + svga->left_overscan = svga->x_add = (dev->h_total - _8514_adj_dot - 1) << 3; + svga->monitor->mon_overscan_x = svga->x_add + (dev->h_sync_start << 3) - _8514_hd + 8; + svga->monitor->mon_overscan_x++; + + if ((dev->hdisp >= 2048) || (svga->left_overscan < 0)) { + svga->left_overscan = svga->x_add = 0; + svga->monitor->mon_overscan_x = 0; + } + + /* - 1 because + 1 but also - 2 to compensate for the + 2 added to vtotal above. */ + svga->y_add = svga->vtotal - svga->vblankend - 1; + svga->monitor->mon_overscan_y = svga->y_add + abs(svga->vblankstart - svga->dispend); + + if ((dev->dispend >= 2048) || (svga->y_add < 0)) { + svga->y_add = 0; + svga->monitor->mon_overscan_y = 0; + } } } #endif - if (svga->hdisp >= 2048) - svga->monitor->mon_overscan_x = 0; - - svga->y_add = (svga->monitor->mon_overscan_y >> 1); - svga->x_add = (svga->monitor->mon_overscan_x >> 1); - if (svga->vblankstart < svga->dispend) { svga_log("DISPEND > VBLANKSTART.\n"); svga->dispend = svga->vblankstart; @@ -992,12 +1056,9 @@ svga_recalctimings(svga_t *svga) vsyncend = (svga->vsyncstart & 0xfffffff0) | (svga->crtc[0x11] & 0x0f); if (vsyncend <= svga->vsyncstart) vsyncend += 0x00000010; - vblankend = (svga->vblankstart & 0xffffff80) | (svga->crtc[0x16] & 0x7f); - if (vblankend <= svga->vblankstart) - vblankend += 0x00000080; - hdispstart = ((svga->crtc[3] >> 5) & 3); hdispend = svga->crtc[1] + 1; + hdispstart = ((svga->crtc[3] >> 5) & 3); hsyncstart = svga->crtc[4] + ((svga->crtc[5] >> 5) & 3) + 1; hsyncend = (hsyncstart & 0xffffffe0) | (svga->crtc[5] & 0x1f); if (hsyncend <= hsyncstart) @@ -1021,7 +1082,7 @@ svga_recalctimings(svga_t *svga) "\n" "\n", svga->vtotal, svga->dispend, svga->vsyncstart, vsyncend, - svga->vblankstart, vblankend, + svga->vblankstart, svga->vblankend, svga->htotal, hdispstart, hdispend, hsyncstart, hsyncend, svga->hblankstart, svga->hblankend); @@ -1031,15 +1092,15 @@ svga_recalctimings(svga_t *svga) if (ibm8514_active && (svga->dev8514 != NULL)) { if (dev->on) { disptime8514 = dev->h_total; - _dispontime8514 = dev->h_disp; + _dispontime8514 = dev->h_disp_time; svga_log("HTOTAL=%d, HDISP=%d.\n", dev->h_total, dev->h_disp); } } if (xga_active && (svga->xga != NULL)) { if (xga->on) { - disptime_xga = xga->h_total ? xga->h_total : TIMER_USEC; - _dispontime_xga = xga->h_disp; + disptime_xga = xga->h_total; + _dispontime_xga = xga->h_disp_time; } } @@ -1151,7 +1212,7 @@ svga_recalctimings(svga_t *svga) int y_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_y >> 1); int x_start = enable_overscan ? 0 : (svga->monitor->mon_overscan_x >> 1); video_wait_for_buffer_monitor(svga->monitor_index); - memset(svga->monitor->target_buffer->dat, 0, svga->monitor->target_buffer->w * svga->monitor->target_buffer->h * 4); + memset(svga->monitor->target_buffer->dat, 0, (size_t) svga->monitor->target_buffer->w * svga->monitor->target_buffer->h * 4); video_blit_memtoscreen_monitor(x_start, y_start, svga->monitor->mon_xsize + x_add, svga->monitor->mon_ysize + y_add, svga->monitor_index); video_wait_for_buffer_monitor(svga->monitor_index); svga->dpms_ui = 1; @@ -1164,6 +1225,27 @@ svga_recalctimings(svga_t *svga) if (enable_overscan && (svga->monitor->mon_overscan_x != old_monitor_overscan_x || svga->monitor->mon_overscan_y != old_monitor_overscan_y)) video_force_resize_set_monitor(1, svga->monitor_index); + + svga->force_shifter_bypass = 0; + if ((svga->hdisp == 320) && (svga->dispend >= 400) && !svga->override && (svga->render != svga_render_8bpp_clone_highres)) { + svga->hdisp <<= 1; + if (svga->render == svga_render_16bpp_highres) + svga->render = svga_render_16bpp_lowres; + else if (svga->render == svga_render_15bpp_highres) + svga->render = svga_render_15bpp_lowres; + else if (svga->render == svga_render_15bpp_mix_highres) + svga->render = svga_render_15bpp_mix_lowres; + else if (svga->render == svga_render_24bpp_highres) + svga->render = svga_render_24bpp_lowres; + else if (svga->render == svga_render_32bpp_highres) + svga->render = svga_render_32bpp_lowres; + else if (svga->render == svga_render_8bpp_highres) { + svga->render = svga_render_8bpp_lowres; + svga->force_shifter_bypass = 1; + } + else + svga->hdisp >>= 1; + } } static void @@ -1176,12 +1258,8 @@ svga_do_render(svga_t *svga) } if (!svga->override) { + svga->render_line_offset = svga->start_retrace_latch - svga->crtc[0x4]; svga->render(svga); - - svga->x_add = (svga->monitor->mon_overscan_x >> 1); - svga_render_overscan_left(svga); - svga_render_overscan_right(svga); - svga->x_add = (svga->monitor->mon_overscan_x >> 1) - svga->scrollcache; } if (svga->overlay_on) { @@ -1208,6 +1286,13 @@ svga_do_render(svga_t *svga) if (svga->hwcursor_on && svga->interlace) svga->hwcursor_on--; } + + if (!svga->override) { + svga->x_add = svga->left_overscan; + svga_render_overscan_left(svga); + svga_render_overscan_right(svga); + svga->x_add = svga->left_overscan - svga->scrollcache; + } } void @@ -1260,17 +1345,17 @@ svga_poll(void *priv) if (svga->dispon) { svga->hdisp_on = 1; - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; if (svga->firstline == 2000) { svga->firstline = svga->displine; video_wait_for_buffer_monitor(svga->monitor_index); } if (svga->hwcursor_on || svga->dac_hwcursor_on || svga->overlay_on) - svga->changedvram[svga->ma >> 12] = svga->changedvram[(svga->ma >> 12) + 1] = svga->interlace ? 3 : 2; + svga->changedvram[svga->memaddr >> 12] = svga->changedvram[(svga->memaddr >> 12) + 1] = svga->interlace ? 3 : 2; if (svga->vertical_linedbl) { - old_ma = svga->ma; + old_ma = svga->memaddr; svga->displine <<= 1; svga->y_add <<= 1; @@ -1279,7 +1364,7 @@ svga_poll(void *priv) svga->displine++; - svga->ma = old_ma; + svga->memaddr = old_ma; svga_do_render(svga); @@ -1308,29 +1393,29 @@ svga_poll(void *priv) svga->hdisp_on = 0; svga->linepos = 0; - if ((svga->sc == (svga->crtc[11] & 31)) || (svga->sc == svga->rowcount)) - svga->con = 0; + if ((svga->scanline == (svga->crtc[11] & 31)) || (svga->scanline == svga->rowcount)) + svga->cursorvisible = 0; if (svga->dispon) { /* TODO: Verify real hardware behaviour for out-of-range fine vertical scroll - - S3 Trio64V2/DX: sc == rowcount, wrapping 5-bit counter. */ + - S3 Trio64V2/DX: scanline == rowcount, wrapping 5-bit counter. */ if (svga->linedbl && !svga->linecountff) { svga->linecountff = 1; - svga->ma = svga->maback; - } else if (svga->sc == svga->rowcount) { + svga->memaddr = svga->memaddr_backup; + } else if (svga->scanline == svga->rowcount) { svga->linecountff = 0; - svga->sc = 0; + svga->scanline = 0; - svga->maback += (svga->adv_flags & FLAG_NO_SHIFT3) ? svga->rowoffset : (svga->rowoffset << 3); + svga->memaddr_backup += (svga->adv_flags & FLAG_NO_SHIFT3) ? svga->rowoffset : (svga->rowoffset << 3); if (svga->interlace) - svga->maback += (svga->adv_flags & FLAG_NO_SHIFT3) ? svga->rowoffset : (svga->rowoffset << 3); + svga->memaddr_backup += (svga->adv_flags & FLAG_NO_SHIFT3) ? svga->rowoffset : (svga->rowoffset << 3); - svga->maback &= svga->vram_display_mask; - svga->ma = svga->maback; + svga->memaddr_backup &= svga->vram_display_mask; + svga->memaddr = svga->memaddr_backup; } else { svga->linecountff = 0; - svga->sc++; - svga->sc &= 0x1f; - svga->ma = svga->maback; + svga->scanline++; + svga->scanline &= 0x1f; + svga->memaddr = svga->memaddr_backup; } } @@ -1350,17 +1435,17 @@ svga_poll(void *priv) if (ret) { if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = (svga->rowoffset << 1) + svga->hblank_sub; + svga->memaddr = svga->memaddr_backup = (svga->rowoffset << 1) + svga->hblank_sub; else - svga->ma = svga->maback = svga->hblank_sub; + svga->memaddr = svga->memaddr_backup = svga->hblank_sub; - svga->ma = (svga->ma << 2); - svga->maback = (svga->maback << 2); + svga->memaddr = (svga->memaddr << 2); + svga->memaddr_backup = (svga->memaddr_backup << 2); - svga->sc = 0; + svga->scanline = 0; if (svga->attrregs[0x10] & 0x20) { - svga->scrollcache = 0; - svga->x_add = (svga->monitor->mon_overscan_x >> 1); + svga->scrollcache = 0; + svga->x_add = svga->left_overscan; } } } @@ -1426,26 +1511,28 @@ svga_poll(void *priv) svga->vslines = 0; if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + svga->hblank_sub; + svga->memaddr = svga->memaddr_backup = svga->memaddr_latch + (svga->rowoffset << 1) + svga->hblank_sub; else - svga->ma = svga->maback = svga->ma_latch + svga->hblank_sub; + svga->memaddr = svga->memaddr_backup = svga->memaddr_latch + svga->hblank_sub; - svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; + svga->cursoraddr = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; if (!(svga->adv_flags & FLAG_NO_SHIFT3)) { - svga->ma = (svga->ma << 2); - svga->maback = (svga->maback << 2); + svga->memaddr = (svga->memaddr << 2); + svga->memaddr_backup = (svga->memaddr_backup << 2); } - svga->ca = (svga->ca << 2); + svga->cursoraddr = (svga->cursoraddr << 2); if (svga->vsync_callback) svga->vsync_callback(svga); + + svga->start_retrace_latch = svga->crtc[0x4]; } #if 0 if (svga->vc == lines_num) { #endif if (svga->vc == svga->vtotal) { svga->vc = 0; - svga->sc = (svga->crtc[0x8] & 0x1f); + svga->scanline = (svga->crtc[0x8] & 0x1f); svga->dispon = 1; svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; @@ -1458,7 +1545,8 @@ svga_poll(void *priv) 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)) + } 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; @@ -1466,7 +1554,7 @@ svga_poll(void *priv) 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; + svga->x_add = svga->left_overscan - svga->scrollcache; svga->linecountff = 0; @@ -1479,8 +1567,8 @@ svga_poll(void *priv) svga->overlay_on = 0; svga->overlay_latch = svga->overlay; } - if (svga->sc == (svga->crtc[10] & 31)) - svga->con = 1; + if (svga->scanline == (svga->crtc[10] & 31)) + svga->cursorvisible = 1; } } @@ -1516,10 +1604,12 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, svga->attrregs[0x11] = 0; svga->overscan_color = 0x000000; + svga->left_overscan = 8; svga->monitor->mon_overscan_x = 16; svga->monitor->mon_overscan_y = 32; svga->x_add = 8; svga->y_add = 16; + svga->force_shifter_bypass = 1; svga->crtc[0] = 63; svga->crtc[6] = 255; @@ -1973,9 +2063,15 @@ svga_doblit(int wx, int wy, svga_t *svga) y_add = enable_overscan ? svga->monitor->mon_overscan_y : 0; x_add = enable_overscan ? svga->monitor->mon_overscan_x : 0; +#ifdef USE_OLD_CALCULATION 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); +#else + y_start = enable_overscan ? 0 : svga->y_add; + x_start = enable_overscan ? 0 : svga->left_overscan; + bottom = svga->monitor->mon_overscan_y - svga->y_add; +#endif if (svga->vertical_linedbl) { y_add <<= 1; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index d47697a7e..f43db41c4 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -58,7 +58,7 @@ svga_render_null(svga_t *svga) void svga_render_blank(svga_t *svga) { - if ((svga->displine + svga->y_add) < 0) + if ((svga->displine + svga->y_add) < 0 || (svga->displine + svga->y_add) >= 2048) return; if (svga->firstline_draw == 2000) @@ -86,9 +86,14 @@ svga_render_blank(svga_t *svga) } uint32_t *line_ptr = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; - uint32_t line_width = (uint32_t) (svga->hdisp + svga->scrollcache) * char_width * sizeof(uint32_t); + int32_t line_width = (uint32_t) (svga->hdisp + svga->scrollcache) * char_width * sizeof(uint32_t); - if ((svga->hdisp + svga->scrollcache) > 0) + if (svga->x_add < 0) { + line_ptr = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][0]; + line_width -= svga->x_add; + } + + if (((svga->hdisp + svga->scrollcache) > 0) && (line_width >= 0)) memset(line_ptr, 0, line_width); } @@ -102,7 +107,8 @@ svga_render_overscan_left(svga_t *svga) return; uint32_t *line_ptr = svga->monitor->target_buffer->line[svga->displine + svga->y_add]; - for (int i = 0; i < svga->x_add; i++) + + if (svga->x_add >= 0) for (int i = 0; i < svga->x_add; i++) *line_ptr++ = svga->overscan_color; } @@ -118,7 +124,7 @@ svga_render_overscan_right(svga_t *svga) return; uint32_t *line_ptr = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add + svga->hdisp]; - right = (overscan_x >> 1); + right = overscan_x - svga->left_overscan; for (int i = 0; i < right; i++) *line_ptr++ = svga->overscan_color; } @@ -156,13 +162,13 @@ svga_render_text_40(svga_t *svga) for (int x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { if (!svga->force_old_addr) - addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + addr = svga->remap_func(svga, svga->memaddr) & svga->vram_display_mask; - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); + drawcursor = ((svga->memaddr == svga->cursoraddr) && svga->cursorvisible && svga->cursoron); if (svga->force_old_addr) { - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + chr = svga->vram[(svga->memaddr << 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->memaddr << 1) + 1) & svga->vram_display_mask]; } else { chr = svga->vram[addr]; attr = svga->vram[addr + 1]; @@ -187,7 +193,7 @@ svga_render_text_40(svga_t *svga) } } - dat = svga->vram[charaddr + (svga->sc << 2)]; + dat = svga->vram[charaddr + (svga->scanline << 2)]; if (svga->seqregs[1] & 1) { for (xx = 0; xx < 16; xx += 2) p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; @@ -199,10 +205,10 @@ svga_render_text_40(svga_t *svga) else p[16] = p[17] = (dat & 1) ? fg : bg; } - svga->ma += 4; + svga->memaddr += 4; p += xinc; } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } @@ -239,13 +245,13 @@ svga_render_text_80(svga_t *svga) for (int x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { if (!svga->force_old_addr) - addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + addr = svga->remap_func(svga, svga->memaddr) & svga->vram_display_mask; - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); + drawcursor = ((svga->memaddr == svga->cursoraddr) && svga->cursorvisible && svga->cursoron); if (svga->force_old_addr) { - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + chr = svga->vram[(svga->memaddr << 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->memaddr << 1) + 1) & svga->vram_display_mask]; } else { chr = svga->vram[addr]; attr = svga->vram[addr + 1]; @@ -269,7 +275,7 @@ svga_render_text_80(svga_t *svga) } } - dat = svga->vram[charaddr + (svga->sc << 2)]; + dat = svga->vram[charaddr + (svga->scanline << 2)]; if (svga->seqregs[1] & 1) { for (xx = 0; xx < 8; xx++) p[xx] = (dat & (0x80 >> xx)) ? fg : bg; @@ -281,10 +287,10 @@ svga_render_text_80(svga_t *svga) else p[8] = (dat & 1) ? fg : bg; } - svga->ma += 4; + svga->memaddr += 4; p += xinc; } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } @@ -317,8 +323,8 @@ svga_render_text_80_ksc5601(svga_t *svga) xinc = (svga->seqregs[1] & 1) ? 8 : 9; for (int x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { - uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); + uint32_t addr = svga->remap_func(svga, svga->memaddr) & svga->vram_display_mask; + drawcursor = ((svga->memaddr == svga->cursoraddr) && svga->cursorvisible && svga->cursoron); chr = svga->vram[addr]; nextchr = svga->vram[addr + 8]; attr = svga->vram[addr + 1]; @@ -338,7 +344,7 @@ svga_render_text_80_ksc5601(svga_t *svga) if ((x + xinc) < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { if ((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff)) - dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc]; + dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->scanline]; else if (nextchr & 0x80) { if (svga->ksc5601_swap_mode == 1 && (nextchr > 0xa0 && nextchr < 0xff)) { if (chr >= 0x80 && chr < 0x99) @@ -346,7 +352,7 @@ svga_render_text_80_ksc5601(svga_t *svga) else if (chr >= 0xB0 && chr < 0xC9) chr -= 0x30; } - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc]; + dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->scanline]; } else dat = 0xff; } else { @@ -356,9 +362,9 @@ svga_render_text_80_ksc5601(svga_t *svga) charaddr = svga->charseta + (chr * 128); if ((svga->ksc5601_english_font_type >> 8) == 1) - dat = fontdatksc5601[((svga->ksc5601_english_font_type & 0x7F) << 7) | (chr >> 1)].chr[((chr & 1) << 4) | svga->sc]; + dat = fontdatksc5601[((svga->ksc5601_english_font_type & 0x7F) << 7) | (chr >> 1)].chr[((chr & 1) << 4) | svga->scanline]; else - dat = svga->vram[charaddr + (svga->sc << 2)]; + dat = svga->vram[charaddr + (svga->scanline << 2)]; } if (svga->seqregs[1] & 1) { @@ -372,11 +378,11 @@ svga_render_text_80_ksc5601(svga_t *svga) else p[8] = (dat & 1) ? fg : bg; } - svga->ma += 4; + svga->memaddr += 4; p += xinc; if ((x + xinc) < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->memaddr << 1) + 1) & svga->vram_display_mask]; if (drawcursor) { bg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; @@ -392,9 +398,9 @@ svga_render_text_80_ksc5601(svga_t *svga) } if ((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff)) - dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc + 16]; + dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->scanline + 16]; else if (nextchr & 0x80) - dat = fontdatksc5601[((chr & 0x7f) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16]; + dat = fontdatksc5601[((chr & 0x7f) << 7) | (nextchr & 0x7F)].chr[svga->scanline + 16]; else dat = 0xff; @@ -410,12 +416,12 @@ svga_render_text_80_ksc5601(svga_t *svga) p[8] = (dat & 1) ? fg : bg; } - svga->ma += 4; + svga->memaddr += 4; p += xinc; x += xinc; } } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } @@ -433,7 +439,7 @@ svga_render_2bpp_s3_lowres(svga_t *svga) return; if (svga->force_old_addr) { - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + changed_offset = ((svga->memaddr << 1) + (svga->scanline & ~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]; @@ -443,32 +449,32 @@ svga_render_2bpp_s3_lowres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->ma; + addr = svga->memaddr; if (!(svga->crtc[0x17] & 0x40)) { addr = (addr << 1) & svga->vram_mask; addr &= ~7; - if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + if ((svga->crtc[0x17] & 0x20) && (svga->memaddr & 0x20000)) addr |= 4; - if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + if (!(svga->crtc[0x17] & 0x20) && (svga->memaddr & 0x8000)) addr |= 4; } if (!(svga->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); + addr = (addr & ~0x8000) | ((svga->scanline & 1) ? 0x8000 : 0); if (!(svga->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + addr = (addr & ~0x10000) | ((svga->scanline & 2) ? 0x10000 : 0); dat[0] = svga->vram[addr]; dat[1] = svga->vram[addr | 0x1]; if (svga->seqregs[1] & 4) - svga->ma += 2; + svga->memaddr += 2; else - svga->ma += 4; - svga->ma &= svga->vram_mask; + svga->memaddr += 4; + svga->memaddr &= svga->vram_mask; p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3] & svga->dac_mask]; p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3] & svga->dac_mask]; p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3] & svga->dac_mask]; @@ -481,7 +487,7 @@ svga_render_2bpp_s3_lowres(svga_t *svga) } } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -491,16 +497,16 @@ svga_render_2bpp_s3_lowres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat[0] = svga->vram[addr]; dat[1] = svga->vram[addr | 0x1]; if (svga->seqregs[1] & 4) - svga->ma += 2; + svga->memaddr += 2; else - svga->ma += 4; + svga->memaddr += 4; - svga->ma &= svga->vram_mask; + svga->memaddr &= svga->vram_mask; p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3] & svga->dac_mask]; p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3] & svga->dac_mask]; @@ -531,7 +537,7 @@ svga_render_2bpp_s3_highres(svga_t *svga) return; if (svga->force_old_addr) { - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + changed_offset = ((svga->memaddr << 1) + (svga->scanline & ~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]; @@ -541,32 +547,32 @@ svga_render_2bpp_s3_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->ma; + addr = svga->memaddr; if (!(svga->crtc[0x17] & 0x40)) { addr = (addr << 1) & svga->vram_mask; addr &= ~7; - if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + if ((svga->crtc[0x17] & 0x20) && (svga->memaddr & 0x20000)) addr |= 4; - if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + if (!(svga->crtc[0x17] & 0x20) && (svga->memaddr & 0x8000)) addr |= 4; } if (!(svga->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); + addr = (addr & ~0x8000) | ((svga->scanline & 1) ? 0x8000 : 0); if (!(svga->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + addr = (addr & ~0x10000) | ((svga->scanline & 2) ? 0x10000 : 0); dat[0] = svga->vram[addr]; dat[1] = svga->vram[addr | 0x1]; if (svga->seqregs[1] & 4) - svga->ma += 2; + svga->memaddr += 2; else - svga->ma += 4; - svga->ma &= svga->vram_mask; + svga->memaddr += 4; + svga->memaddr &= svga->vram_mask; p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3] & svga->dac_mask]; p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3] & svga->dac_mask]; p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3] & svga->dac_mask]; @@ -579,7 +585,7 @@ svga_render_2bpp_s3_highres(svga_t *svga) } } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -589,16 +595,16 @@ svga_render_2bpp_s3_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat[0] = svga->vram[addr]; dat[1] = svga->vram[addr | 0x1]; if (svga->seqregs[1] & 4) - svga->ma += 2; + svga->memaddr += 2; else - svga->ma += 4; + svga->memaddr += 4; - svga->ma &= svga->vram_mask; + svga->memaddr &= svga->vram_mask; p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3] & svga->dac_mask]; p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3] & svga->dac_mask]; @@ -628,7 +634,7 @@ svga_render_2bpp_headland_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -638,7 +644,7 @@ svga_render_2bpp_headland_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (int x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); oddeven = 0; if (svga->seqregs[1] & 4) { @@ -649,8 +655,8 @@ svga_render_2bpp_headland_highres(svga_t *svga) } else { *(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]); } - svga->ma += 4; - svga->ma &= svga->vram_mask; + svga->memaddr += 4; + svga->memaddr &= 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] & svga->dac_mask]; @@ -694,7 +700,7 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) - 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 highres8bpp = (combine8bits && highres) || svga->force_shifter_bypass; const bool dwordload = ((svga->seqregs[0x01] & 0x10) != 0); const bool wordload = ((svga->seqregs[0x01] & 0x04) != 0) && !dwordload; @@ -736,14 +742,21 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) return; if (svga->force_old_addr) - changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + changed_offset = (svga->memaddr + (svga->scanline & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; else - changed_offset = svga->remap_func(svga, svga->ma) >> 12; + changed_offset = svga->remap_func(svga, svga->memaddr) >> 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->render_line_offset) { + if (svga->render_line_offset > 0) { + memset(p, svga->overscan_color, (size_t) charwidth * svga->render_line_offset * sizeof(uint32_t)); + p += charwidth * svga->render_line_offset; + } + } + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; @@ -755,19 +768,19 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) if (load_counter == 0) { /* Find our address */ if (svga->force_old_addr) { - addr = ((svga->ma & ~0x3) << incbypow2); + addr = ((svga->memaddr & ~0x3) << incbypow2); if (incbypow2 == 2) { - if (svga->ma & (4 << 15)) + if (svga->memaddr & (4 << 15)) addr |= 0x8; - if (svga->ma & (4 << 14)) + if (svga->memaddr & (4 << 14)) addr |= 0x4; } else if (incbypow2 == 1) { if ((svga->crtc[0x17] & 0x20)) { - if (svga->ma & (4 << 15)) + if (svga->memaddr & (4 << 15)) addr |= 0x4; } else { - if (svga->ma & (4 << 13)) + if (svga->memaddr & (4 << 13)) addr |= 0x4; } } else { @@ -775,13 +788,13 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) } if (!(svga->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); + addr = (addr & ~0x8000) | ((svga->scanline & 1) ? 0x8000 : 0); if (!(svga->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + addr = (addr & ~0x10000) | ((svga->scanline & 2) ? 0x10000 : 0); } else if (svga->remap_required) - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); else - addr = svga->ma; + addr = svga->memaddr; addr &= svga->vram_display_mask; @@ -819,9 +832,9 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) incr_counter += 1; if (incr_counter >= incevery) { incr_counter = 0; - svga->ma += 4; + svga->memaddr += 4; /* DISCREPANCY TODO FIXME 2/4bpp used vram_mask, 8bpp used vram_display_mask --GM */ - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } uint32_t current_shift = shift_values; @@ -900,6 +913,12 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) else p += charwidth; } + + if (svga->render_line_offset < 0) { + uint32_t *orig_line = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; + memmove(orig_line, orig_line + (charwidth * -svga->render_line_offset), (svga->hdisp) * 4); + memset((orig_line + svga->hdisp) - (charwidth * -svga->render_line_offset), svga->overscan_color, (size_t) charwidth * -svga->render_line_offset * 4); + } } /* @@ -913,6 +932,126 @@ void svga_render_4bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true void svga_render_8bpp_lowres(svga_t *svga) { svga_render_indexed_gfx(svga, false, true); } void svga_render_8bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true, true); } +void +svga_render_4bpp_tseng_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->memaddr + (svga->scanline & ~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->memaddr; + 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->memaddr & 0x20000)) + addr |= 4; + if (!(svga->crtc[0x17] & 0x20) && (svga->memaddr & 0x8000)) + addr |= 4; + } + + if (!(svga->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((svga->scanline & 1) ? 0x8000 : 0); + if (!(svga->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((svga->scanline & 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->memaddr += 2; + } else { + *(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]); + svga->memaddr += 4; + } + svga->memaddr &= 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->memaddr); + + 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->memaddr); + 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->memaddr += 2; + } else { + *(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]); + svga->memaddr += 4; + } + svga->memaddr &= 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; + } + } + } +} + void svga_render_8bpp_clone_highres(svga_t *svga) { @@ -926,7 +1065,7 @@ svga_render_8bpp_clone_highres(svga_t *svga) return; if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -934,25 +1073,25 @@ svga_render_8bpp_clone_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { - dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); p[0] = svga->map8[dat & svga->dac_mask & 0xff]; p[1] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff]; p[2] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff]; p[3] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff]; - dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + 4) & svga->vram_display_mask]); p[4] = svga->map8[dat & svga->dac_mask & 0xff]; p[5] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff]; p[6] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff]; p[7] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff]; - svga->ma += 8; + svga->memaddr += 8; p += 8; } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -963,35 +1102,35 @@ svga_render_8bpp_clone_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 & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); p[0] = svga->map8[dat & svga->dac_mask & 0xff]; p[1] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff]; p[2] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff]; p[3] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff]; - dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + 4) & svga->vram_display_mask]); p[4] = svga->map8[dat & svga->dac_mask & 0xff]; p[5] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff]; p[6] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff]; p[7] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff]; - svga->ma += 8; + svga->memaddr += 8; p += 8; } } else { for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 4) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); p[0] = svga->map8[dat & svga->dac_mask & 0xff]; p[1] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff]; p[2] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff]; p[3] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff]; - svga->ma += 4; + svga->memaddr += 4; p += 4; } } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } } @@ -1011,7 +1150,7 @@ svga_render_8bpp_lowres(svga_t *svga) return; if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -1019,20 +1158,20 @@ svga_render_8bpp_lowres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); p[0] = p[1] = svga->map8[dat & 0xff]; p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; - svga->ma += 4; + svga->memaddr += 4; p += 8; } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -1043,29 +1182,29 @@ svga_render_8bpp_lowres(svga_t *svga) 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]); + dat = *(uint32_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); p[0] = p[1] = svga->map8[dat & svga->dac_mask & 0xff]; p[2] = p[3] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff]; p[4] = p[5] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff]; p[6] = p[7] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff]; - svga->ma += 4; + svga->memaddr += 4; p += 8; } } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); p[0] = p[1] = svga->map8[dat & svga->dac_mask & 0xff]; p[2] = p[3] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff]; p[4] = p[5] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff]; p[6] = p[7] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff]; - svga->ma += 4; + svga->memaddr += 4; p += 8; } } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } } @@ -1083,7 +1222,7 @@ svga_render_8bpp_highres(svga_t *svga) return; if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -1091,25 +1230,25 @@ svga_render_8bpp_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { - dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); p[0] = svga->map8[dat & svga->dac_mask & 0xff]; p[1] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff]; p[2] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff]; p[3] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff]; - dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + 4) & svga->vram_display_mask]); p[4] = svga->map8[dat & svga->dac_mask & 0xff]; p[5] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff]; p[6] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff]; p[7] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff]; - svga->ma += 8; + svga->memaddr += 8; p += 8; } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -1120,35 +1259,35 @@ svga_render_8bpp_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 & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); p[0] = svga->map8[dat & svga->dac_mask & 0xff]; p[1] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff]; p[2] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff]; p[3] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff]; - dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + 4) & svga->vram_display_mask]); p[4] = svga->map8[dat & svga->dac_mask & 0xff]; p[5] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff]; p[6] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff]; p[7] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff]; - svga->ma += 8; + svga->memaddr += 8; p += 8; } } else { for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 4) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); p[0] = svga->map8[dat & svga->dac_mask & 0xff]; p[1] = svga->map8[(dat >> 8) & svga->dac_mask & 0xff]; p[2] = svga->map8[(dat >> 16) & svga->dac_mask & 0xff]; p[3] = svga->map8[(dat >> 24) & svga->dac_mask & 0xff]; - svga->ma += 4; + svga->memaddr += 4; p += 4; } } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } } @@ -1163,15 +1302,22 @@ svga_render_8bpp_tseng_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange || svga->render_line_offset) { 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; + if (svga->render_line_offset) { + if (svga->render_line_offset > 0) { + memset(p, svga->overscan_color, 8 * svga->render_line_offset * sizeof(uint32_t)); + p += 8 * svga->render_line_offset; + } + } + for (int x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); p[0] = p[1] = svga->map8[dat & svga->dac_mask & 0xff]; @@ -1188,10 +1334,15 @@ svga_render_8bpp_tseng_lowres(svga_t *svga) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); p[6] = p[7] = svga->map8[dat & svga->dac_mask & 0xff]; - svga->ma += 4; + svga->memaddr += 4; p += 8; } - svga->ma &= svga->vram_display_mask; + if (svga->render_line_offset < 0) { + uint32_t *orig_line = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; + memmove(orig_line, orig_line + (8 * -svga->render_line_offset), (svga->hdisp) * 4); + memset((orig_line + svga->hdisp) - (8 * -svga->render_line_offset), svga->overscan_color, 8 * -svga->render_line_offset * 4); + } + svga->memaddr &= svga->vram_display_mask; } } @@ -1204,15 +1355,22 @@ svga_render_8bpp_tseng_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange || svga->render_line_offset) { 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; + if (svga->render_line_offset) { + if (svga->render_line_offset > 0) { + memset(p, svga->overscan_color, 8 * svga->render_line_offset * sizeof(uint32_t)); + p += 8 * svga->render_line_offset; + } + } + for (int x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { - dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); p[0] = svga->map8[dat & svga->dac_mask & 0xff]; @@ -1229,7 +1387,7 @@ svga_render_8bpp_tseng_highres(svga_t *svga) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); p[3] = svga->map8[dat & svga->dac_mask & 0xff]; - dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + 4) & svga->vram_display_mask]); if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); p[4] = svga->map8[dat & svga->dac_mask & 0xff]; @@ -1246,10 +1404,17 @@ svga_render_8bpp_tseng_highres(svga_t *svga) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); p[7] = svga->map8[dat & svga->dac_mask & 0xff]; - svga->ma += 8; + svga->memaddr += 8; p += 8; } - svga->ma &= svga->vram_display_mask; + + if (svga->render_line_offset < 0) { + uint32_t *orig_line = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; + memmove(orig_line, orig_line + (8 * -svga->render_line_offset), (svga->hdisp) * 4); + memset((orig_line + svga->hdisp) - (8 * -svga->render_line_offset), svga->overscan_color, 8 * -svga->render_line_offset * 4); + } + + svga->memaddr &= svga->vram_display_mask; } } @@ -1266,7 +1431,7 @@ svga_render_15bpp_lowres(svga_t *svga) return; if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -1274,21 +1439,21 @@ svga_render_15bpp_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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1)) & svga->vram_display_mask]); 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 4) & svga->vram_display_mask]); 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; + svga->memaddr += x << 1; + svga->memaddr &= svga->vram_display_mask; } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -1299,28 +1464,28 @@ svga_render_15bpp_lowres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1)) & svga->vram_display_mask]); *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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 4) & svga->vram_display_mask]); *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); *p++ = svga->conv_16to32(svga, dat >> 16, 15); } - svga->ma += x << 1; + svga->memaddr += x << 1; } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); *p++ = svga->conv_16to32(svga, dat >> 16, 15); - svga->ma += 4; + svga->memaddr += 4; } } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } } @@ -1338,7 +1503,7 @@ svga_render_15bpp_highres(svga_t *svga) return; if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -1346,27 +1511,27 @@ svga_render_15bpp_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1)) & svga->vram_display_mask]); 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 4) & svga->vram_display_mask]); 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 8) & svga->vram_display_mask]); 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 12) & svga->vram_display_mask]); 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; + svga->memaddr += x << 1; + svga->memaddr &= svga->vram_display_mask; } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -1377,34 +1542,34 @@ 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1)) & svga->vram_display_mask]); *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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 4) & svga->vram_display_mask]); *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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 8) & svga->vram_display_mask]); *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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 12) & svga->vram_display_mask]); *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); *p++ = svga->conv_16to32(svga, dat >> 16, 15); } - svga->ma += x << 1; + svga->memaddr += x << 1; } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); *p++ = svga->conv_16to32(svga, dat >> 16, 15); - svga->ma += 4; + svga->memaddr += 4; } } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } } @@ -1419,7 +1584,7 @@ svga_render_15bpp_mix_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -1427,20 +1592,20 @@ 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (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] : svga->conv_16to32(svga, dat & 0xffff, 15); - dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 4) & svga->vram_display_mask]); 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] : svga->conv_16to32(svga, dat & 0xffff, 15); } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; + svga->memaddr += x << 1; + svga->memaddr &= svga->vram_display_mask; } } @@ -1454,7 +1619,7 @@ svga_render_15bpp_mix_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -1462,28 +1627,28 @@ svga_render_15bpp_mix_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1)) & svga->vram_display_mask]); 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] : svga->conv_16to32(svga, dat & 0xffff, 15); - dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 4) & svga->vram_display_mask]); 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] : svga->conv_16to32(svga, dat & 0xffff, 15); - dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 8) & svga->vram_display_mask]); 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] : svga->conv_16to32(svga, dat & 0xffff, 15); - dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 12) & svga->vram_display_mask]); 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] : svga->conv_16to32(svga, dat & 0xffff, 15); } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; + svga->memaddr += x << 1; + svga->memaddr &= svga->vram_display_mask; } } @@ -1500,7 +1665,7 @@ svga_render_16bpp_lowres(svga_t *svga) return; if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -1508,19 +1673,19 @@ 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 4) & svga->vram_display_mask]); 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; + svga->memaddr += x << 1; + svga->memaddr &= svga->vram_display_mask; } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -1531,28 +1696,28 @@ svga_render_16bpp_lowres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1)) & svga->vram_display_mask]); *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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 4) & svga->vram_display_mask]); *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); *p++ = svga->conv_16to32(svga, dat >> 16, 16); } - svga->ma += x << 1; + svga->memaddr += x << 1; } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); *p++ = svga->conv_16to32(svga, dat >> 16, 16); } - svga->ma += 4; + svga->memaddr += 4; } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } } @@ -1570,7 +1735,7 @@ svga_render_16bpp_highres(svga_t *svga) return; if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -1578,27 +1743,27 @@ svga_render_16bpp_highres(svga_t *svga) svga->lastline_draw = svga->displine; 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]); + uint32_t dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1)) & svga->vram_display_mask]); 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 4) & svga->vram_display_mask]); 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 8) & svga->vram_display_mask]); 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 12) & svga->vram_display_mask]); 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; + svga->memaddr += x << 1; + svga->memaddr &= svga->vram_display_mask; } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -1609,35 +1774,35 @@ 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1)) & svga->vram_display_mask]); *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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 4) & svga->vram_display_mask]); *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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 8) & svga->vram_display_mask]); *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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 1) + 12) & svga->vram_display_mask]); *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); *p++ = svga->conv_16to32(svga, dat >> 16, 16); } - svga->ma += x << 1; + svga->memaddr += x << 1; } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); *p++ = svga->conv_16to32(svga, dat >> 16, 16); - svga->ma += 4; + svga->memaddr += 4; } } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } } @@ -1661,20 +1826,20 @@ svga_render_24bpp_lowres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - 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; + fg = svga->vram[svga->memaddr] | (svga->vram[svga->memaddr + 1] << 8) | (svga->vram[svga->memaddr + 2] << 16); + svga->memaddr += 3; + svga->memaddr &= 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] = lookup_lut(fg); } } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -1685,24 +1850,24 @@ svga_render_24bpp_lowres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - dat0 = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); - dat1 = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - dat2 = *(uint32_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + dat0 = *(uint32_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); + dat1 = *(uint32_t *) (&svga->vram[(svga->memaddr + 4) & svga->vram_display_mask]); + dat2 = *(uint32_t *) (&svga->vram[(svga->memaddr + 8) & svga->vram_display_mask]); 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; + svga->memaddr += 12; } } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat0 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 4); + addr = svga->remap_func(svga, svga->memaddr + 4); dat1 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 8); + addr = svga->remap_func(svga, svga->memaddr + 8); dat2 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); p[0] = p[1] = lookup_lut(dat0 & 0xffffff); @@ -1710,10 +1875,10 @@ svga_render_24bpp_lowres(svga_t *svga) p[4] = p[5] = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); p[6] = p[7] = lookup_lut(dat2 >> 8); - svga->ma += 12; + svga->memaddr += 12; } } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } } @@ -1734,7 +1899,7 @@ svga_render_24bpp_highres(svga_t *svga) return; if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -1742,24 +1907,24 @@ svga_render_24bpp_highres(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 & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); p[x] = lookup_lut(dat & 0xffffff); - dat = *(uint32_t *) (&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + 3) & svga->vram_display_mask]); p[x + 1] = lookup_lut(dat & 0xffffff); - dat = *(uint32_t *) (&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + 6) & svga->vram_display_mask]); p[x + 2] = lookup_lut(dat & 0xffffff); - dat = *(uint32_t *) (&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + 9) & svga->vram_display_mask]); p[x + 3] = lookup_lut(dat & 0xffffff); - svga->ma += 12; + svga->memaddr += 12; } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -1770,24 +1935,24 @@ svga_render_24bpp_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat0 = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); - dat1 = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - dat2 = *(uint32_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + dat0 = *(uint32_t *) (&svga->vram[svga->memaddr & svga->vram_display_mask]); + dat1 = *(uint32_t *) (&svga->vram[(svga->memaddr + 4) & svga->vram_display_mask]); + dat2 = *(uint32_t *) (&svga->vram[(svga->memaddr + 8) & svga->vram_display_mask]); *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; + svga->memaddr += 12; } } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat0 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 4); + addr = svga->remap_func(svga, svga->memaddr + 4); dat1 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 8); + addr = svga->remap_func(svga, svga->memaddr + 8); dat2 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); *p++ = lookup_lut(dat0 & 0xffffff); @@ -1795,10 +1960,10 @@ svga_render_24bpp_highres(svga_t *svga) *p++ = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); *p++ = lookup_lut(dat2 >> 8); - svga->ma += 12; + svga->memaddr += 12; } } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } } @@ -1816,20 +1981,20 @@ svga_render_32bpp_lowres(svga_t *svga) return; if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->fullchange) { if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - 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; + dat = svga->vram[svga->memaddr] | (svga->vram[svga->memaddr + 1] << 8) | (svga->vram[svga->memaddr + 2] << 16); + svga->memaddr += 4; + svga->memaddr &= 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] = lookup_lut(dat); } } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -1840,20 +2005,20 @@ 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 2)) & svga->vram_display_mask]); *p++ = lookup_lut(dat & 0xffffff); *p++ = lookup_lut(dat & 0xffffff); } - svga->ma += (x * 4); + svga->memaddr += (x * 4); } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); *p++ = lookup_lut(dat & 0xffffff); *p++ = lookup_lut(dat & 0xffffff); - svga->ma += 4; + svga->memaddr += 4; } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } } @@ -1872,7 +2037,7 @@ svga_render_32bpp_highres(svga_t *svga) return; if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + if (svga->changedvram[svga->memaddr >> 12] || svga->changedvram[(svga->memaddr >> 12) + 1] || svga->changedvram[(svga->memaddr >> 12) + 2] || svga->fullchange) { p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -1880,14 +2045,14 @@ svga_render_32bpp_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 2)) & svga->vram_display_mask]); p[x] = lookup_lut(dat & 0xffffff); } - svga->ma += 4; - svga->ma &= svga->vram_display_mask; + svga->memaddr += 4; + svga->memaddr &= svga->vram_display_mask; } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -1898,20 +2063,20 @@ 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 2)) & svga->vram_display_mask]); *p++ = lookup_lut(dat & 0xffffff); } - svga->ma += (x * 4); + svga->memaddr += (x * 4); } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); *p++ = lookup_lut(dat & 0xffffff); - svga->ma += 4; + svga->memaddr += 4; } } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } } @@ -1928,7 +2093,7 @@ svga_render_ABGR8888_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -1939,20 +2104,20 @@ 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 2)) & svga->vram_display_mask]); *p++ = lookup_lut(((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16)); } - svga->ma += x * 4; + svga->memaddr += x * 4; } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); *p++ = lookup_lut(((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16)); - svga->ma += 4; + svga->memaddr += 4; } } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } @@ -1968,7 +2133,7 @@ svga_render_RGBA8888_highres(svga_t *svga) if ((svga->displine + svga->y_add) < 0) return; - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->memaddr); 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]; @@ -1979,19 +2144,19 @@ 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]); + dat = *(uint32_t *) (&svga->vram[(svga->memaddr + (x << 2)) & svga->vram_display_mask]); *p++ = lookup_lut(dat >> 8); } - svga->ma += (x * 4); + svga->memaddr += (x * 4); } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - addr = svga->remap_func(svga, svga->ma); + addr = svga->remap_func(svga, svga->memaddr); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); *p++ = lookup_lut(dat >> 8); - svga->ma += 4; + svga->memaddr += 4; } } - svga->ma &= svga->vram_display_mask; + svga->memaddr &= svga->vram_display_mask; } } diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 36573e9f9..e8e945ab8 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -28,6 +28,7 @@ #include <86box/machine.h> #include <86box/mem.h> #include <86box/device.h> +#include <86box/lpt.h> #include <86box/plat.h> #include <86box/video.h> #include <86box/vid_svga.h> @@ -52,25 +53,69 @@ video_cards[] = { // clang-format off { .device = &device_none, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &device_internal, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &atiega800p_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &mach8_vga_isa_device, .flags = VIDEO_FLAG_TYPE_8514 }, - { .device = &mach32_isa_device, .flags = VIDEO_FLAG_TYPE_8514 }, - { .device = &mach64gx_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &ati28800k_device, .flags = VIDEO_FLAG_TYPE_NONE }, + /* ISA */ + { .device = &ati18800_wonder_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &ati18800_vga88_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &ati28800_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &compaq_ati28800_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &ati28800_wonder1024d_xl_plus_device, .flags = VIDEO_FLAG_TYPE_NONE }, #ifdef USE_XL24 { .device = &ati28800_wonderxl24_device, .flags = VIDEO_FLAG_TYPE_NONE }, #endif /* USE_XL24 */ + { .device = &ati28800_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &compaq_ati28800_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &ati28800_wonder1024d_xl_plus_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &atiega800p_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &mach8_vga_isa_device, .flags = VIDEO_FLAG_TYPE_8514 }, + { .device = &mach32_isa_device, .flags = VIDEO_FLAG_TYPE_8514 }, + { .device = &ati28800k_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &ati18800_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &ati18800_wonder_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &cga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &sega_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &jega_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5401_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5402_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &colorplus_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &compaq_cga_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &compaq_cga_2_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &cpqega_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &g2_gc205_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &hercules_device, .flags = VIDEO_FLAG_TYPE_MDA }, + { .device = &herculesplus_device, .flags = VIDEO_FLAG_TYPE_MDA }, + { .device = &incolor_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &cga_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &ega_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &mda_device, .flags = VIDEO_FLAG_TYPE_MDA }, + { .device = &pgc_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &vga_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &im1024_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &iskra_ega_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &jega_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000_kasan_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &genius_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &nga_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &nec_sv9000_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &ogc_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &jvga_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &oti037c_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &oti067_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &oti077_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = ¶dise_pvga1a_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = ¶dise_wd90c11_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = ¶dise_wd90c30_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &cga_pravetz_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &quadcolor_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &realtek_rtg3105_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &realtek_rtg3106_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &sigma_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &tvga8900b_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &tvga8900d_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &tvga8900dr_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &tvga9000b_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000k_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et2000_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et3000_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000_tc6058af_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &v7_vga_1024i_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &wy700_device, .flags = VIDEO_FLAG_TYPE_NONE }, + /* ISA16 */ + { .device = &mach64gx_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5420_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5422_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5426_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -80,62 +125,62 @@ video_cards[] = { { .device = &gd5429_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5434_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5434_diamond_speedstar_64_a3_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &compaq_cga_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &compaq_cga_2_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &cpqega_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &ega_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &g2_gc205_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &hercules_device, .flags = VIDEO_FLAG_TYPE_MDA }, - { .device = &herculesplus_device, .flags = VIDEO_FLAG_TYPE_MDA }, - { .device = &incolor_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &inmos_isa_device, .flags = VIDEO_FLAG_TYPE_XGA }, - { .device = &im1024_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &iskra_ega_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000_kasan_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &mda_device, .flags = VIDEO_FLAG_TYPE_MDA }, - { .device = &genius_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &nga_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &ogc_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &jvga_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &oti037c_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &oti067_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &oti077_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = ¶dise_pvga1a_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = ¶dise_wd90c11_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = ¶dise_wd90c30_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &colorplus_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &pgc_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &cga_pravetz_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &radius_svga_multiview_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &realtek_rtg3105_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &realtek_rtg3106_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_diamond_stealth_vram_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_orchid_86c911_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_ami_86c924_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_metheus_86c928_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_phoenix_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_spea_mirage_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &sigma_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &tvga8900b_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &tvga8900d_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &tvga8900dr_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &tvga9000b_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &nec_sv9000_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000k_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et2000_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et3000_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000_tc6058af_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_winner1000_805_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000w32_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000w32i_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &vga_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &v7_vga_1024i_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &wy700_device, .flags = VIDEO_FLAG_TYPE_NONE }, + /* MCA */ { .device = &mach32_mca_device, .flags = VIDEO_FLAG_TYPE_8514 }, { .device = &gd5426_mca_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5428_mca_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000_mca_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &radius_svga_multiview_mca_device, .flags = VIDEO_FLAG_TYPE_NONE }, + /* VLB */ + { .device = &mach32_vlb_device, .flags = VIDEO_FLAG_TYPE_8514 }, + { .device = &mach64gx_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32i_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_videomagic_revb_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_revc_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_cardex_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_noncardex_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5424_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5426_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5428_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5428_diamond_speedstar_pro_b1_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5429_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5430_diamond_speedstar_pro_se_a8_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5430_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5434_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_metheus_86c928_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_mirocrystal_8s_805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_mirocrystal_10sd_805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_phoenix_86c805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_spea_mirage_86c805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_diamond_stealth64_964_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_mirocrystal_20sv_964_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_mirocrystal_20sd_864_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_bahamas64_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_phoenix_vision864_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_diamond_stealth_se_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_phoenix_trio32_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_diamond_stealth64_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_9fx_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_phoenix_trio64_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_spea_mirage_p64_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_diamond_stealth64_968_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_stb_powergraph_64_video_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &ht216_32_standalone_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &tgui9400cxi_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &tgui9440_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + /* PCI */ { .device = &mach32_pci_device, .flags = VIDEO_FLAG_TYPE_8514 }, { .device = &mach64gx_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &mach64vt2_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -199,43 +244,7 @@ video_cards[] = { { .device = &voodoo_3_1000_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &voodoo_3_2000_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &voodoo_3_3000_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &mach32_vlb_device, .flags = VIDEO_FLAG_TYPE_8514 }, - { .device = &mach64gx_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32i_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_videomagic_revb_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_revc_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_cardex_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_noncardex_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &gd5424_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &gd5426_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &gd5428_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &gd5428_diamond_speedstar_pro_b1_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &gd5429_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &gd5430_diamond_speedstar_pro_se_a8_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &gd5430_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &gd5434_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_metheus_86c928_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_mirocrystal_8s_805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_mirocrystal_10sd_805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_phoenix_86c805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_spea_mirage_86c805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_diamond_stealth64_964_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_mirocrystal_20sv_964_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_mirocrystal_20sd_864_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_bahamas64_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_phoenix_vision864_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_diamond_stealth_se_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_phoenix_trio32_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_diamond_stealth64_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_9fx_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_phoenix_trio64_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_spea_mirage_p64_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_diamond_stealth64_968_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &s3_stb_powergraph_64_video_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &ht216_32_standalone_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &tgui9400cxi_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &tgui9440_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + /* AGP */ { .device = &s3_virge_357_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_diamond_stealth_4000_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_trio3d2x_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -327,7 +336,7 @@ video_reset(int card) card, machine_has_flags(machine, MACHINE_VIDEO) ? 1 : 0); monitor_index_global = 0; - loadfont("roms/video/mda/mda.rom", 0); + loadfont(FONT_IBM_MDA_437_PATH, 0); for (uint8_t i = 1; i < GFXCARD_MAX; i ++) { if ((card != VID_NONE) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY) && diff --git a/src/video/vid_tandy.c b/src/video/vid_tandy.c new file mode 100644 index 000000000..7d9b5af1a --- /dev/null +++ b/src/video/vid_tandy.c @@ -0,0 +1,827 @@ +/* + * 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. + * + * Tandy 1000 video emulation + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * Connor Hyde / starfrost, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2025 starfrost + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/nmi.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/device.h> +#include <86box/nvr.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/fdc_ext.h> +#include <86box/gameport.h> +#include <86box/keyboard.h> +#include <86box/sound.h> +#include <86box/snd_sn76489.h> +#include <86box/video.h> +#include <86box/vid_cga_comp.h> +#include <86box/m_tandy.h> +#include <86box/machine.h> +#include <86box/plat_unused.h> + +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 crtcmask_sl[32] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, + 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +enum { + TANDY_RGB = 0, + TANDY_COMPOSITE +}; + +static video_timings_t timing_dram = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*No additional waitstates*/ + +static void +recalc_mapping(tandy_t *dev) +{ + t1kvid_t *vid = dev->vid; + + mem_mapping_disable(&vid->mapping); + io_removehandler(0x03d0, 16, + tandy_vid_in, NULL, NULL, tandy_vid_out, NULL, NULL, dev); + + if (vid->planar_ctrl & 4) { + mem_mapping_enable(&vid->mapping); + if (vid->array[5] & 1) + mem_mapping_set_addr(&vid->mapping, 0xa0000, 0x10000); + else + mem_mapping_set_addr(&vid->mapping, 0xb8000, 0x8000); + io_sethandler(0x03d0, 16, tandy_vid_in, NULL, NULL, tandy_vid_out, NULL, NULL, dev); + } +} + +static void +recalc_timings(tandy_t *dev) +{ + t1kvid_t *vid = dev->vid; + + double _dispontime; + double _dispofftime; + double disptime; + + if (vid->mode & 1) { + disptime = vid->crtc[0] + 1; + _dispontime = vid->crtc[1]; + } else { + disptime = (vid->crtc[0] + 1) << 1; + _dispontime = vid->crtc[1] << 1; + } + + _dispofftime = disptime - _dispontime; + _dispontime *= CGACONST; + _dispofftime *= CGACONST; + vid->dispontime = (uint64_t) (_dispontime); + vid->dispofftime = (uint64_t) (_dispofftime); +} + +static void +recalc_address(tandy_t *dev) +{ + t1kvid_t *vid = dev->vid; + + if ((vid->memctrl & 0xc0) == 0xc0) { + vid->vram = &ram[((vid->memctrl & 0x06) << 14) + dev->base]; + vid->b8000 = &ram[((vid->memctrl & 0x30) << 11) + dev->base]; + vid->b8000_mask = 0x7fff; + } else { + vid->vram = &ram[((vid->memctrl & 0x07) << 14) + dev->base]; + vid->b8000 = &ram[((vid->memctrl & 0x38) << 11) + dev->base]; + vid->b8000_mask = 0x3fff; + } +} + +void +tandy_recalc_address_sl(tandy_t *dev) +{ + t1kvid_t *vid = dev->vid; + + vid->b8000_limit = 0x8000; + + if (vid->array[5] & 1) { + vid->vram = &ram[((vid->memctrl & 0x04) << 14) + dev->base]; + vid->b8000 = &ram[((vid->memctrl & 0x20) << 11) + dev->base]; + } else if ((vid->memctrl & 0xc0) == 0xc0) { + vid->vram = &ram[((vid->memctrl & 0x06) << 14) + dev->base]; + vid->b8000 = &ram[((vid->memctrl & 0x30) << 11) + dev->base]; + } else { + vid->vram = &ram[((vid->memctrl & 0x07) << 14) + dev->base]; + vid->b8000 = &ram[((vid->memctrl & 0x38) << 11) + dev->base]; + if ((vid->memctrl & 0x38) == 0x38) + vid->b8000_limit = 0x4000; + } +} + +static void +vid_update_latch(t1kvid_t *vid) +{ + uint32_t lp_latch = vid->displine * vid->crtc[1]; + + vid->crtc[0x10] = (lp_latch >> 8) & 0x3f; + vid->crtc[0x11] = lp_latch & 0xff; +} + +void +tandy_vid_out(uint16_t addr, uint8_t val, void *priv) +{ + tandy_t *dev = (tandy_t *) priv; + t1kvid_t *vid = dev->vid; + uint8_t old; + + if ((addr >= 0x3d0) && (addr <= 0x3d7)) + addr = (addr & 0xff9) | 0x004; + + switch (addr) { + case 0x03d4: + vid->crtcreg = val & 0x1f; + break; + + case 0x03d5: + old = vid->crtc[vid->crtcreg]; + if (dev->is_sl2) + vid->crtc[vid->crtcreg] = val & crtcmask_sl[vid->crtcreg]; + else + vid->crtc[vid->crtcreg] = val & crtcmask[vid->crtcreg]; + if (old != val) { + if (vid->crtcreg < 0xe || vid->crtcreg > 0x10) { + vid->fullchange = changeframecount; + recalc_timings(dev); + } + } + break; + + case 0x03d8: + old = vid->mode; + vid->mode = val; + if ((old ^ val) & 0x01) + recalc_timings(dev); + if (!dev->is_sl2) + update_cga16_color(vid->mode); + break; + + case 0x03d9: + vid->col = val; + break; + + case 0x03da: + vid->array_index = val & 0x1f; + break; + + case 0x3db: + if (!dev->is_sl2 && (vid->lp_strobe == 1)) + vid->lp_strobe = 0; + break; + + case 0x3dc: + if (!dev->is_sl2 && (vid->lp_strobe == 0)) { + vid->lp_strobe = 1; + vid_update_latch(vid); + } + break; + + case 0x03de: + if (vid->array_index & 16) + val &= 0xf; + vid->array[vid->array_index & 0x1f] = val; + if (dev->is_sl2) { + if ((vid->array_index & 0x1f) == 5) { + recalc_mapping(dev); + tandy_recalc_address_sl(dev); + } + } + break; + + case 0x03df: + vid->memctrl = val; + if (dev->is_sl2) + tandy_recalc_address_sl(dev); + else + recalc_address(dev); + break; + + case 0x0065: + if (val == 8) + return; /*Hack*/ + vid->planar_ctrl = val; + recalc_mapping(dev); + break; + + default: + break; + } +} + +uint8_t +tandy_vid_in(uint16_t addr, void *priv) +{ + const tandy_t *dev = (tandy_t *) priv; + t1kvid_t *vid = dev->vid; + uint8_t ret = 0xff; + + if ((addr >= 0x3d0) && (addr <= 0x3d7)) + addr = (addr & 0xff9) | 0x004; + + switch (addr) { + case 0x03d4: + ret = vid->crtcreg; + break; + + case 0x03d5: + ret = vid->crtc[vid->crtcreg]; + break; + + case 0x03da: + ret = vid->status; + break; + + case 0x3db: + if (!dev->is_sl2 && (vid->lp_strobe == 1)) + vid->lp_strobe = 0; + break; + + case 0x3dc: + if (!dev->is_sl2 && (vid->lp_strobe == 0)) { + vid->lp_strobe = 1; + vid_update_latch(vid); + } + break; + + default: + break; + } + + return ret; +} + +static void +vid_write(uint32_t addr, uint8_t val, void *priv) +{ + tandy_t *dev = (tandy_t *) priv; + t1kvid_t *vid = dev->vid; + + if (vid->memctrl == -1) + return; + + if (dev->is_sl2) { + if (vid->array[5] & 1) + vid->b8000[addr & 0xffff] = val; + else { + if ((addr & 0x7fff) < vid->b8000_limit) + vid->b8000[addr & 0x7fff] = val; + } + } else { + vid->b8000[addr & vid->b8000_mask] = val; + } +} + +static uint8_t +vid_read(uint32_t addr, void *priv) +{ + const tandy_t *dev = (tandy_t *) priv; + const t1kvid_t *vid = dev->vid; + + if (vid->memctrl == -1) + return 0xff; + + if (dev->is_sl2) { + if (vid->array[5] & 1) + return (vid->b8000[addr & 0xffff]); + if ((addr & 0x7fff) < vid->b8000_limit) + return (vid->b8000[addr & 0x7fff]); + else + return 0xff; + } else { + return (vid->b8000[addr & vid->b8000_mask]); + } +} + +static void +vid_poll(void *priv) +{ + tandy_t *dev = (tandy_t *) priv; + t1kvid_t *vid = dev->vid; + uint16_t cursoraddr = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff; + int drawcursor; + int x; + int c; + int xs_temp; + int ys_temp; + int oldvc; + uint8_t chr; + uint8_t attr; + uint16_t dat; + int cols[4]; + int col; + int scanline_old; + + if (!vid->linepos) { + timer_advance_u64(&vid->timer, vid->dispofftime); + vid->status |= 1; + vid->linepos = 1; + scanline_old = vid->scanline; + if ((vid->crtc[8] & 3) == 3) + vid->scanline = (vid->scanline << 1) & 7; + if (vid->dispon) { + if (vid->displine < vid->firstline) { + vid->firstline = vid->displine; + video_wait_for_buffer(); + } + vid->lastline = vid->displine; + cols[0] = (vid->array[2] & 0xf) + 16; + for (c = 0; c < 8; c++) { + if (vid->array[3] & 4) { + buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = cols[0]; + if (vid->mode & 1) { + buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = cols[0]; + } else { + buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = cols[0]; + } + } else if ((vid->mode & 0x12) == 0x12) { + buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = 0; + if (vid->mode & 1) { + buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = 0; + } else { + buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = 0; + } + } else { + buffer32->line[vid->displine << 1][c] = buffer32->line[(vid->displine << 1) + 1][c] = (vid->col & 15) + 16; + if (vid->mode & 1) { + buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 3) + 8] = (vid->col & 15) + 16; + } else { + buffer32->line[vid->displine << 1][c + (vid->crtc[1] << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][c + (vid->crtc[1] << 4) + 8] = (vid->col & 15) + 16; + } + } + } + if (dev->is_sl2 && (vid->array[5] & 1)) { /*640x200x16*/ + for (x = 0; x < vid->crtc[1] * 2; x++) { + dat = (vid->vram[(vid->memaddr << 1) & 0xffff] << 8) | vid->vram[((vid->memaddr << 1) + 1) & 0xffff]; + vid->memaddr++; + buffer32->line[vid->displine << 1][(x << 2) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 8] = vid->array[((dat >> 12) & 0xf) + 16] + 16; + buffer32->line[vid->displine << 1][(x << 2) + 9] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 9] = vid->array[((dat >> 8) & 0xf) + 16] + 16; + buffer32->line[vid->displine << 1][(x << 2) + 10] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 10] = vid->array[((dat >> 4) & 0xf) + 16] + 16; + buffer32->line[vid->displine << 1][(x << 2) + 11] = buffer32->line[(vid->displine << 1) + 1][(x << 2) + 11] = vid->array[(dat & 0xf) + 16] + 16; + } + } else if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/ + for (x = 0; x < vid->crtc[1]; x++) { + dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000)] << 8) | vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000) + 1]; + vid->memaddr++; + buffer32->line[vid->displine << 1][(x << 3) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 8] = buffer32->line[vid->displine << 1][(x << 3) + 9] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 9] = vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16; + buffer32->line[vid->displine << 1][(x << 3) + 10] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 10] = buffer32->line[vid->displine << 1][(x << 3) + 11] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 11] = vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16; + buffer32->line[vid->displine << 1][(x << 3) + 12] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 12] = buffer32->line[vid->displine << 1][(x << 3) + 13] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 13] = vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16; + buffer32->line[vid->displine << 1][(x << 3) + 14] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 14] = buffer32->line[vid->displine << 1][(x << 3) + 15] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 15] = vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16; + } + } else if (vid->array[3] & 0x10) { /*160x200x16*/ + for (x = 0; x < vid->crtc[1]; x++) { + if (dev->is_sl2) { + dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000)] << 8) | vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000) + 1]; + } else { + dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000)] << 8) | vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000) + 1]; + } + vid->memaddr++; + buffer32->line[vid->displine << 1][(x << 4) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 8] = buffer32->line[vid->displine << 1][(x << 4) + 9] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 9] = buffer32->line[vid->displine << 1][(x << 4) + 10] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 10] = buffer32->line[vid->displine << 1][(x << 4) + 11] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 11] = vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16; + buffer32->line[vid->displine << 1][(x << 4) + 12] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 12] = buffer32->line[vid->displine << 1][(x << 4) + 13] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 13] = buffer32->line[vid->displine << 1][(x << 4) + 14] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 14] = buffer32->line[vid->displine << 1][(x << 4) + 15] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 15] = vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16; + buffer32->line[vid->displine << 1][(x << 4) + 16] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 16] = buffer32->line[vid->displine << 1][(x << 4) + 17] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 17] = buffer32->line[vid->displine << 1][(x << 4) + 18] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 18] = buffer32->line[vid->displine << 1][(x << 4) + 19] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 19] = vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16; + buffer32->line[vid->displine << 1][(x << 4) + 20] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 20] = buffer32->line[vid->displine << 1][(x << 4) + 21] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 21] = buffer32->line[vid->displine << 1][(x << 4) + 22] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 22] = buffer32->line[vid->displine << 1][(x << 4) + 23] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + 23] = vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16; + } + } else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/ + for (x = 0; x < vid->crtc[1]; x++) { + dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000)] << 8) | vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000) + 1]; + vid->memaddr++; + for (c = 0; c < 8; c++) { + chr = (dat >> 6) & 2; + chr |= ((dat >> 15) & 1); + buffer32->line[vid->displine << 1][(x << 3) + 8 + c] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + 8 + c] = vid->array[(chr & vid->array[1]) + 16] + 16; + dat <<= 1; + } + } + } else if (vid->mode & 1) { + for (x = 0; x < vid->crtc[1]; x++) { + chr = vid->vram[(vid->memaddr << 1) & 0x3fff]; + attr = vid->vram[((vid->memaddr << 1) + 1) & 0x3fff]; + drawcursor = ((vid->memaddr == cursoraddr) && vid->cursorvisible && vid->cursoron); + if (vid->mode & 0x20) { + cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16; + cols[0] = vid->array[(((attr >> 4) & 7) & vid->array[1]) + 16] + 16; + if ((vid->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16; + cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16; + } + if (vid->scanline & 8) { + for (c = 0; c < 8; c++) { + buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = ((chr >= 0xb3) && (chr <= 0xdf)) ? cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0] : cols[0]; + } + } else { + for (c = 0; c < 8; c++) { + if (vid->scanline == 8) { + buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0]; + } else { + buffer32->line[vid->displine << 1][(x << 3) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + } + if (drawcursor) { + for (c = 0; c < 8; c++) { + buffer32->line[vid->displine << 1][(x << 3) + c + 8] ^= 15; + buffer32->line[(vid->displine << 1) + 1][(x << 3) + c + 8] ^= 15; + } + } + vid->memaddr++; + } + } else if (!(vid->mode & 2)) { + for (x = 0; x < vid->crtc[1]; x++) { + chr = vid->vram[(vid->memaddr << 1) & 0x3fff]; + attr = vid->vram[((vid->memaddr << 1) + 1) & 0x3fff]; + drawcursor = ((vid->memaddr == cursoraddr) && vid->cursorvisible && vid->cursoron); + if (vid->mode & 0x20) { + cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16; + cols[0] = vid->array[(((attr >> 4) & 7) & vid->array[1]) + 16] + 16; + if ((vid->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16; + cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16; + } + vid->memaddr++; + if (vid->scanline & 8) { + for (c = 0; c < 8; c++) + buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = ((chr >= 0xb3) && (chr <= 0xdf)) ? cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0] : cols[0]; + } else { + for (c = 0; c < 8; c++) { + if (vid->scanline == 8) { + buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0]; + } else { + buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + } + if (drawcursor) { + for (c = 0; c < 16; c++) { + buffer32->line[vid->displine << 1][(x << 4) + c + 8] ^= 15; + buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] ^= 15; + } + } + } + } else if (!(vid->mode & 16)) { + cols[0] = (vid->col & 15); + col = (vid->col & 16) ? 8 : 0; + if (vid->mode & 4) { + cols[1] = col | 3; + cols[2] = col | 4; + cols[3] = col | 7; + } else if (vid->col & 32) { + cols[1] = col | 3; + cols[2] = col | 5; + cols[3] = col | 7; + } else { + cols[1] = col | 2; + cols[2] = col | 4; + cols[3] = col | 6; + } + cols[0] = vid->array[(cols[0] & vid->array[1]) + 16] + 16; + cols[1] = vid->array[(cols[1] & vid->array[1]) + 16] + 16; + cols[2] = vid->array[(cols[2] & vid->array[1]) + 16] + 16; + cols[3] = vid->array[(cols[3] & vid->array[1]) + 16] + 16; + for (x = 0; x < vid->crtc[1]; x++) { + dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000)] << 8) | vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000) + 1]; + vid->memaddr++; + for (c = 0; c < 8; c++) { + buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[vid->displine << 1][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + dat <<= 2; + } + } + } else { + cols[0] = 0; + cols[1] = vid->array[(vid->col & vid->array[1]) + 16] + 16; + for (x = 0; x < vid->crtc[1]; x++) { + dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000)] << 8) | vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000) + 1]; + vid->memaddr++; + for (c = 0; c < 16; c++) { + buffer32->line[vid->displine << 1][(x << 4) + c + 8] = buffer32->line[(vid->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15]; + dat <<= 1; + } + } + } + } else { + if (vid->array[3] & 4) { + if (vid->mode & 1) { + hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16); + hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16); + } else { + hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 4) + 16, (vid->array[2] & 0xf) + 16); + hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 4) + 16, (vid->array[2] & 0xf) + 16); + } + } else { + cols[0] = ((vid->mode & 0x12) == 0x12) ? 0 : (vid->col & 0xf) + 16; + if (vid->mode & 1) { + hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 3) + 16, cols[0]); + hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 3) + 16, cols[0]); + } else { + hline(buffer32, 0, (vid->displine << 1), (vid->crtc[1] << 4) + 16, cols[0]); + hline(buffer32, 0, (vid->displine << 1) + 1, (vid->crtc[1] << 4) + 16, cols[0]); + } + } + } + + if (vid->mode & 1) + x = (vid->crtc[1] << 3) + 16; + else + x = (vid->crtc[1] << 4) + 16; + if (!dev->is_sl2 && vid->composite) { + Composite_Process(vid->mode, 0, x >> 2, buffer32->line[vid->displine << 1]); + Composite_Process(vid->mode, 0, x >> 2, buffer32->line[(vid->displine << 1) + 1]); + } else { + video_process_8(x, vid->displine << 1); + video_process_8(x, (vid->displine << 1) + 1); + } + vid->scanline = scanline_old; + if (vid->vc == vid->crtc[7] && !vid->scanline) + vid->status |= 8; + vid->displine++; + if (vid->displine >= 360) + vid->displine = 0; + } else { + timer_advance_u64(&vid->timer, vid->dispontime); + if (vid->dispon) + vid->status &= ~1; + vid->linepos = 0; + if (vid->vsynctime) { + vid->vsynctime--; + if (!vid->vsynctime) + vid->status &= ~8; + } + if (vid->scanline == (vid->crtc[11] & 31) || ((vid->crtc[8] & 3) == 3 && vid->scanline == ((vid->crtc[11] & 31) >> 1))) { + vid->cursorvisible = 0; + } + if (vid->vadj) { + vid->scanline++; + vid->scanline &= 31; + vid->memaddr = vid->memaddr_backup; + vid->vadj--; + if (!vid->vadj) { + vid->dispon = 1; + if (dev->is_sl2 && (vid->array[5] & 1)) + vid->memaddr = vid->memaddr_backup = vid->crtc[13] | (vid->crtc[12] << 8); + else + vid->memaddr = vid->memaddr_backup = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff; + vid->scanline = 0; + } + } else if (vid->scanline == vid->crtc[9] || ((vid->crtc[8] & 3) == 3 && vid->scanline == (vid->crtc[9] >> 1))) { + vid->memaddr_backup = vid->memaddr; + vid->scanline = 0; + oldvc = vid->vc; + vid->vc++; + if (dev->is_sl2) + vid->vc &= 255; + else + vid->vc &= 127; + if (vid->vc == vid->crtc[6]) + vid->dispon = 0; + if (oldvc == vid->crtc[4]) { + vid->vc = 0; + vid->vadj = vid->crtc[5]; + if (!vid->vadj) + vid->dispon = 1; + if (!vid->vadj) { + if (dev->is_sl2 && (vid->array[5] & 1)) + vid->memaddr = vid->memaddr_backup = vid->crtc[13] | (vid->crtc[12] << 8); + else + vid->memaddr = vid->memaddr_backup = (vid->crtc[13] | (vid->crtc[12] << 8)) & 0x3fff; + } + if ((vid->crtc[10] & 0x60) == 0x20) + vid->cursoron = 0; + else + vid->cursoron = vid->blink & 16; + } + if (vid->vc == vid->crtc[7]) { + vid->dispon = 0; + vid->displine = 0; + vid->vsynctime = 16; + picint(1 << 5); + if (vid->crtc[7]) { + if (vid->mode & 1) + x = (vid->crtc[1] << 3) + 16; + else + x = (vid->crtc[1] << 4) + 16; + vid->lastline++; + + xs_temp = x; + ys_temp = (vid->lastline - vid->firstline) << 1; + + if ((xs_temp > 0) && (ys_temp > 0)) { + if (xs_temp < 64) + xs_temp = 656; + if (ys_temp < 32) + ys_temp = 400; + if (!enable_overscan) + xs_temp -= 16; + + if ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get()) { + xsize = xs_temp; + ysize = ys_temp; + set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); + + if (video_force_resize_get()) + video_force_resize_set(0); + } + + if (enable_overscan) { + video_blit_memtoscreen(0, (vid->firstline - 4) << 1, + xsize, ((vid->lastline - vid->firstline) + 8) << 1); + } else { + video_blit_memtoscreen(8, vid->firstline << 1, + xsize, (vid->lastline - vid->firstline) << 1); + } + } + + frames++; + + video_res_x = xsize; + video_res_y = ysize; + if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/ + video_res_x /= 2; + video_bpp = 4; + } else if (vid->array[3] & 0x10) { /*160x200x16*/ + video_res_x /= 4; + video_bpp = 4; + } else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/ + video_bpp = 2; + } else if (vid->mode & 1) { + video_res_x /= 8; + video_res_y /= vid->crtc[9] + 1; + video_bpp = 0; + } else if (!(vid->mode & 2)) { + video_res_x /= 16; + video_res_y /= vid->crtc[9] + 1; + video_bpp = 0; + } else if (!(vid->mode & 16)) { + video_res_x /= 2; + video_bpp = 2; + } else { + video_bpp = 1; + } + } + vid->firstline = 1000; + vid->lastline = 0; + vid->blink++; + } + } else { + vid->scanline++; + vid->scanline &= 31; + vid->memaddr = vid->memaddr_backup; + } + if (vid->scanline == (vid->crtc[10] & 31) || ((vid->crtc[8] & 3) == 3 && vid->scanline == ((vid->crtc[10] & 31) >> 1))) + vid->cursorvisible = 1; + } +} + +void +tandy_vid_speed_changed(void *priv) +{ + tandy_t *dev = (tandy_t *) priv; + + recalc_timings(dev); +} + +void +tandy_vid_close(void *priv) +{ + tandy_t *dev = (tandy_t *) priv; + + free(dev->vid); + dev->vid = NULL; +} + +void +tandy_vid_init(tandy_t *dev) +{ + int display_type; + t1kvid_t *vid; + + vid = calloc(1, sizeof(t1kvid_t)); + vid->memctrl = -1; + + video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram); + + display_type = device_get_config_int("display_type"); + vid->composite = (display_type != TANDY_RGB); + + cga_comp_init(1); + + if (dev->is_sl2) { + vid->b8000_limit = 0x8000; + vid->planar_ctrl = 4; + overscan_x = overscan_y = 16; + + io_sethandler(0x0065, 1, tandy_vid_in, NULL, NULL, tandy_vid_out, NULL, NULL, dev); + } else + vid->b8000_mask = 0x3fff; + + timer_add(&vid->timer, vid_poll, dev, 1); + mem_mapping_add(&vid->mapping, 0xb8000, 0x08000, + vid_read, NULL, NULL, vid_write, NULL, NULL, NULL, 0, dev); + io_sethandler(0x03d0, 16, + tandy_vid_in, NULL, NULL, tandy_vid_out, NULL, NULL, dev); + + dev->vid = vid; +} + +const device_config_t vid_config[] = { + // clang-format off + { + .name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = TANDY_RGB, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "RGB", .value = TANDY_RGB }, + { .description = "Composite", .value = TANDY_COMPOSITE }, + { .description = "" } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t tandy_1000_video_device = { + .name = "Tandy 1000", + .internal_name = "tandy1000_video", + .flags = 0, + .local = 0, + .init = NULL, + .close = tandy_vid_close, + .reset = NULL, + .available = NULL, + .speed_changed = tandy_vid_speed_changed, + .force_redraw = NULL, + .config = vid_config +}; + +const device_t tandy_1000hx_video_device = { + .name = "Tandy 1000 HX", + .internal_name = "tandy1000_hx_video", + .flags = 0, + .local = 0, + .init = NULL, + .close = tandy_vid_close, + .reset = NULL, + .available = NULL, + .speed_changed = tandy_vid_speed_changed, + .force_redraw = NULL, + .config = vid_config +}; + +const device_t tandy_1000sl_video_device = { + .name = "Tandy 1000SL2", + .internal_name = "tandy1000_sl_video", + .flags = 0, + .local = 1, + .init = NULL, + .close = tandy_vid_close, + .reset = NULL, + .available = NULL, + .speed_changed = tandy_vid_speed_changed, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index af203f327..6a0e1ca5e 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -72,6 +72,7 @@ #include <86box/video.h> #include <86box/i2c.h> #include <86box/vid_ddc.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> @@ -125,6 +126,7 @@ typedef struct tgui_t { uint8_t rop; uint32_t flags; uint8_t pattern[0x80]; + uint8_t pattern_32bpp[0x100]; int command; int offset; uint16_t ger22; @@ -142,6 +144,7 @@ typedef struct tgui_t { uint32_t pattern_8[8 * 8]; uint32_t pattern_16[8 * 8]; uint32_t pattern_32[8 * 8]; + int pattern_32_idx; } accel; uint8_t copy_latch[16]; /*TGUI9400CXi only*/ @@ -541,7 +544,7 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = svga->monitor->mon_changeframecount; svga_recalctimings(svga); @@ -724,13 +727,13 @@ tgui_recalctimings(svga_t *svga) #endif if ((svga->crtc[0x1e] & 0xA0) == 0xA0) - svga->ma_latch |= 0x10000; + svga->memaddr_latch |= 0x10000; if (svga->crtc[0x27] & 0x01) - svga->ma_latch |= 0x20000; + svga->memaddr_latch |= 0x20000; if (svga->crtc[0x27] & 0x02) - svga->ma_latch |= 0x40000; + svga->memaddr_latch |= 0x40000; if (svga->crtc[0x27] & 0x04) - svga->ma_latch |= 0x80000; + svga->memaddr_latch |= 0x80000; if (svga->crtc[0x27] & 0x08) svga->split |= 0x400; @@ -756,8 +759,8 @@ tgui_recalctimings(svga_t *svga) if (svga->vdisp == 1020) svga->vdisp += 2; - if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) - svga->ma_latch <<= 1; + if (tgui->oldctrl2 & 0x10) + svga->memaddr_latch <<= 1; svga->lowres = !(svga->crtc[0x2a] & 0x40); @@ -909,6 +912,7 @@ static void tgui_recalcmapping(tgui_t *tgui) { svga_t *svga = &tgui->svga; + xga_t *xga = (xga_t *) svga->xga; if (tgui->type == TGUI_9400CXI) { if (svga->gdcreg[0x10] & EXT_CTRL_LATCH_COPY) { @@ -962,6 +966,10 @@ tgui_recalcmapping(tgui_t *tgui) case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) { + xga->on = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + } break; case 0x8: /*32k at B0000*/ mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); @@ -986,6 +994,10 @@ tgui_recalcmapping(tgui_t *tgui) case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) { + xga->on = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + } break; case 0x8: /*32k at B0000*/ mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); @@ -2280,6 +2292,8 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) if (count == -1) tgui->accel.x = tgui->accel.y = 0; + tgui->accel.pattern_32_idx = 0; + if (tgui->accel.flags & TGUI_SOLIDFILL) { for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { @@ -2298,22 +2312,21 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) if (tgui->accel.bpp == 0) { for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { - tgui->accel.pattern_8[(y * 8) + (7 - x)] = tgui->accel.pattern[x + y * 8]; + tgui->accel.pattern_8[(y * 8) + x] = tgui->accel.pattern[x + y * 8]; } } pattern_data = tgui->accel.pattern_8; } else if (tgui->accel.bpp == 1) { for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { - tgui->accel.pattern_16[(y * 8) + (7 - x)] = tgui->accel.pattern[x * 2 + y * 16] | (tgui->accel.pattern[x * 2 + y * 16 + 1] << 8); + tgui->accel.pattern_16[(y * 8) + x] = tgui->accel.pattern[x * 2 + y * 16] | (tgui->accel.pattern[x * 2 + y * 16 + 1] << 8); } } pattern_data = tgui->accel.pattern_16; } else { - for (y = 0; y < 4; y++) { + for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { - tgui->accel.pattern_32[(y * 8) + (7 - x)] = tgui->accel.pattern[x * 4 + y * 32] | (tgui->accel.pattern[x * 4 + y * 32 + 1] << 8) | (tgui->accel.pattern[x * 4 + y * 32 + 2] << 16) | (tgui->accel.pattern[x * 4 + y * 32 + 3] << 24); - tgui->accel.pattern_32[((y + 4) * 8) + (7 - x)] = tgui->accel.pattern[x * 4 + y * 32] | (tgui->accel.pattern[x * 4 + y * 32 + 1] << 8) | (tgui->accel.pattern[x * 4 + y * 32 + 2] << 16) | (tgui->accel.pattern[x * 4 + y * 32 + 3] << 24); + tgui->accel.pattern_32[(y * 8) + x] = tgui->accel.pattern_32bpp[x * 4 + y * 32] | (tgui->accel.pattern_32bpp[x * 4 + y * 32 + 1] << 8) | (tgui->accel.pattern_32bpp[x * 4 + y * 32 + 2] << 16) | (tgui->accel.pattern_32bpp[x * 4 + y * 32 + 3] << 24); } } pattern_data = tgui->accel.pattern_32; @@ -2396,6 +2409,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) count -= 3; } + READ(tgui->accel.dst, dst_dat); pat_dat = pattern_data[((tgui->accel.pat_y & 7) * 8) + (tgui->accel.pat_x & 7)]; @@ -3192,6 +3206,8 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *priv) case 0x21fe: case 0x21ff: tgui->accel.pattern[addr & 0x7f] = val; + tgui->accel.pattern_32bpp[tgui->accel.pattern_32_idx] = val; + tgui->accel.pattern_32_idx = (tgui->accel.pattern_32_idx + 1) & 0xff; break; default: diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 9dd7e424d..51ab132ca 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -168,7 +168,7 @@ tvga_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -293,15 +293,15 @@ tvga_recalctimings(svga_t *svga) svga->hdisp = (svga->crtc[1] + 1) * 8; if ((svga->crtc[0x1e] & 0xA0) == 0xA0) - svga->ma_latch |= 0x10000; + svga->memaddr_latch |= 0x10000; if ((svga->crtc[0x27] & 0x01) == 0x01) - svga->ma_latch |= 0x20000; + svga->memaddr_latch |= 0x20000; if ((svga->crtc[0x27] & 0x02) == 0x02) - svga->ma_latch |= 0x40000; + svga->memaddr_latch |= 0x40000; if (tvga->oldctrl2 & 0x10) { svga->rowoffset <<= 1; - svga->ma_latch <<= 1; + svga->memaddr_latch <<= 1; } if (svga->gdcreg[0xf] & 0x08) { diff --git a/src/video/vid_vga.c b/src/video/vid_vga.c index 8289fd4cb..4cde5ba01 100644 --- a/src/video/vid_vga.c +++ b/src/video/vid_vga.c @@ -63,7 +63,7 @@ vga_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index e45f112ed..57ddbf64d 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -530,6 +530,7 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) voodoo_recalc(voodoo); voodoo->front_offset = voodoo->params.front_offset; } + svga_recalctimings(voodoo->svga); } break; case SST_fbiInit1: diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 1381a95f7..86329ee8d 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ #include <86box/video.h> #include <86box/i2c.h> #include <86box/vid_ddc.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #include <86box/vid_voodoo_common.h> @@ -121,6 +123,8 @@ typedef struct banshee_t { uint32_t vidProcCfg; uint32_t vidScreenSize; uint32_t vidSerialParallelPort; + uint32_t vidChromaKeyMin; + uint32_t vidChromaKeyMax; uint32_t agpReqSize; uint32_t agpHostAddressHigh; @@ -153,6 +157,8 @@ typedef struct banshee_t { uint8_t pci_slot; uint8_t irq_state; + bool chroma_key_enabled; + void *i2c, *i2c_ddc, *ddc; } banshee_t; @@ -186,6 +192,8 @@ enum { Video_hwCurC0 = 0x68, Video_hwCurC1 = 0x6c, Video_vidSerialParallelPort = 0x78, + Video_vidChromaKeyMin = 0x8c, + Video_vidChromaKeyMax = 0x90, Video_vidScreenSize = 0x98, Video_vidOverlayStartCoords = 0x9c, Video_vidOverlayEndScreenCoords = 0xa0, @@ -385,7 +393,7 @@ banshee_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x11 || (svga->crtcreg == 0x11 && old != val)) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -445,6 +453,7 @@ static void banshee_updatemapping(banshee_t *banshee) { svga_t *svga = &banshee->svga; + xga_t *xga = (xga_t *) svga->xga; if (!(banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { #if 0 @@ -466,6 +475,10 @@ banshee_updatemapping(banshee_t *banshee) case 0x4: /*64k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) { + xga->on = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + } break; case 0x8: /*32k at B0000*/ mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); @@ -663,7 +676,7 @@ banshee_recalctimings(svga_t *svga) svga->rowoffset = ((banshee->vidDesktopOverlayStride & 0x3fff) * 128) >> 3; else svga->rowoffset = (banshee->vidDesktopOverlayStride & 0x3fff) >> 3; - svga->ma_latch = banshee->vidDesktopStartAddr >> 2; + svga->memaddr_latch = banshee->vidDesktopStartAddr >> 2; banshee->desktop_stride_tiled = (banshee->vidDesktopOverlayStride & 0x3fff) * 128 * 32; #if 0 banshee_log("Extended shift out %i rowoffset=%i %02x\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, svga->rowoffset, svga->crtc[1]); @@ -946,6 +959,14 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *priv) i2c_gpio_set(banshee->i2c, !!(val & VIDSERIAL_I2C_SCK_W), !!(val & VIDSERIAL_I2C_SDA_W)); break; + case Video_vidChromaKeyMin: + banshee->vidChromaKeyMin = val; + break; + + case Video_vidChromaKeyMax: + banshee->vidChromaKeyMax = val; + break; + case Video_vidScreenSize: banshee->vidScreenSize = val; voodoo->h_disp = (val & 0xfff) + 1; @@ -1253,6 +1274,12 @@ banshee_ext_inl(uint16_t addr, void *priv) #endif break; + case Video_vidChromaKeyMin: + ret = banshee->vidChromaKeyMin; + break; + case Video_vidChromaKeyMax: + ret = banshee->vidChromaKeyMax; + break; case Video_vidScreenSize: ret = banshee->vidScreenSize; break; @@ -2634,12 +2661,97 @@ voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg) } } +/* 1 = render overlay, 0 = render desktop */ +static bool +banshee_chroma_key(banshee_t* banshee, uint32_t x, uint32_t y) +{ + uint32_t src_addr_desktop = banshee->desktop_addr + y * (banshee->vidDesktopOverlayStride & 0x3fff); + bool res = true; + uint8_t chromaKeyMaxIndex = banshee->vidChromaKeyMax & 0xff; + uint8_t chromaKeyMinIndex = banshee->vidChromaKeyMin & 0xff; + uint32_t desktop_pixel = 0; + uint8_t desktop_r = 0; + uint8_t desktop_g = 0; + uint8_t desktop_b = 0; + uint32_t prev_desktop_y = banshee->desktop_y - 1; + + if (!banshee->chroma_key_enabled) + return true; + + if (y > 2048) + return true; + + if (!(banshee->vidProcCfg & (1 << 5))) { + return true; + } + + switch (VIDPROCCFG_DESKTOP_PIX_FORMAT) { + case PIX_FORMAT_8: + { + desktop_pixel = banshee->svga.vram[src_addr_desktop + x]; + res = (desktop_pixel & 0xFF) >= chromaKeyMinIndex && (desktop_pixel & 0xFF) <= chromaKeyMaxIndex; + break; + } + case PIX_FORMAT_RGB565: + { + if (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) { + uint32_t addr = 0; + if (prev_desktop_y & 0x80000000) + return false; + if (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE) + addr = banshee->desktop_addr + ((prev_desktop_y >> 1) & 31) * 128 + ((prev_desktop_y >> 6) * banshee->desktop_stride_tiled); + else + addr = banshee->desktop_addr + (prev_desktop_y & 31) * 128 + ((prev_desktop_y >> 5) * banshee->desktop_stride_tiled); + + addr += 128 * 32 * (x >> 6); + addr += (x & 63) * 2; + desktop_pixel = *(uint16_t*)&banshee->svga.vram[addr & banshee->svga.vram_mask]; + } else { + desktop_pixel = *(uint16_t*)&banshee->svga.vram[(src_addr_desktop + x * 2) & banshee->svga.vram_mask]; + } + + desktop_r = (desktop_pixel & 0x1f); + desktop_g = (desktop_pixel & 0x7e0) >> 5; + desktop_b = (desktop_pixel & 0xf800) >> 11; + + res = (desktop_r >= ((banshee->vidChromaKeyMin >> 11) & 0x1F) && desktop_r <= ((banshee->vidChromaKeyMax >> 11) & 0x1F)) && + (desktop_g >= ((banshee->vidChromaKeyMin >> 5) & 0x3F) && desktop_g <= ((banshee->vidChromaKeyMax >> 5) & 0x3F)) && + (desktop_b >= ((banshee->vidChromaKeyMin) & 0x1F) && desktop_b <= ((banshee->vidChromaKeyMax) & 0x1F)); + break; + } + case PIX_FORMAT_RGB24: + { + desktop_r = banshee->svga.vram[(src_addr_desktop + x * 3) & banshee->svga.vram_mask]; + desktop_g = banshee->svga.vram[(src_addr_desktop + x * 3 + 1) & banshee->svga.vram_mask]; + desktop_b = banshee->svga.vram[(src_addr_desktop + x * 3 + 2) & banshee->svga.vram_mask]; + res = (desktop_r >= ((banshee->vidChromaKeyMin >> 16) & 0xFF) && desktop_r <= ((banshee->vidChromaKeyMax >> 16) & 0xFF)) && + (desktop_g >= ((banshee->vidChromaKeyMin >> 8) & 0xFF) && desktop_g <= ((banshee->vidChromaKeyMax >> 8) & 0xFF)) && + (desktop_b >= ((banshee->vidChromaKeyMin) & 0xFF) && desktop_b <= ((banshee->vidChromaKeyMax) & 0xFF)); + break; + } + case PIX_FORMAT_RGB32: + { + desktop_r = banshee->svga.vram[(src_addr_desktop + x * 4) & banshee->svga.vram_mask]; + desktop_g = banshee->svga.vram[(src_addr_desktop + x * 4 + 1) & banshee->svga.vram_mask]; + desktop_b = banshee->svga.vram[(src_addr_desktop + x * 4 + 2) & banshee->svga.vram_mask]; + res = (desktop_r >= ((banshee->vidChromaKeyMin >> 16) & 0xFF) && desktop_r <= ((banshee->vidChromaKeyMax >> 16) & 0xFF)) && + (desktop_g >= ((banshee->vidChromaKeyMin >> 8) & 0xFF) && desktop_g <= ((banshee->vidChromaKeyMax >> 8) & 0xFF)) && + (desktop_b >= ((banshee->vidChromaKeyMin) & 0xFF) && desktop_b <= ((banshee->vidChromaKeyMax) & 0xFF)); + break; + } + } + + res ^= !!(banshee->vidProcCfg & (1 << 6)); + return res; +} + 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; + bool chroma_test_passed = true; 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); @@ -2655,6 +2767,8 @@ banshee_overlay_draw(svga_t *svga, int displine) return; } + chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x, displine - svga->y_add); + if ((voodoo->overlay.src_y >> 20) < 2048) voodoo->dirty_line[voodoo->overlay.src_y >> 20] = 0; #if 0 @@ -2671,7 +2785,8 @@ banshee_overlay_draw(svga_t *svga, int displine) if (skip_filtering) { /*No scaling or filtering required, just write straight to output buffer*/ - OVERLAY_SAMPLE(p); + if (chroma_test_passed) + OVERLAY_SAMPLE(p); } else { OVERLAY_SAMPLE(banshee->overlay_buffer[0]); @@ -2688,25 +2803,31 @@ banshee_overlay_draw(svga_t *svga, int displine) ((0x10000 - x_coeff) * y_coeff) >> 16, (x_coeff * y_coeff) >> 16 }; - uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; - uint32_t samp1 = banshee->overlay_buffer[0][(src_x >> 20) + 1]; - uint32_t samp2 = banshee->overlay_buffer[1][src_x >> 20]; - uint32_t samp3 = banshee->overlay_buffer[1][(src_x >> 20) + 1]; - int r = (((samp0 >> 16) & 0xff) * coeffs[0] + ((samp1 >> 16) & 0xff) * coeffs[1] + ((samp2 >> 16) & 0xff) * coeffs[2] + ((samp3 >> 16) & 0xff) * coeffs[3]) >> 16; - int g = (((samp0 >> 8) & 0xff) * coeffs[0] + ((samp1 >> 8) & 0xff) * coeffs[1] + ((samp2 >> 8) & 0xff) * coeffs[2] + ((samp3 >> 8) & 0xff) * coeffs[3]) >> 16; - int b = ((samp0 & 0xff) * coeffs[0] + (samp1 & 0xff) * coeffs[1] + (samp2 & 0xff) * coeffs[2] + (samp3 & 0xff) * coeffs[3]) >> 16; - p[x] = (r << 16) | (g << 8) | b; + uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; + uint32_t samp1 = banshee->overlay_buffer[0][(src_x >> 20) + 1]; + uint32_t samp2 = banshee->overlay_buffer[1][src_x >> 20]; + uint32_t samp3 = banshee->overlay_buffer[1][(src_x >> 20) + 1]; + int r = (((samp0 >> 16) & 0xff) * coeffs[0] + ((samp1 >> 16) & 0xff) * coeffs[1] + ((samp2 >> 16) & 0xff) * coeffs[2] + ((samp3 >> 16) & 0xff) * coeffs[3]) >> 16; + int g = (((samp0 >> 8) & 0xff) * coeffs[0] + ((samp1 >> 8) & 0xff) * coeffs[1] + ((samp2 >> 8) & 0xff) * coeffs[2] + ((samp3 >> 8) & 0xff) * coeffs[3]) >> 16; + int b = ((samp0 & 0xff) * coeffs[0] + (samp1 & 0xff) * coeffs[1] + (samp2 & 0xff) * coeffs[2] + (samp3 & 0xff) * coeffs[3]) >> 16; + chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add); + + if (chroma_test_passed) + p[x] = (r << 16) | (g << 8) | b; src_x += voodoo->overlay.vidOverlayDudx; } } else { for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { - uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; - uint32_t samp1 = banshee->overlay_buffer[1][src_x >> 20]; - int r = (((samp0 >> 16) & 0xff) * (0x10000 - y_coeff) + ((samp1 >> 16) & 0xff) * y_coeff) >> 16; - int g = (((samp0 >> 8) & 0xff) * (0x10000 - y_coeff) + ((samp1 >> 8) & 0xff) * y_coeff) >> 16; - int b = ((samp0 & 0xff) * (0x10000 - y_coeff) + (samp1 & 0xff) * y_coeff) >> 16; - p[x] = (r << 16) | (g << 8) | b; + uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; + uint32_t samp1 = banshee->overlay_buffer[1][src_x >> 20]; + int r = (((samp0 >> 16) & 0xff) * (0x10000 - y_coeff) + ((samp1 >> 16) & 0xff) * y_coeff) >> 16; + int g = (((samp0 >> 8) & 0xff) * (0x10000 - y_coeff) + ((samp1 >> 8) & 0xff) * y_coeff) >> 16; + int b = ((samp0 & 0xff) * (0x10000 - y_coeff) + (samp1 & 0xff) * y_coeff) >> 16; + chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add); + + if (chroma_test_passed) + p[x] = (r << 16) | (g << 8) | b; } } break; @@ -2761,21 +2882,30 @@ banshee_overlay_draw(svga_t *svga, int displine) fil3[x * 3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]]; } for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { - fil[x * 3] = vb_filter_v1_rb[fil[x * 3]][fil3[(x + 1) * 3]]; - fil[x * 3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil3[(x + 1) * 3 + 1]]; - fil[x * 3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil3[(x + 1) * 3 + 2]]; - p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3]; + fil[x * 3] = vb_filter_v1_rb[fil[x * 3]][fil3[(x + 1) * 3]]; + fil[x * 3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil3[(x + 1) * 3 + 1]]; + fil[x * 3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil3[(x + 1) * 3 + 2]]; + chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add); + + if (chroma_test_passed) + p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3]; } } else /* filter disabled by emulator option */ { if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { - p[x] = banshee->overlay_buffer[0][src_x >> 20]; + chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add); + if (chroma_test_passed) + p[x] = banshee->overlay_buffer[0][src_x >> 20]; + src_x += voodoo->overlay.vidOverlayDudx; } } else { - for (x = 0; x < svga->overlay_latch.cur_xsize; x++) - p[x] = banshee->overlay_buffer[0][x]; + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add); + if (chroma_test_passed) + p[x] = banshee->overlay_buffer[0][x]; + } } } break; @@ -2830,25 +2960,35 @@ banshee_overlay_draw(svga_t *svga, int displine) if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* 2x2 on a scaled low res */ { for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { - p[x] = (fil[(src_x >> 20) * 3 + 2] << 16) | (fil[(src_x >> 20) * 3 + 1] << 8) | fil[(src_x >> 20) * 3]; + chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add); + if (chroma_test_passed) + p[x] = (fil[(src_x >> 20) * 3 + 2] << 16) | (fil[(src_x >> 20) * 3 + 1] << 8) | fil[(src_x >> 20) * 3]; + src_x += voodoo->overlay.vidOverlayDudx; } } else { for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { - p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3]; + chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add); + if (chroma_test_passed) + p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3]; } } } else /* filter disabled by emulator option */ { if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { - p[x] = banshee->overlay_buffer[0][src_x >> 20]; + chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add); + if (chroma_test_passed) + p[x] = banshee->overlay_buffer[0][src_x >> 20]; src_x += voodoo->overlay.vidOverlayDudx; } } else { - for (x = 0; x < svga->overlay_latch.cur_xsize; x++) - p[x] = banshee->overlay_buffer[0][x]; + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add); + if (chroma_test_passed) + p[x] = banshee->overlay_buffer[0][x]; + } } } break; @@ -2857,13 +2997,18 @@ banshee_overlay_draw(svga_t *svga, int displine) default: if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { - p[x] = banshee->overlay_buffer[0][src_x >> 20]; + chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add); + if (chroma_test_passed) + p[x] = banshee->overlay_buffer[0][src_x >> 20]; src_x += voodoo->overlay.vidOverlayDudx; } } else { - for (x = 0; x < svga->overlay_latch.cur_xsize; x++) - p[x] = banshee->overlay_buffer[0][x]; + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + chroma_test_passed = banshee_chroma_key(banshee, svga->overlay_latch.x + x, displine - svga->y_add); + if (chroma_test_passed) + p[x] = banshee->overlay_buffer[0][x]; + } } break; } @@ -3262,6 +3407,8 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int banshee->agp = agp; banshee->has_bios = !!fn; + banshee->chroma_key_enabled = device_get_config_int("chromakey"); + if (banshee->has_bios) { rom_init(&banshee->bios_rom, fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&banshee->bios_rom.mapping); @@ -3692,6 +3839,17 @@ static const device_config_t banshee_sgram_config[] = { .selection = { { 0 } }, .bios = { { 0 } } }, + { + .name = "chromakey", + .description = "Video chroma-keying", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "dithersub", .description = "Dither subtraction", @@ -3758,6 +3916,17 @@ static const device_config_t banshee_sgram_16mbonly_config[] = { .selection = { { 0 } }, .bios = { { 0 } } }, + { + .name = "chromakey", + .description = "Video chroma-keying", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "dithersub", .description = "Dither subtraction", @@ -3824,6 +3993,17 @@ static const device_config_t banshee_sdram_config[] = { .selection = { { 0 } }, .bios = { { 0 } } }, + { + .name = "chromakey", + .description = "Video chroma-keying", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "dithersub", .description = "Dither subtraction", diff --git a/src/video/vid_voodoo_banshee_blitter.c b/src/video/vid_voodoo_banshee_blitter.c index 4dc39f332..cf2824bba 100644 --- a/src/video/vid_voodoo_banshee_blitter.c +++ b/src/video/vid_voodoo_banshee_blitter.c @@ -917,7 +917,19 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in 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; + int src_colorkey; + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { + case SRC_FORMAT_COL_8_BPP: + src_colorkey = COLORKEY_8; + break; + case SRC_FORMAT_COL_16_BPP: + src_colorkey = COLORKEY_16; + break; + default: + src_colorkey = COLORKEY_32; + break; + } #if 0 int error_y = voodoo->banshee_blt.dstSizeY / 2; @@ -925,104 +937,218 @@ do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, in bansheeblt_log(" srcXY=%i,%i srcsizeXY=%i,%i\n", voodoo->banshee_blt.srcX, voodoo->banshee_blt.srcY, voodoo->banshee_blt.srcSizeX, voodoo->banshee_blt.srcSizeY); bansheeblt_log(" dstXY=%i,%i dstsizeXY=%i,%i\n", voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY, voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY);*/ #endif - if (dst_y >= clip->y_min && dst_y < clip->y_max) { -#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]; - int error_x = voodoo->banshee_blt.dstSizeX / 2; + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK)) { + if (dst_y >= clip->y_min && dst_y < clip->y_max) { + 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]; + int error_x = voodoo->banshee_blt.dstSizeX / 2; -#if 0 - bansheeblt_log(" Plot dest line %03i : src line %03i\n", dst_y, src_y); -#endif - for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { - int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; - if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { - switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { - case DST_FORMAT_COL_8_BPP: - { - uint32_t dst_addr = get_addr(voodoo, dst_x, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = src_p[src_x]; - uint32_t dest = voodoo->vram[dst_addr]; - 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]; + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { + switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { + case DST_FORMAT_COL_8_BPP: + { + uint32_t dst_addr = get_addr(voodoo, dst_x, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = src_p[src_x]; + uint32_t dest = voodoo->vram[dst_addr]; + 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]; - if (dst_addr > voodoo->fb_mask) + if (dst_addr > voodoo->fb_mask) + break; + + voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); + voodoo->changedvram[dst_addr >> 12] = changeframecount; break; + } + case DST_FORMAT_COL_16_BPP: + { + uint32_t dst_addr = get_addr(voodoo, dst_x * 2, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint16_t *) &src_p[src_x * 2]; + uint32_t dest = *(uint16_t *) &voodoo->vram[dst_addr]; + 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); -#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; - } - case DST_FORMAT_COL_16_BPP: - { - uint32_t dst_addr = get_addr(voodoo, dst_x * 2, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint16_t *) &src_p[src_x * 2]; - uint32_t dest = *(uint16_t *) &voodoo->vram[dst_addr]; - 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]; + if (dst_addr > voodoo->fb_mask) + break; - if (dst_addr > voodoo->fb_mask) + *(uint16_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); + voodoo->changedvram[dst_addr >> 12] = changeframecount; break; + } + case DST_FORMAT_COL_24_BPP: + { + uint32_t dst_addr = get_addr(voodoo, dst_x * 3, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *) &src_p[src_x * 3]; + uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; + 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]; - *(uint16_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); -#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, *(uint16_t *)&voodoo->vram[dst_addr]); -#endif - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_24_BPP: - { - uint32_t dst_addr = get_addr(voodoo, dst_x * 3, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *) &src_p[src_x * 3]; - uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; - 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]; + if (dst_addr > voodoo->fb_mask) + break; - if (dst_addr > voodoo->fb_mask) + *(uint32_t *) &voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (*(uint32_t *) &voodoo->vram[dst_addr] & 0xff000000); + voodoo->changedvram[dst_addr >> 12] = changeframecount; break; + } + case DST_FORMAT_COL_32_BPP: + { + uint32_t dst_addr = get_addr(voodoo, dst_x * 4, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *) &src_p[src_x * 4]; + uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; + 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]; - *(uint32_t *) &voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (*(uint32_t *) &voodoo->vram[dst_addr] & 0xff000000); -#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; - } - case DST_FORMAT_COL_32_BPP: - { - uint32_t dst_addr = get_addr(voodoo, dst_x * 4, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *) &src_p[src_x * 4]; - uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; - 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]; + if (dst_addr > voodoo->fb_mask) + break; - if (dst_addr > voodoo->fb_mask) + *(uint32_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); + voodoo->changedvram[dst_addr >> 12] = changeframecount; break; + } - *(uint32_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); -#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; + default: break; - } - - default: - break; + } } - } - error_x -= voodoo->banshee_blt.srcSizeX; - while (error_x < 0) { - error_x += voodoo->banshee_blt.dstSizeX; - src_x++; + error_x -= voodoo->banshee_blt.srcSizeX; + while (error_x < 0) { + error_x += voodoo->banshee_blt.dstSizeX; + src_x++; + } + dst_x++; + pat_x++; + } + } + } else { + /* Color conversion required. */ + if (dst_y >= clip->y_min && dst_y < clip->y_max) { + 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]; + int error_x = voodoo->banshee_blt.dstSizeX / 2; + + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; + int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3; + + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { + uint32_t src_data = 0; + uint32_t src_data_yuv = 0; /* Used in YUYV-to-RGB convesions. */ + int transparent = 0; + + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { + case SRC_FORMAT_COL_1_BPP: + { + uint8_t src_byte = src_p[src_x_real]; + src_data = (src_byte & (0x80 >> (src_x & 7))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack; + if (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) + transparent = !(src_byte & (0x80 >> (src_x & 7))); +#if 0 + bansheeblt_log(" 1bpp src_byte=%02x src_x=%i src_data=%x transparent=%i\n", src_byte, src_x, src_data, transparent); +#endif + break; + } + case SRC_FORMAT_COL_8_BPP: + { + src_data = src_p[src_x_real]; + break; + } + case SRC_FORMAT_COL_16_BPP: + { + uint16_t src_16 = *(uint16_t *) &src_p[src_x_real]; + int r = (src_16 >> 11); + int g = (src_16 >> 5) & 0x3f; + int b = src_16 & 0x1f; + + r = (r << 3) | (r >> 2); + g = (g << 2) | (g >> 4); + b = (b << 3) | (b >> 2); + src_data = (r << 16) | (g << 8) | b; + break; + } + case SRC_FORMAT_COL_24_BPP: + { + src_data = *(uint32_t *) &src_p[src_x_real]; + break; + } + case SRC_FORMAT_COL_32_BPP: + { + src_data = *(uint32_t *) &src_p[src_x_real]; + break; + } + case SRC_FORMAT_COL_YUYV: + { + src_data_yuv = *(uint32_t *) &src_p[src_x_real]; + break; + } + case SRC_FORMAT_COL_UYVY: + { + src_data_yuv = *(uint32_t *) &src_p[src_x_real]; + src_data_yuv = ((src_data_yuv & 0xFF00) >> 8) | ((src_data_yuv & 0xFF) << 8) | + ((src_data_yuv & 0xFF000000) >> 8) | ((src_data_yuv & 0xFF0000) << 8); + break; + } + + default: + fatal("banshee_do_screen_to_screen_stretch_blt: unknown srcFormat %08x\n", voodoo->banshee_blt.srcFormat); + } + + if ((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_16_BPP && (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) != SRC_FORMAT_COL_1_BPP) { + int r = src_data >> 16; + int g = (src_data >> 8) & 0xff; + int b = src_data & 0xff; + + src_data = (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11); + } + + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_YUYV + || (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_UYVY) { + if (((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_24_BPP) || + ((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_32_BPP)) { + uint32_t rgbcol[2] = { 0, 0 }; + DECODE_YUYV422(rgbcol, (uint8_t *) &src_data_yuv); + + bansheeblt_log("YUV -> 24 bpp or 32 bpp\n"); + + if (!transparent) { + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, 0xFF, rgbcol[0], src_colorkey); + } + dst_x++; + + if (!transparent) { + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, 0xFF, rgbcol[1], src_colorkey); + } + } else if ((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_16_BPP) { + uint32_t rgbcol = 0; + DECODE_YUYV422_16BPP((uint16_t *) &rgbcol, (uint8_t *) &src_data_yuv); + + bansheeblt_log("YUV -> 16 bpp\n"); + + if (!transparent) { + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, 0xFF, rgbcol & 0xffff, src_colorkey); + } + dst_x++; + + if (!transparent) { + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, 0xFF, rgbcol >> 16, src_colorkey); + } + } else + fatal("banshee_do_screen_to_screen_stretch_blt: unknown dstFormat %08x\n", voodoo->banshee_blt.dstFormat); + } else { + if (!transparent) + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, 0xFF, src_data, src_colorkey); + } + } + + error_x -= voodoo->banshee_blt.srcSizeX; + while (error_x < 0) { + error_x += voodoo->banshee_blt.dstSizeX; + src_x++; + } + dst_x++; + pat_x++; } - dst_x++; - pat_x++; } } diff --git a/src/video/vid_voodoo_reg.c b/src/video/vid_voodoo_reg.c index ce3ee6064..82dfde354 100644 --- a/src/video/vid_voodoo_reg.c +++ b/src/video/vid_voodoo_reg.c @@ -965,10 +965,12 @@ voodoo_reg_writel(uint32_t addr, uint32_t val, void *priv) if (chip & CHIP_TREX0) { voodoo->params.textureMode[0] = val; voodoo->params.tformat[0] = (val >> 8) & 0xf; + voodoo_recalc_tex(voodoo, 0); } if (chip & CHIP_TREX1) { voodoo->params.textureMode[1] = val; voodoo->params.tformat[1] = (val >> 8) & 0xf; + voodoo_recalc_tex(voodoo, 1); } break; case SST_tLOD: diff --git a/src/video/vid_wy700.c b/src/video/vid_wy700.c index a52bad4ee..c00541113 100644 --- a/src/video/vid_wy700.c +++ b/src/video/vid_wy700.c @@ -212,9 +212,9 @@ typedef struct wy700_t { } wy700_t; /* Mapping of attributes to colours, in CGA emulation... */ -static int cgacols[256][2][2]; +static int cga_attr_to_color_table[256][2][2]; /* ... and MDA emulation. */ -static int mdacols[256][2][2]; +static int mda_attr_to_color_table[256][2][2]; void wy700_recalctimings(wy700_t *wy700); void wy700_write(uint32_t addr, uint8_t val, void *priv); @@ -535,9 +535,9 @@ wy700_textline(wy700_t *wy700) 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; + uint8_t scanline; + uint16_t memaddr = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; + uint16_t cursoraddr = (wy700->cga_crtc[15] | (wy700->cga_crtc[14] << 8)) & 0x3fff; /* The fake CRTC character height register selects whether MDA or CGA * attributes are used */ @@ -548,41 +548,41 @@ wy700_textline(wy700_t *wy700) if (wy700->font) { fontbase += 256 * 32; } - addr = ((ma & ~1) + (wy700->displine >> 5) * w) * 2; - sc = (wy700->displine >> 1) & 15; + addr = ((memaddr & ~1) + (wy700->displine >> 5) * w) * 2; + scanline = (wy700->displine >> 1) & 15; - ma += ((wy700->displine >> 5) * w); + memaddr += ((wy700->displine >> 5) * w); if ((wy700->real_crtc[10] & 0x60) == 0x20) { cursorline = 0; } else { - cursorline = ((wy700->real_crtc[10] & 0x1F) <= sc) && ((wy700->real_crtc[11] & 0x1F) >= sc); + cursorline = ((wy700->real_crtc[10] & 0x1F) <= scanline) && ((wy700->real_crtc[11] & 0x1F) >= scanline); } for (int x = 0; x < w; x++) { chr = wy700->vram[(addr + 2 * x) & 0x3FFF]; attr = wy700->vram[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && wy700->enabled && (wy700->cga_ctrl & 8) && (wy700->blink & 16)); + drawcursor = ((memaddr == cursoraddr) && cursorline && wy700->enabled && (wy700->cga_ctrl & 8) && (wy700->blink & 16)); blink = ((wy700->blink & 16) && (wy700->cga_ctrl & 0x20) && (attr & 0x80) && !drawcursor); if (wy700->cga_ctrl & 0x20) attr &= 0x7F; /* MDA underline */ - if (sc == 14 && mda && ((attr & 7) == 1)) { + if (scanline == 14 && mda && ((attr & 7) == 1)) { for (c = 0; c < cw; c++) - buffer32->line[wy700->displine][(x * cw) + c] = mdacols[attr][blink][1]; + buffer32->line[wy700->displine][(x * cw) + c] = mda_attr_to_color_table[attr][blink][1]; } else /* Draw 16 pixels of character */ { - bitmap[0] = fontbase[chr * 32 + 2 * sc]; - bitmap[1] = fontbase[chr * 32 + 2 * sc + 1]; + bitmap[0] = fontbase[chr * 32 + 2 * scanline]; + bitmap[1] = fontbase[chr * 32 + 2 * scanline + 1]; for (c = 0; c < 16; c++) { int col; if (c < 8) - col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; + col = (mda ? mda_attr_to_color_table : cga_attr_to_color_table)[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; else - col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[1] & (1 << ((c & 7) ^ 7))) ? 1 : 0]; + col = (mda ? mda_attr_to_color_table : cga_attr_to_color_table)[attr][blink][(bitmap[1] & (1 << ((c & 7) ^ 7))) ? 1 : 0]; if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) - col = mdacols[0][0][0]; + col = mda_attr_to_color_table[0][0][0]; if (w == 40) { buffer32->line[wy700->displine][(x * cw) + 2 * c] = col; buffer32->line[wy700->displine][(x * cw) + 2 * c + 1] = col; @@ -592,9 +592,9 @@ wy700_textline(wy700_t *wy700) if (drawcursor) { for (c = 0; c < cw; c++) - buffer32->line[wy700->displine][(x * cw) + c] ^= (mda ? mdacols : cgacols)[attr][0][1]; + buffer32->line[wy700->displine][(x * cw) + c] ^= (mda ? mda_attr_to_color_table : cga_attr_to_color_table)[attr][0][1]; } - ++ma; + ++memaddr; } } } @@ -608,8 +608,8 @@ wy700_cgaline(wy700_t *wy700) uint8_t ink = 0; uint16_t addr; - uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; - addr = ((wy700->displine >> 2) & 1) * 0x2000 + (wy700->displine >> 3) * 80 + ((ma & ~1) << 1); + uint16_t memaddr = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; + addr = ((wy700->displine >> 2) & 1) * 0x2000 + (wy700->displine >> 3) * 80 + ((memaddr & ~1) << 1); /* The fixed mode setting here programs the real CRTC with a screen * width to 20, so draw in 20 fixed chunks of 4 bytes each */ @@ -902,74 +902,74 @@ wy700_init(UNUSED(const device_t *info)) /* Set up the emulated attributes. * CGA is done in four groups: 00-0F, 10-7F, 80-8F, 90-FF */ for (c = 0; c < 0x10; c++) { - cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = 16; + cga_attr_to_color_table[c][0][0] = cga_attr_to_color_table[c][1][0] = cga_attr_to_color_table[c][1][1] = 16; if (c & 8) - cgacols[c][0][1] = 15 + 16; + cga_attr_to_color_table[c][0][1] = 15 + 16; else - cgacols[c][0][1] = 7 + 16; + cga_attr_to_color_table[c][0][1] = 7 + 16; } for (c = 0x10; c < 0x80; c++) { - cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = 16 + 7; + cga_attr_to_color_table[c][0][0] = cga_attr_to_color_table[c][1][0] = cga_attr_to_color_table[c][1][1] = 16 + 7; if (c & 8) - cgacols[c][0][1] = 15 + 16; + cga_attr_to_color_table[c][0][1] = 15 + 16; else - cgacols[c][0][1] = 0 + 16; + cga_attr_to_color_table[c][0][1] = 0 + 16; if ((c & 0x0F) == 8) - cgacols[c][0][1] = 8 + 16; + cga_attr_to_color_table[c][0][1] = 8 + 16; } /* With special cases for 00, 11, 22, ... 77 */ - cgacols[0x00][0][1] = cgacols[0x00][1][1] = 16; + cga_attr_to_color_table[0x00][0][1] = cga_attr_to_color_table[0x00][1][1] = 16; for (c = 0x11; c <= 0x77; c += 0x11) { - cgacols[c][0][1] = cgacols[c][1][1] = 16 + 7; + cga_attr_to_color_table[c][0][1] = cga_attr_to_color_table[c][1][1] = 16 + 7; } for (c = 0x80; c < 0x90; c++) { - cgacols[c][0][0] = 16 + 8; + cga_attr_to_color_table[c][0][0] = 16 + 8; if (c & 8) - cgacols[c][0][1] = 15 + 16; + cga_attr_to_color_table[c][0][1] = 15 + 16; else - cgacols[c][0][1] = 7 + 16; - cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c - 0x80][0][0]; + cga_attr_to_color_table[c][0][1] = 7 + 16; + cga_attr_to_color_table[c][1][0] = cga_attr_to_color_table[c][1][1] = cga_attr_to_color_table[c - 0x80][0][0]; } for (c = 0x90; c < 0x100; c++) { - cgacols[c][0][0] = 16 + 15; + cga_attr_to_color_table[c][0][0] = 16 + 15; if (c & 8) - cgacols[c][0][1] = 8 + 16; + cga_attr_to_color_table[c][0][1] = 8 + 16; else - cgacols[c][0][1] = 7 + 16; + cga_attr_to_color_table[c][0][1] = 7 + 16; if ((c & 0x0F) == 0) - cgacols[c][0][1] = 16; - cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c - 0x80][0][0]; + cga_attr_to_color_table[c][0][1] = 16; + cga_attr_to_color_table[c][1][0] = cga_attr_to_color_table[c][1][1] = cga_attr_to_color_table[c - 0x80][0][0]; } /* Also special cases for 99, AA, ..., FF */ for (c = 0x99; c <= 0xFF; c += 0x11) { - cgacols[c][0][1] = 16 + 15; + cga_attr_to_color_table[c][0][1] = 16 + 15; } /* Special cases for 08, 80 and 88 */ - cgacols[0x08][0][1] = 16 + 8; - cgacols[0x80][0][1] = 16; - cgacols[0x88][0][1] = 16 + 8; + cga_attr_to_color_table[0x08][0][1] = 16 + 8; + cga_attr_to_color_table[0x80][0][1] = 16; + cga_attr_to_color_table[0x88][0][1] = 16 + 8; /* MDA attributes */ for (c = 0; c < 256; c++) { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; + mda_attr_to_color_table[c][0][0] = mda_attr_to_color_table[c][1][0] = mda_attr_to_color_table[c][1][1] = 16; if (c & 8) - mdacols[c][0][1] = 15 + 16; + mda_attr_to_color_table[c][0][1] = 15 + 16; else - mdacols[c][0][1] = 7 + 16; + mda_attr_to_color_table[c][0][1] = 7 + 16; } - mdacols[0x70][0][1] = 16; - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15; - mdacols[0xF0][0][1] = 16; - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15; - mdacols[0x78][0][1] = 16 + 7; - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15; - mdacols[0xF8][0][1] = 16 + 7; - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; + mda_attr_to_color_table[0x70][0][1] = 16; + mda_attr_to_color_table[0x70][0][0] = mda_attr_to_color_table[0x70][1][0] = mda_attr_to_color_table[0x70][1][1] = 16 + 15; + mda_attr_to_color_table[0xF0][0][1] = 16; + mda_attr_to_color_table[0xF0][0][0] = mda_attr_to_color_table[0xF0][1][0] = mda_attr_to_color_table[0xF0][1][1] = 16 + 15; + mda_attr_to_color_table[0x78][0][1] = 16 + 7; + mda_attr_to_color_table[0x78][0][0] = mda_attr_to_color_table[0x78][1][0] = mda_attr_to_color_table[0x78][1][1] = 16 + 15; + mda_attr_to_color_table[0xF8][0][1] = 16 + 7; + mda_attr_to_color_table[0xF8][0][0] = mda_attr_to_color_table[0xF8][1][0] = mda_attr_to_color_table[0xF8][1][1] = 16 + 15; + mda_attr_to_color_table[0x00][0][1] = mda_attr_to_color_table[0x00][1][1] = 16; + mda_attr_to_color_table[0x08][0][1] = mda_attr_to_color_table[0x08][1][1] = 16; + mda_attr_to_color_table[0x80][0][1] = mda_attr_to_color_table[0x80][1][1] = 16; + mda_attr_to_color_table[0x88][0][1] = mda_attr_to_color_table[0x88][1][1] = 16; /* Start off in 80x25 text mode */ wy700->cga_stat = 0xF4; diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 4c08b7b71..a91a893df 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -35,6 +35,7 @@ #include <86box/vid_svga_render.h> #include <86box/vid_xga_device.h> #include "cpu.h" +#include <86box/plat.h> #include <86box/plat_unused.h> #define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN" @@ -107,7 +108,7 @@ svga_xga_out(uint16_t addr, uint8_t val, void *priv) if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->memaddr_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -161,37 +162,77 @@ xga_updatemapping(svga_t *svga) switch (xga->op_mode & 7) { case 0: xga_log("XGA: VGA mode address decode disabled.\n"); + mem_mapping_disable(&xga->linear_mapping); + xga->test_stage = 0; + xga->mapping_base = svga->mapping.base; break; case 1: xga_log("XGA: VGA mode address decode enabled.\n"); - if (xga->base_addr_1mb) { - mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); - mem_mapping_enable(&xga->linear_mapping); - } else if (xga->linear_base) { - mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); - mem_mapping_enable(&xga->linear_mapping); - } else - mem_mapping_disable(&xga->linear_mapping); + mem_mapping_disable(&xga->linear_mapping); + xga->test_stage = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + switch (svga->gdcreg[6] & 0xc) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + + default: + break; + } + xga->mapping_base = svga->mapping.base; break; case 2: xga_log("XGA: 132-Column mode address decode disabled.\n"); + mem_mapping_disable(&xga->linear_mapping); + xga->test_stage = 0; + xga->mapping_base = svga->mapping.base; break; case 3: xga_log("XGA: 132-Column mode address decode enabled.\n"); - if (xga->base_addr_1mb) { - mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); - mem_mapping_enable(&xga->linear_mapping); - } else if (xga->linear_base) { - mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); - mem_mapping_enable(&xga->linear_mapping); - } else - mem_mapping_disable(&xga->linear_mapping); + mem_mapping_disable(&xga->linear_mapping); + xga->test_stage = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + switch (svga->gdcreg[6] & 0xc) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + + default: + break; + } + xga->mapping_base = svga->mapping.base; break; default: - xga_log("XGA: Extended Graphics mode, ap=%d.\n", xga->aperture_cntl); + xga_log("XGA: Extended Graphics mode, ap=%d, mapbits=%x.\n", xga->aperture_cntl, svga->gdcreg[6] & 0xc); switch (xga->aperture_cntl) { case 0: - xga_log("XGA: No 64KB aperture: 1MB=%x, 4MB=%x, SVGA Mapping Base=%x.\n", xga->base_addr_1mb, xga->linear_base, svga->mapping.base); + xga_log("XGA: No 64KB aperture: 1MB=%x, 4MB=%x, SVGA Mapping Base=%x, mapbits=%x.\n", xga->base_addr_1mb, xga->linear_base, svga->mapping.base, svga->gdcreg[6] & 0xc); if (xga->base_addr_1mb) { mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); mem_mapping_enable(&xga->linear_mapping); @@ -201,6 +242,7 @@ xga_updatemapping(svga_t *svga) } else mem_mapping_disable(&xga->linear_mapping); + xga->test_stage = 0; mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); switch (svga->gdcreg[6] & 0xc) { case 0x0: /*128k at A0000*/ @@ -223,15 +265,22 @@ xga_updatemapping(svga_t *svga) default: break; } + xga->mapping_base = svga->mapping.base; break; case 1: - xga_log("XGA: 64KB aperture at A0000.\n"); + mem_mapping_disable(&xga->linear_mapping); + xga_log("XGA: 64KB aperture at A0000, on=%d.\n", xga->on); + xga->test_stage = 0; + xga->mapping_base = 0xa0000; mem_mapping_set_handler(&svga->mapping, xga_read, xga_readw, xga_readl, xga_write, xga_writew, xga_writel); mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); xga->banked_mask = 0xffff; break; case 2: + mem_mapping_disable(&xga->linear_mapping); xga_log("XGA: 64KB aperture at B0000.\n"); + xga->test_stage = 0; + xga->mapping_base = 0xb0000; mem_mapping_set_handler(&svga->mapping, xga_read, xga_readw, xga_readl, xga_write, xga_writew, xga_writel); mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x10000); xga->banked_mask = 0xffff; @@ -267,6 +316,8 @@ void xga_recalctimings(svga_t *svga) { xga_t *xga = (xga_t *) svga->xga; + + xga_log("DispCntl2=%d, lowres=%x.\n", xga->disp_cntl_2 & 7, svga->lowres); if (xga->on) { xga->h_total = xga->htotal + 1; xga->v_total = xga->vtotal + 1; @@ -276,6 +327,7 @@ xga_recalctimings(svga_t *svga) xga->v_blankstart = xga->vblankstart + 1; xga->h_disp = (xga->hdisp + 1) << 3; + xga->h_disp_time = xga->h_disp >> 3; xga->rowoffset = xga->pix_map_width; @@ -290,8 +342,7 @@ xga_recalctimings(svga_t *svga) xga->v_blankstart >>= 1; } - xga->ma_latch = xga->disp_start_addr; - + xga->memaddr_latch = xga->disp_start_addr; xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x, dispcntl2=%02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80, xga->disp_cntl_2 & 0xc0); switch ((xga->clk_sel_1 >> 2) & 3) { @@ -314,6 +365,7 @@ xga_recalctimings(svga_t *svga) break; } + svga->render_xga = xga_render_blank; switch (xga->disp_cntl_2 & 7) { case 2: svga->render_xga = xga_render_4bpp; @@ -326,9 +378,10 @@ xga_recalctimings(svga_t *svga) break; default: - svga->render_xga = xga_render_blank; break; } + + xga_log("XGA: H_TOTAL=%d, rowoffset=%x, rowcount=%x, memaddr_latch=%06x, bpp type=%d.\n", xga->h_total, xga->rowoffset, xga->rowcount, xga->memaddr_latch, xga->disp_cntl_2 & 7); } } @@ -522,19 +575,40 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) xga->dac_pos++; break; case 1: - xga->dac_g = val; + if (xga->pal_seq & 0x04) + xga->pal_b = val; + else + xga->dac_g = val; + xga->dac_pos++; break; case 2: - xga->pal_b = val; - index = xga->dac_addr & 0xff; - xga->xgapal[index].r = xga->dac_r; - xga->xgapal[index].g = xga->dac_g; - xga->xgapal[index].b = xga->pal_b; - xga->pallook[index] = makecol32(xga->xgapal[index].r, xga->xgapal[index].g, xga->xgapal[index].b); - xga_log("XGA Pallook=%06x, idx=%d.\n", xga->pallook[index], index); - xga->dac_pos = 0; - xga->dac_addr = (xga->dac_addr + 1) & 0xff; + if (xga->pal_seq & 0x04) { + xga->dac_g = val; + xga->dac_pos++; + } else { + xga->pal_b = val; + index = xga->dac_addr & 0xff; + xga->xgapal[index].r = xga->dac_r; + xga->xgapal[index].g = xga->dac_g; + xga->xgapal[index].b = xga->pal_b; + xga->pallook[index] = makecol32(xga->xgapal[index].r, xga->xgapal[index].g, xga->xgapal[index].b); + xga_log("XGA Pallook=%06x, idx=%d.\n", xga->pallook[index], index); + xga->dac_pos = 0; + xga->dac_addr = (xga->dac_addr + 1) & 0xff; + } + break; + case 3: + if (xga->pal_seq & 0x04) { + index = xga->dac_addr & 0xff; + xga->xgapal[index].r = xga->dac_r; + xga->xgapal[index].b = xga->pal_b; + xga->xgapal[index].g = xga->dac_g; + xga->pallook[index] = makecol32(xga->xgapal[index].r, xga->xgapal[index].g, xga->xgapal[index].b); + xga_log("XGA Pallook=%06x, idx=%d.\n", xga->pallook[index], index); + xga->dac_pos = 0; + xga->dac_addr = (xga->dac_addr + 1) & 0xff; + } break; default: @@ -580,13 +654,27 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) xga->aperture_cntl = val & 3; xga_updatemapping(svga); break; + case 4: + xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); + xga->int_ena = val; + break; + case 5: + xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); + xga->int_stat = val; + break; + case 6: + xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); + break; + case 7: + xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); + break; case 8: xga->ap_idx = val; xga_log("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, val, val & 0x3f); - if ((xga->op_mode & 7) < 4) { + if ((xga->op_mode & 7) < 4) xga->write_bank = xga->read_bank = 0; - } else { + else { if (xga->base_addr_1mb) { if (xga->aperture_cntl) { xga->write_bank = (xga->ap_idx & 0x3f) << 16; @@ -638,6 +726,12 @@ xga_ext_inb(uint16_t addr, void *priv) case 1: ret = xga->aperture_cntl; break; + case 4: + ret = xga->int_ena; + break; + case 5: + ret = xga->int_stat; + break; case 8: ret = xga->ap_idx; break; @@ -801,12 +895,26 @@ xga_ext_inb(uint16_t addr, void *priv) break; case 1: xga->dac_pos++; - ret = xga->xgapal[index].g; + if (xga->pal_seq & 0x04) + ret = xga->xgapal[index].b; + else + ret = xga->xgapal[index].g; break; case 2: - xga->dac_pos = 0; - xga->dac_addr = (xga->dac_addr + 1) & 0xff; - ret = xga->xgapal[index].b; + if (xga->pal_seq & 0x04) { + xga->dac_pos++; + ret = xga->xgapal[index].g; + } else { + xga->dac_pos = 0; + xga->dac_addr = (xga->dac_addr + 1) & 0xff; + ret = xga->xgapal[index].b; + } + break; + case 3: + if (xga->pal_seq & 0x04) { + xga->dac_pos = 0; + xga->dac_addr = (xga->dac_addr + 1) & 0xff; + } break; default: @@ -856,20 +964,6 @@ xga_ext_inb(uint16_t addr, void *priv) return ret; } -#define READ(addr, dat) \ - dat = xga->vram[(addr) & (xga->vram_mask)]; - -#define WRITE(addr, dat) \ - xga->vram[((addr)) & (xga->vram_mask)] = dat; \ - xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; - -#define READW(addr, dat) \ - dat = *(uint16_t *) &xga->vram[(addr) & (xga->vram_mask)]; - -#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 ROP(mix, d, s) \ { \ switch ((mix) ? (xga->accel.frgd_mix & 0x1f) : (xga->accel.bkgd_mix & 0x1f)) { \ @@ -943,218 +1037,255 @@ xga_ext_inb(uint16_t addr, void *priv) } static uint32_t -xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, uint32_t base, int width) +xga_transform_addr(uint32_t addr, uint8_t mode) { - const xga_t *xga = (xga_t *) svga->xga; - uint32_t addr = base; - int bits; - uint8_t byte; - uint8_t px; - int skip = 0; + uint32_t ret = addr; - if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) - skip = 1; + if ((mode & 0x0f) == 0x0c) + ret ^= 1; - addr += (y * (width >> 3)); - addr += (x >> 3); - if (!skip) { - READ(addr, byte); - } else - byte = mem_readb_phys(addr); + return ret; +} - bits = 7 - (x & 7); +static uint16_t +xga_transform_val(uint16_t val, uint8_t mode, int bits) +{ + uint16_t ret = 0x0000; - xga_log("0. AccessMode=%02x, SRCMAP=%02x, DSTMAP=%02x, PAT=%02x.\n", xga->access_mode & 0x0f, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), (xga->accel.px_map_format[xga->accel.pat_src] & 0x08)); - if (!(xga->accel.px_map_format[xga->accel.src_map] & 0x08) && !(xga->accel.px_map_format[xga->accel.dst_map] & 0x08)) { - if (((xga->accel.px_map_format[xga->accel.src_map] & 0x07) >= 0x02) && ((xga->accel.px_map_format[xga->accel.dst_map] & 0x07) >= 0x02) && (xga->accel.pat_src <= 2)) - bits ^= 7; + switch (mode & 0x0f) { + default: + ret = val; + break; + case 0x08: /* 1 bpp */ + for (int i = 0; i < bits; i++) + ret |= ((val >> i) & 0x01) << (i ^ 7); + break; + case 0x09: /* 2 bpp */ + for (int i = 0; i < bits; i += 2) + ret |= ((val >> i) & 0x03) << (i ^ 6); + break; + case 0x0a: /* 4 bpp */ + for (int i = 0; i < bits; i += 4) + ret |= ((val >> i) & 0x0f) << (i ^ 4); + break; + case 0x0c: /* 16 bpp */ + if (bits == 16) for (int i = 0; i < (bits >> 3); i++) + ret |= ((val >> (i << 3)) & 0xff) << ((i << 3) ^ 8); + else + ret = val; + break; } - px = (byte >> bits) & 1; - return px; + return ret & ((1 << bits) - 1); } -static uint32_t -xga_accel_read_area_map_pixel(svga_t *svga, int x, int y, uint32_t base, int width) +static uint8_t +xga_map_readb(svga_t *svga, uint32_t addr, int map) { - const xga_t *xga = (xga_t *) svga->xga; - uint32_t addr = base; - int bits; - uint8_t byte; - uint8_t px; - int skip = 0; + xga_t *xga = (xga_t *) svga->xga; + uint8_t ret; - if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) - skip = 1; + if ((addr >= xga->linear_base) && (addr <= (xga->linear_base + 0xfffff))) + ret = xga->vram[addr & xga->vram_mask]; + else + ret = xga_transform_val(mem_readb_phys(xga_transform_addr(addr, xga->accel.px_map_format[map])), + xga->accel.px_map_format[map], 8); + return ret; +} - addr += (y * (width >> 3)); - addr += (x >> 3); - if (!skip) { - READ(addr, byte); +static uint16_t +xga_map_readw(svga_t *svga, uint32_t addr, int map) +{ + xga_t *xga = (xga_t *) svga->xga; + uint16_t ret; + + if ((addr >= xga->linear_base) && (addr <= (xga->linear_base + 0xfffff))) + ret = *(uint16_t *) &xga->vram[addr & xga->vram_mask]; + else + ret = xga_transform_val(mem_readw_phys(addr), xga->accel.px_map_format[map], 16); + + return ret; +} + +static void +xga_map_writeb(svga_t *svga, uint32_t addr, int map, uint8_t val) +{ + xga_t *xga = (xga_t *) svga->xga; + + if ((addr >= xga->linear_base) && (addr <= (xga->linear_base + 0xfffff))) { + xga->vram[addr & xga->vram_mask] = val; + xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; } else - byte = mem_readb_phys(addr); + mem_writeb_phys(xga_transform_addr(addr, xga->accel.px_map_format[map]), + xga_transform_val(val, xga->accel.px_map_format[map], 8)); +} - bits = 7 - (x & 7); +static void +xga_map_writew(svga_t *svga, uint32_t addr, int map, uint16_t val) +{ + xga_t *xga = (xga_t *) svga->xga; - px = (byte >> bits) & 1; - return px; + if ((addr >= xga->linear_base) && (addr <= (xga->linear_base + 0xfffff))) { + *(uint16_t *) &xga->vram[addr & xga->vram_mask] = val; + xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; + } else + mem_writew_phys(addr, xga_transform_val(val, xga->accel.px_map_format[map], 16)); +} + +static int +xga_calc_pos(int x, int y, int width) +{ + int ret = (y * (width + 1)) + (x % (width + 1)); + + return ret; } static uint32_t -xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width) +xga_add_to_addr(xga_t *xga, uint32_t addr, int pos, int map) { - xga_t *xga = (xga_t *) svga->xga; - uint32_t addr = base; - int bits; - uint32_t byte; - uint8_t px; - int skip = 0; + int pos_div[8] = { 8, 4, 2, 1, 1, 1, 1, 1 }; + int pos_mul[8] = { 1, 1, 1, 1, 2, 1, 1, 1 }; + int div_val = pos_div[xga->accel.px_map_format[map] & 0x07]; + int mul_val = pos_mul[xga->accel.px_map_format[map] & 0x07]; + uint32_t ret = addr + ((pos / div_val) * mul_val); - if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) - skip = 1; + return ret; +} + +#define READ_MAP(base, pos, map) xga_map_readb(svga, xga_add_to_addr(xga, base, pos, map), map) +#define READ_MAPW(base, pos, map) xga_map_readw(svga, xga_add_to_addr(xga, base, pos, map), map) +#define WRITE_MAP(base, pos, map, val) xga_map_writeb(svga, xga_add_to_addr(xga, base, pos, map), map, val) +#define WRITE_MAPW(base, pos, map, val) xga_map_writew(svga, xga_add_to_addr(xga, base, pos, map), map, val) + +#define DO_READ_MAP(map) READ_MAP(base, pos, map) + +#define PIXEL_MASK(bits) (0x07 / bits) +#define ALL_SET(bits) ((1 << bits) - 1) + +#define MASK(map, bits) ((pos & PIXEL_MASK(bits)) * bits) +#define MASKED_READ(map, bits) (DO_READ_MAP(map) >> MASK(map, bits)) & ALL_SET(bits) + +static uint32_t +xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y) +{ + xga_t *xga = (xga_t *) svga->xga; + int map = 0; + uint32_t ret = 0x000000ff; + + switch ((xga->accel.command >> 12) & 0x0f) { + default: + case 8: + map = 0; + break; + case 1 ... 3: + map = (xga->accel.command >> 12) & 0x0f; + break; + case 9: + map = (xga->accel.command >> 20) & 0x0f; + if (map > 0x03) + map = 0; + break; + } + + if (map != 0) { + int width = xga->accel.px_map_width[map]; + int pos = xga_calc_pos(x, y, width); + uint32_t base = xga->accel.px_map_base[map]; + + ret = MASKED_READ(map, 1); + } + + return ret; +} + +static uint32_t +xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map) +{ + xga_t *xga = (xga_t *) svga->xga; + int width = xga->accel.px_map_width[map]; + int pos = xga_calc_pos(x, y, width); + uint32_t base = xga->accel.px_map_base[map]; + uint32_t ret = 0x00000000; switch (xga->accel.px_map_format[map] & 0x07) { - case 0: /*1-bit*/ - addr += (y * (width >> 3)); - addr += (x >> 3); - if (!skip) { - READ(addr, byte); - } else - byte = mem_readb_phys(addr); + case 0: /* 1 bpp */ + ret = MASKED_READ(map, 1); + break; - xga_log("1. AccessMode=%02x, SRCMAP=%02x, DSTMAP=%02x, PAT=%02x.\n", xga->access_mode & 0x0f, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->accel.pat_src); - if ((xga->accel.px_map_format[xga->accel.src_map] & 0x08) && !(xga->access_mode & 0x08)) - bits = (x & 7); - else - bits = 7 - (x & 7); + case 1: /* 2 bpp */ + ret = MASKED_READ(map, 2); + break; - 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); + case 2: /* 4 bpp */ + ret = MASKED_READ(map, 4); + break; - xga_log("4bpp read: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, wordpix=%04x, x=%d, y=%d, skip=%d.\n", xga->op_mode & 0x08, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->access_mode & 0x0f, xga->accel.src_map, xga->accel.dst_map, byte, x, y, skip); - return byte; - case 3: /*8-bit*/ - addr += (y * width); - addr += x; - if (!skip) { - READ(addr, byte); - } else - byte = mem_readb_phys(addr); + case 3: /* 8 bpp */ + ret = READ_MAP(base, pos, map); + break; - return byte; - case 4: /*16-bit*/ - addr += (y * (width << 1)); - addr += (x << 1); - - if (!skip) { - READW(addr, byte); - } else { - byte = mem_readw_phys(addr); - if ((xga->access_mode & 0x07) == 0x04) - byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8); - else if (xga->access_mode & 0x08) - byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8); - } - return byte; + case 4: /* 16 bpp */ + ret = READ_MAPW(base, pos, map); + break; default: break; } - return 0; + + return ret; } 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_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t pixel) { xga_t *xga = (xga_t *) svga->xga; - uint32_t addr = base; uint8_t byte; uint8_t mask; - int skip = 0; - - if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) - skip = 1; + int bit; + int width = xga->accel.px_map_width[map]; + int pos = xga_calc_pos(x, y, width); + uint32_t base = xga->accel.px_map_base[map]; switch (xga->accel.px_map_format[map] & 0x07) { - case 0: /*1-bit*/ - addr += (y * (width >> 3)); - addr += (x >> 3); - if (!skip) { - READ(addr, byte); - } else - byte = mem_readb_phys(addr); + case 0: /* 1 bpp */ + byte = READ_MAP(base, pos, map); + bit = pos & 7; - if (xga->access_mode & 0x08) - mask = 1 << (7 - (x & 7)); - else { - if ((xga->accel.px_map_format[map] & 0x08) || (xga->accel.px_map_format[xga->accel.src_map] & 0x08)) { - xga_log("2. AccessMode=%02x, SRCMAP=%02x, DSTMAP=%02x, PAT=%02x.\n", xga->access_mode & 0x0f, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[map] & 0x0f), xga->accel.pat_src); - mask = 1 << (x & 7); - } else - mask = 1 << (7 - (x & 7)); - } - - byte = (byte & ~mask) | ((pixel ? 0xff : 0) & mask); - if (pixel & 1) { - if (!skip) { - xga->vram[addr & (xga->vram_mask)] |= mask; - xga->changedvram[(addr & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; - } - } else { - if (!skip) { - xga->vram[addr & (xga->vram_mask)] &= ~mask; - xga->changedvram[(addr & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; - } - } - 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->accel.px_map_format[map] & 0x08) - mask = 0x0f << ((x & 1) << 2); - else - mask = 0x0f << ((1 - (x & 1)) << 2); + pixel <<= bit; + mask = 1 << bit; byte = (byte & ~mask) | (pixel & mask); - if (!skip) { - WRITE(addr, byte); - } - mem_writeb_phys(addr, byte); + WRITE_MAP(base, pos, map, byte); break; - case 3: /*8-bit*/ - addr += (y * width); - addr += x; - if (!skip) { - WRITE(addr, pixel & 0xff); - } - mem_writeb_phys(addr, pixel & 0xff); - break; - case 4: /*16-bit*/ - addr += (y * width << 1); - addr += (x << 1); - if (!skip) { - WRITEW(addr, pixel); - } else { - if ((xga->access_mode & 0x07) == 0x04) - pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8); - else if (xga->access_mode & 0x08) - pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8); - } - mem_writew_phys(addr, pixel); + case 1: /* 2 bpp */ + byte = READ_MAP(base, pos, map); + mask = ((pos & 3) << 1); + + pixel <<= mask; + mask = 0x03 << mask; + + byte = (byte & ~mask) | (pixel & mask); + WRITE_MAP(base, pos, map, byte); + break; + + case 2: /* 4 bpp */ + byte = READ_MAP(base, pos, map); + mask = ((pos & 1) << 2); + + pixel <<= mask; + mask = 0x0f << mask; + + byte = (byte & ~mask) | (pixel & mask); + WRITE_MAP(base, pos, map, byte); + break; + + case 3: /* 8bpp */ + WRITE_MAP(base, pos, map, pixel); + break; + + case 4: /* 16bpp */ + WRITE_MAPW(base, pos, map, pixel); break; default: @@ -1171,8 +1302,6 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) uint32_t old_dest_dat; uint32_t color_cmp = xga->accel.color_cmp; uint32_t plane_mask = xga->accel.plane_mask; - uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map]; - uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; int y = ssv & 0x0f; int x = 0; int16_t dx; @@ -1230,8 +1359,11 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) 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) : + xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map); 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; @@ -1239,19 +1371,22 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } else if (((xga->accel.command & 0x30) == 0x10) && x) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } else if (((xga->accel.command & 0x30) == 0x20) && y) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } } } } 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) : + xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map); 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; @@ -1259,13 +1394,13 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } else if (((xga->accel.command & 0x30) == 0x10) && x) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } else if (((xga->accel.command & 0x30) == 0x20) && y) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } } } @@ -1294,8 +1429,6 @@ xga_line_draw_write(svga_t *svga) uint32_t old_dest_dat = 0x00000000; uint32_t color_cmp = xga->accel.color_cmp; uint32_t plane_mask = xga->accel.plane_mask; - uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map]; - uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; int y = xga->accel.blt_width; int x = 0; int draw_pixel = 0; @@ -1316,7 +1449,7 @@ xga_line_draw_write(svga_t *svga) dy |= ~0x17ff; if ((xga->accel.command & 0x30) == 0x30) - xga_log("Line Draw Write Fill: DX=%d, DY=%d, BLTWIDTH=%d, BLTHEIGHT=%d, FRGDCOLOR=%04x, negative XDIR=%i, negative YDIR=%i, YMAJOR=%d, ERR=%d, BRESK2=%d, BRESK1=%d, mask=%02x.\n", dx, dy, xga->accel.blt_width, xga->accel.blt_height, xga->accel.frgd_color & 0xffff, (xga->accel.octant & 0x04), (xga->accel.octant & 0x02), (xga->accel.octant & 0x01), xga->accel.bres_err_term, xga->accel.bres_k2, xga->accel.bres_k1, xga->accel.command & 0xc0); + xga_log("Line Draw Write Fill: DX=%d, DY=%d, BLTWIDTH=%d, BLTHEIGHT=%d, FRGDCOLOR=%04x, negative XDIR=%i, negative YDIR=%i, YMAJOR=%d, ERR=%d, BRESK2=%d, BRESK1=%d, mask=%02x, frgdmix=%02x, bkgdmix=%02x.\n", dx, dy, xga->accel.blt_width, xga->accel.blt_height, xga->accel.frgd_color & 0xffff, (xga->accel.octant & 0x04), (xga->accel.octant & 0x02), (xga->accel.octant & 0x01), xga->accel.bres_err_term, xga->accel.bres_k2, xga->accel.bres_k1, xga->accel.command & 0xc0, xga->accel.frgd_mix & 0x1f, xga->accel.bkgd_mix & 0x1f); if (xga->accel.pat_src == 8) { if ((xga->accel.command & 0x30) == 0x30) { @@ -1358,32 +1491,39 @@ xga_line_draw_write(svga_t *svga) xga_log("Draw Boundary: DX=%d, DY=%d, wrt_pix=%d, ymajor=%d, bottomtotop=%x, len=%d, err=%d, frgdmix=%02x.\n", dx, dy, draw_pixel, xga->accel.octant & 0x01, xga->accel.octant & 0x02, y, xga->accel.bres_err_term, xga->accel.frgd_mix & 0x1f); 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)) && draw_pixel) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : 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, cx, cy, xga->accel.src_map) : + xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map); 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, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } } } else { if (draw_pixel) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : 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, cx, cy, xga->accel.src_map) : + xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map); 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, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } } } - if (x == xga->accel.blt_width) + if (x == xga->accel.blt_width) { + xga->accel.dst_map_x = dx; + xga->accel.dst_map_y = dy; break; + } if (xga->accel.octant & 0x01) { if (xga->accel.octant & 0x02) @@ -1421,35 +1561,41 @@ xga_line_draw_write(svga_t *svga) 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) : + xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } } } 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) : + xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } } @@ -1504,13 +1650,10 @@ xga_bitblt(svga_t *svga) uint32_t old_dest_dat; uint32_t color_cmp = xga->accel.color_cmp; uint32_t plane_mask = xga->accel.plane_mask; - uint32_t patbase; - uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map]; - uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; - uint32_t patwidth = xga->accel.px_map_width[xga->accel.pat_src]; + uint32_t patwidth; uint32_t dstwidth = xga->accel.px_map_width[xga->accel.dst_map]; 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 patheight; uint32_t srcheight = xga->accel.px_map_height[xga->accel.src_map]; uint32_t dstheight = xga->accel.px_map_height[xga->accel.dst_map]; uint32_t frgdcol = xga->accel.frgd_color; @@ -1539,17 +1682,18 @@ xga_bitblt(svga_t *svga) xga->accel.pattern = 0; xga->accel.filling = 0; + xga->accel.y_len = 0; xga_log("XGA bitblt access_mode=%x, octanty=%d, src command=%08x, " "pxsrcmap=%x, pxpatmap=%x, pxdstmap=%x, srcmap=%d, patmap=%d, dstmap=%d, " - "usesrcvramfr=%d, usevrambk=%d, frgdcol=%04x, bkgdcol=%04x, bgmix=%02x, fgmix=%02x.\n", + "usesrcvramfr=%d, usevrambk=%d, planemask=%04x, frgdcol=%04x, bkgdcol=%04x, bgmix=%02x, fgmix=%02x.\n", 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.pat_src & 0x03] & 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), - frgdcol, bkgdcol, xga->accel.bkgd_mix & 0x1f, xga->accel.frgd_mix & 0x1f); + xga->accel.plane_mask, frgdcol, bkgdcol, xga->accel.bkgd_mix & 0x1f, xga->accel.frgd_mix & 0x1f); if (xga->accel.pat_src == 8) { if (srcheight == 7) @@ -1559,43 +1703,43 @@ xga_bitblt(svga_t *svga) if ((xga->accel.dst_map == 1) && (xga->accel.src_map == 2)) { if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0a) && (xga->accel.px_map_format[xga->accel.src_map] >= 0x0a)) xga->accel.pattern = 1; + else if (!(xga->accel.px_map_format[xga->accel.dst_map] & 0x08) && !(xga->accel.px_map_format[xga->accel.src_map] & 0x08)) { + if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x02) && (xga->accel.px_map_format[xga->accel.src_map] >= 0x02)) + xga->accel.pattern = 1; + } } } } - 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]); - xga_log("PAT8: Pattern Enabled?=%d, xdir=%d, ydir=%d.\n", xga->accel.pattern, xdir, ydir); + xga_log("CMD=%08x, EnablePat=%d, SRC%d, DST%d: SrcFormat=%x, DstFormat=%x, SrcWidth=%d, SrcHeight=%d, DstWidth=%d, DstHeight=%d, sx=%d, sy=%d.\n", xga->accel.command, + xga->accel.pattern, xga->accel.src_map, xga->accel.dst_map, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), + srcwidth, srcheight, dstwidth, dstheight, xga->accel.sx, xga->accel.sy); while (xga->accel.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.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? + xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map) : + frgdcol; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map); 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); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } } } else { if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? + xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map) : + frgdcol; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map); 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); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } } } @@ -1606,6 +1750,7 @@ xga_bitblt(svga_t *svga) xga->accel.sx += xdir; dx += xdir; + xga->accel.x--; if (xga->accel.x < 0) { xga->accel.x = xga->accel.blt_width & 0xfff; @@ -1616,6 +1761,7 @@ xga_bitblt(svga_t *svga) xga->accel.sx = xga->accel.src_map_x & 0xfff; dy += ydir; + xga->accel.y_len++; if (xga->accel.pattern) xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight); @@ -1632,7 +1778,8 @@ xga_bitblt(svga_t *svga) } } } else if (xga->accel.pat_src >= 1) { - patbase = xga->accel.px_map_base[xga->accel.pat_src]; + patwidth = xga->accel.px_map_width[xga->accel.pat_src]; + patheight = xga->accel.px_map_height[xga->accel.pat_src]; if (patheight == 7) { if (xga->accel.src_map != 1) @@ -1649,38 +1796,31 @@ xga_bitblt(svga_t *svga) } else { 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] >= 0x0a) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) { - if ((patwidth >= 7) && ((xga->accel.command & 0xc0) == 0x40)) + if (patheight > 1) xga->accel.pattern = 0; else xga->accel.pattern = 1; + } else if (!(xga->accel.px_map_format[xga->accel.dst_map] & 0x08)) { + if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x02) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) { + if (patheight > 1) + xga->accel.pattern = 0; + else + xga->accel.pattern = 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); - xga_log("Pattern Enabled?=%d, patwidth=%d, patheight=%d, P(%d,%d).\n", xga->accel.pattern, patwidth, patheight, xga->accel.px, xga->accel.py); + xga_log("CMD=%08x, EnablePat=%d, PAT%d, SRC%d, DST%d: PatFormat=%x, SrcFormat=%x, DstFormat=%x, PatWidth=%d, PatHeight=%d, SrcWidth=%d, SrcHeight=%d, DstWidth=%d, DstHeight=%d, px=%d, py=%d.\n", xga->accel.command, + xga->accel.pattern, xga->accel.pat_src, xga->accel.src_map, xga->accel.dst_map, xga->accel.px_map_format[xga->accel.pat_src], (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), + patwidth, patheight, srcwidth, srcheight, dstwidth, dstheight, xga->accel.px, xga->accel.py); if (((xga->accel.command >> 24) & 0x0f) == 0x0a) { if ((xga->accel.bkgd_mix & 0x1f) == 0x05) { while (xga->accel.y >= 0) { - mix = xga_accel_read_area_map_pixel(svga, xga->accel.px, xga->accel.py, patbase, patwidth + 1); + mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py); if (mix) xga->accel.filling ^= 1; @@ -1688,26 +1828,30 @@ xga_bitblt(svga_t *svga) 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)) && xga->accel.filling) { - 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) : frgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? + xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map) : + frgdcol; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_log("1SRCDat=%02x, DSTDat=%02x, Old=%02x, MIX=%d.\n", src_dat, dest_dat, old_dest_dat, area_state); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + xga_log("XGA Area Fill1: Dest=%02x, Src=%02x, OldD=%02x.\n", dest_dat, src_dat, old_dest_dat); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } } } else { if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight) && xga->accel.filling) { - 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) : frgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? + xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map) : + frgdcol; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_log("2Fill: NumXY(%d,%d): DXY(%d,%d): SRCDat=%02x, DSTDat=%02x, Old=%02x, frgdcol=%02x, bkgdcol=%02x, MIX=%d, frgdmix=%02x, bkgdmix=%02x, dstmapfmt=%02x, srcmapfmt=%02x, srcmapnum=%d.\n", x, y, dx, dy, src_dat, dest_dat, old_dest_dat, frgdcol, bkgdcol, area_state, xga->accel.frgd_mix & 0x1f, xga->accel.bkgd_mix & 0x1f, xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.src_map); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); + xga_log("XGA Area Fill2: Dest=%02x, Src=%02x, OldD=%02x.\n", dest_dat, src_dat, old_dest_dat); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } } } @@ -1743,50 +1887,60 @@ xga_bitblt(svga_t *svga) } } } else { - patbase = xga->accel.px_map_base[xga->accel.pat_src]; - while (xga->accel.y >= 0) { - mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, patbase, patwidth + 1); + mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py); 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) : frgdcol; + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? + xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map) : + 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) : bkgdcol; + src_dat = (((xga->accel.command >> 30) & 3) == 2) ? + xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map) : + bkgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map); 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_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } } } 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) : frgdcol; + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? + xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map) : + 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) : bkgdcol; + src_dat = (((xga->accel.command >> 30) & 3) == 2) ? + xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map) : + bkgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map); 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_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dest_dat); } } } 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_log("MIX=%d, DX=%d, DY=%d, LX=%d, LY=%d, PX=%d, PY=%d, SX=%d, SY=%d.\n", mix, dx, dy, xga->accel.x, xga->accel.y, xga->accel.px, xga->accel.py, xga->accel.sx, xga->accel.sy); + dx += xdir; + xga->accel.x--; if (xga->accel.x < 0) { xga->accel.y--; @@ -1800,6 +1954,7 @@ xga_bitblt(svga_t *svga) 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 @@ -1850,6 +2005,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) break; case 0x14: + xga_log("MMIO14, len=%d, val=%08x, pxmapidx=%d.\n", len, val, xga->accel.px_map_idx); if (len == 4) xga->accel.px_map_base[xga->accel.px_map_idx] = val; else if (len == 2) @@ -1862,6 +2018,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) xga->accel.px_map_base[xga->accel.px_map_idx] = (xga->accel.px_map_base[xga->accel.px_map_idx] & 0xffff00ff) | (val << 8); break; case 0x16: + xga_log("MMIO16, len=%d, val=%08x, pxmapidx=%d.\n", len, val, xga->accel.px_map_idx); if (len == 2) xga->accel.px_map_base[xga->accel.px_map_idx] = (xga->accel.px_map_base[xga->accel.px_map_idx] & 0x0000ffff) | (val << 16); else @@ -1878,10 +2035,12 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) xga->accel.px_map_height[xga->accel.px_map_idx] = (val >> 16) & 0xffff; } else if (len == 2) { xga->accel.px_map_width[xga->accel.px_map_idx] = val & 0xffff; + xga_log("MMIO18, len=2, val=%04x, pxmapidx=%d.\n", val & 0xffff, xga->accel.px_map_idx); } else xga->accel.px_map_width[xga->accel.px_map_idx] = (xga->accel.px_map_width[xga->accel.px_map_idx] & 0xff00) | val; break; case 0x19: + xga_log("MMIO19, len=%d, val=%08x.\n", len, val); if (len == 1) xga->accel.px_map_width[xga->accel.px_map_idx] = (xga->accel.px_map_width[xga->accel.px_map_idx] & 0xff) | (val << 8); break; @@ -2055,6 +2214,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) break; case 0x54: + xga_log("MMIO54, len=%d, val=%08x.\n", len, val); if (len == 4) xga->accel.carry_chain = val; else if (len == 2) @@ -2067,6 +2227,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) xga->accel.carry_chain = (xga->accel.carry_chain & 0xffff00ff) | (val << 8); break; case 0x56: + xga_log("MMIO56, len=%d, val=%04x.\n", len, val); if (len == 2) xga->accel.carry_chain = (xga->accel.carry_chain & 0x0000ffff) | (val << 16); else @@ -2260,13 +2421,12 @@ exec_command: xga->accel.src_map = ((xga->accel.command >> 20) & 0x0f); xga_log("PATMAP=%x, DSTMAP=%x, SRCMAP=%x.\n", xga->accel.px_map_format[xga->accel.pat_src], xga->accel.px_map_format[xga->accel.dst_map], xga->accel.px_map_format[xga->accel.src_map]); - if (xga->accel.pat_src) - xga_log("[%04X:%08X]: Accel Command = %02x, full = %08x, patwidth = %d, " + 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", + "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], @@ -2300,14 +2460,14 @@ exec_command: xga_line_draw_write(svga); break; case 8: /*BitBLT*/ - xga_log("BitBLT.\n"); + xga_log("Normal BitBLT.\n"); xga_bitblt(svga); break; case 9: /*Inverting BitBLT*/ xga_log("Inverting BitBLT\n"); break; case 0x0a: /*Area Fill*/ - xga_log("Area Fill BitBLT.\n"); + xga_log("Area Fill.\n"); xga_bitblt(svga); break; @@ -2626,31 +2786,38 @@ xga_render_4bpp(svga_t *svga) if ((xga->displine + svga->y_add) < 0) return; - if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { + if (xga->changedvram[xga->memaddr >> 12] || xga->changedvram[(xga->memaddr >> 12) + 1] || svga->fullchange) { p = &buffer32->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 += 8) { - dat = *(uint32_t *) (&xga->vram[xga->ma & xga->vram_mask]); - p[0] = xga->pallook[dat & 0x0f]; - p[1] = xga->pallook[(dat >> 8) & 0x0f]; - p[2] = xga->pallook[(dat >> 16) & 0x0f]; - p[3] = xga->pallook[(dat >> 24) & 0x0f]; - - dat = *(uint32_t *) (&xga->vram[(xga->ma + 2) & xga->vram_mask]); - p[4] = xga->pallook[dat & 0x0f]; - p[5] = xga->pallook[(dat >> 8) & 0x0f]; - p[6] = xga->pallook[(dat >> 16) & 0x0f]; + for (int x = 0; x <= xga->h_disp; x += 16) { + dat = *(uint32_t *) (&xga->vram[xga->memaddr & xga->vram_mask]); + p[1] = xga->pallook[dat & 0x0f]; + p[0] = xga->pallook[(dat >> 4) & 0x0f]; + p[3] = xga->pallook[(dat >> 8) & 0x0f]; + p[2] = xga->pallook[(dat >> 12) & 0x0f]; + p[5] = xga->pallook[(dat >> 16) & 0x0f]; + p[4] = xga->pallook[(dat >> 20) & 0x0f]; p[7] = xga->pallook[(dat >> 24) & 0x0f]; + p[6] = xga->pallook[(dat >> 28) & 0x0f]; - xga->ma += 8; - p += 8; + dat = *(uint32_t *) (&xga->vram[(xga->memaddr + 4) & xga->vram_mask]); + p[9] = xga->pallook[dat & 0x0f]; + p[8] = xga->pallook[(dat >> 4) & 0x0f]; + p[11] = xga->pallook[(dat >> 8) & 0x0f]; + p[10] = xga->pallook[(dat >> 12) & 0x0f]; + p[13] = xga->pallook[(dat >> 16) & 0x0f]; + p[12] = xga->pallook[(dat >> 20) & 0x0f]; + p[15] = xga->pallook[(dat >> 24) & 0x0f]; + p[14] = xga->pallook[(dat >> 28) & 0x0f]; + + xga->memaddr += 8; + p += 16; } - xga->ma &= xga->vram_mask; + xga->memaddr &= xga->vram_mask; } } @@ -2664,7 +2831,7 @@ xga_render_8bpp(svga_t *svga) if ((xga->displine + svga->y_add) < 0) return; - if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { + if (xga->changedvram[xga->memaddr >> 12] || xga->changedvram[(xga->memaddr >> 12) + 1] || svga->fullchange) { p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; if (xga->firstline_draw == 2000) @@ -2672,22 +2839,22 @@ xga_render_8bpp(svga_t *svga) xga->lastline_draw = xga->displine; for (int x = 0; x <= xga->h_disp; x += 8) { - dat = *(uint32_t *) (&xga->vram[xga->ma & xga->vram_mask]); + dat = *(uint32_t *) (&xga->vram[xga->memaddr & xga->vram_mask]); 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]); + dat = *(uint32_t *) (&xga->vram[(xga->memaddr + 4) & xga->vram_mask]); 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; + xga->memaddr += 8; p += 8; } - xga->ma &= xga->vram_mask; + xga->memaddr &= xga->vram_mask; } } @@ -2702,7 +2869,7 @@ xga_render_16bpp(svga_t *svga) if ((xga->displine + svga->y_add) < 0) return; - if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { + if (xga->changedvram[xga->memaddr >> 12] || xga->changedvram[(xga->memaddr >> 12) + 1] || svga->fullchange) { p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; if (xga->firstline_draw == 2000) @@ -2710,55 +2877,63 @@ xga_render_16bpp(svga_t *svga) xga->lastline_draw = xga->displine; for (x = 0; x <= xga->h_disp; x += 8) { - dat = *(uint32_t *) (&xga->vram[(xga->ma + (x << 1)) & xga->vram_mask]); + dat = *(uint32_t *) (&xga->vram[(xga->memaddr + (x << 1)) & xga->vram_mask]); p[x] = video_16to32[dat & 0xffff]; p[x + 1] = video_16to32[dat >> 16]; - dat = *(uint32_t *) (&xga->vram[(xga->ma + (x << 1) + 4) & xga->vram_mask]); + dat = *(uint32_t *) (&xga->vram[(xga->memaddr + (x << 1) + 4) & xga->vram_mask]); p[x + 2] = video_16to32[dat & 0xffff]; p[x + 3] = video_16to32[dat >> 16]; - dat = *(uint32_t *) (&xga->vram[(xga->ma + (x << 1) + 8) & xga->vram_mask]); + dat = *(uint32_t *) (&xga->vram[(xga->memaddr + (x << 1) + 8) & xga->vram_mask]); p[x + 4] = video_16to32[dat & 0xffff]; p[x + 5] = video_16to32[dat >> 16]; - dat = *(uint32_t *) (&xga->vram[(xga->ma + (x << 1) + 12) & xga->vram_mask]); + dat = *(uint32_t *) (&xga->vram[(xga->memaddr + (x << 1) + 12) & xga->vram_mask]); p[x + 6] = video_16to32[dat & 0xffff]; p[x + 7] = video_16to32[dat >> 16]; } - xga->ma += x << 1; - xga->ma &= xga->vram_mask; + xga->memaddr += x << 1; + xga->memaddr &= xga->vram_mask; } } void xga_write_test(uint32_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) priv; - xga_t *xga = (xga_t *) svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; if (xga_active && xga) { - if (((xga->op_mode & 7) >= 1) && xga->aperture_cntl && (svga->mapping.base == 0xb8000)) { - xga_log("WriteAddr=%05x.\n", addr); - if (val == 0xa5) { /*Memory size test of XGA*/ - xga->test = val; - if (addr == 0xa0001) - xga->a5_test = 1; - else if (addr == 0xafffe) - xga->a5_test = 2; + if ((xga->op_mode & 7) == 4) { + if (xga->aperture_cntl && !xga->test_stage) { + if (val == 0xa5) { /*Memory size test of XGA*/ + xga->test = val; + if (addr == (xga->mapping_base + 0x0001)) + xga->a5_test = 1; + else if (addr == (xga->mapping_base + xga->banked_mask - 0x0001)) + xga->a5_test = 2; + xga->test_stage = 1; + xga->on = 0; + xga_log("XGA test1 addr=%05x, test=%02x.\n", addr, xga->a5_test); + } else if (val == 0x5a) { + xga->test = val; + xga->test_stage = 1; + xga->on = 0; + xga_log("XGA test2 addr = %05x.\n", addr); + } else if ((addr == xga->mapping_base) || (addr == (xga->mapping_base + 0x0010))) { + addr += xga->write_bank; + xga->vram[addr & xga->vram_mask] = val; + xga_log("XGA Linear endian reverse write, val = %02x, addr = %05x, banked mask = %04x, a5test=%d.\n", val, addr, svga->banked_mask, xga->a5_test); + } + } else { + xga->test_stage = 0; xga->on = 0; - xga_log("XGA test1 addr=%05x, test=%02x.\n", addr, xga->a5_test); - } else if (val == 0x5a) { - xga->test = val; - xga->on = 0; - xga_log("XGA test2 addr = %05x.\n", addr); - } else if ((addr == 0xa0000) || (addr == 0xa0010)) { - addr += xga->write_bank; - xga->vram[addr & xga->vram_mask] = val; - xga_log("XGA Linear endian reverse write, val = %02x, addr = %05x, banked mask = %04x, a5test=%d.\n", val, addr, svga->banked_mask, xga->a5_test); + xga_log("Write: AP=%x, teststage=%x, on=%d.\n", xga->aperture_cntl, xga->test_stage, xga->on); } - } else if (xga->aperture_cntl || (!xga->aperture_cntl && (svga->mapping.base == 0xa0000))) { + } else { + xga->test_stage = 0; xga->on = 0; xga_log("OFF XGA write.\n"); } @@ -2771,13 +2946,20 @@ xga_write_banked(uint32_t addr, uint8_t val, void *priv) svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; - if (xga->access_mode & 0x08) { - if ((xga->access_mode & 0x07) == 0x04) - addr ^= 1; - } + xga->changedvram[(xga_transform_addr(addr, xga->access_mode) & xga->vram_mask) >> 12] = + svga->monitor->mon_changeframecount; + xga->vram[xga_transform_addr(addr, xga->access_mode) & xga->vram_mask] = + xga_transform_val(val, xga->access_mode, 8); +} - xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; - xga->vram[addr & xga->vram_mask] = val; +static void +xga_writew_banked(uint32_t addr, uint16_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + + xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; + *(uint16_t *) &(xga->vram[addr & xga->vram_mask]) = xga_transform_val(val, xga->access_mode, 16); } static void @@ -2789,6 +2971,7 @@ xga_write(uint32_t addr, uint8_t val, void *priv) addr &= xga->banked_mask; addr += xga->write_bank; + xga_log("WriteBankedB addr=%08x, val=%02x, ison=%d, mapbits=%x.\n", addr, val, xga->on, svga->gdcreg[6] & 0x0c); if (addr >= xga->vram_size) return; @@ -2806,13 +2989,13 @@ xga_writew(uint32_t addr, uint16_t val, void *priv) addr &= xga->banked_mask; addr += xga->write_bank; + xga_log("WriteBankedW addr=%08x, val=%04x, ison=%d.\n", addr, val, xga->on); if (addr >= xga->vram_size) return; cycles -= svga->monitor->mon_video_timing_write_w; - xga_write_banked(addr, val & 0xff, svga); - xga_write_banked(addr + 1, val >> 8, svga); + xga_writew_banked(addr, val, svga); } static void @@ -2824,15 +3007,14 @@ xga_writel(uint32_t addr, uint32_t val, void *priv) addr &= xga->banked_mask; addr += xga->write_bank; + xga_log("WriteBankedL addr=%08x, val=%08x.\n", addr, val); if (addr >= xga->vram_size) return; cycles -= svga->monitor->mon_video_timing_write_l; - xga_write_banked(addr, val & 0xff, svga); - xga_write_banked(addr + 1, val >> 8, svga); - xga_write_banked(addr + 2, val >> 16, svga); - xga_write_banked(addr + 3, val >> 24, svga); + xga_writew_banked(addr, val & 0xffff, svga); + xga_writew_banked(addr + 2, val >> 16, svga); } uint8_t @@ -2843,31 +3025,41 @@ xga_read_test(uint32_t addr, void *priv) uint8_t ret = 0x00; if (xga_active && xga) { - if (((xga->op_mode & 7) >= 1) && xga->aperture_cntl && (svga->mapping.base == 0xb8000)) { - if (xga->test == 0xa5) { /*Memory size test of XGA*/ - if (addr == 0xa0001) { + xga_log("Read: OPMODE=%x, APCNTL=%x, base=%05x, test=%x.\n", xga->op_mode & 7, xga->aperture_cntl, svga->mapping.base, xga->test); + if ((xga->op_mode & 7) == 4) { + if (xga->aperture_cntl && (xga->test_stage == 1)) { + if (xga->test == 0xa5) { /*Memory size test of XGA*/ + if (addr == (xga->mapping_base + 0x0001)) { + xga_log("A5 test bank = %x, svgabase=%05x.\n", addr, svga->mapping.base); + ret = xga->test; + } else if ((addr == xga->mapping_base) && (xga->a5_test == 1)) { /*This is required by XGAKIT to pass the memory test*/ + xga_log("A5 test bank = %x.\n", addr); + addr += xga->read_bank; + ret = xga->vram[addr & xga->vram_mask]; + } else + ret = xga->test; + + xga->test_stage = 0; + xga->on = 1; + xga_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) { + xga->test_stage = 0; ret = xga->test; xga->on = 1; - } else if ((addr == 0xa0000) && (xga->a5_test == 1)) { /*This is required by XGAKIT to pass the memory test*/ - xga_log("A5 test bank = %x.\n", addr); + xga_log("5A read: XGA ON = %d.\n", xga->on); + return ret; + } else if ((addr == xga->mapping_base) || (addr == (xga->mapping_base + 0x0010))) { addr += xga->read_bank; - ret = xga->vram[addr & xga->vram_mask]; - } else { - ret = xga->test; - xga->on = 1; + return xga->vram[addr & xga->vram_mask]; } - xga_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; - xga_log("5A read: XGA ON = %d.\n", xga->on); - return ret; - } else if ((addr == 0xa0000) || (addr == 0xa0010)) { - addr += xga->read_bank; - return xga->vram[addr & xga->vram_mask]; + } else { + xga->test_stage = 0; + xga->on = 0; + xga_log("Read: AP=%x, teststage=%x, on=%d.\n", xga->aperture_cntl, xga->test_stage, xga->on); } - } else if (xga->aperture_cntl || (!xga->aperture_cntl && (svga->mapping.base == 0xa0000))) { + } else { + xga->test_stage = 0; xga->on = 0; xga_log("OFF XGA read.\n"); } @@ -2882,12 +3074,21 @@ xga_read_banked(uint32_t addr, void *priv) xga_t *xga = (xga_t *) svga->xga; uint8_t ret = 0xff; - if (xga->access_mode & 0x08) { - if ((xga->access_mode & 0x07) == 0x04) - addr ^= 1; - } + ret = xga_transform_val(xga->vram[xga_transform_addr(addr, xga->access_mode) & xga->vram_mask], + xga->access_mode, 8); - ret = xga->vram[addr & xga->vram_mask]; + return ret; +} + +static uint16_t +xga_readw_banked(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + uint16_t ret = 0xffff; + + ret = xga_transform_val(*(uint16_t *) &(xga->vram[addr & xga->vram_mask]), + xga->access_mode, 16); return ret; } @@ -2910,6 +3111,7 @@ xga_read(uint32_t addr, void *priv) cycles -= svga->monitor->mon_video_timing_read_b; ret = xga_read_banked(addr, svga); + xga_log("ReadBankedB addr=%08x, ret=%02x, ison=%d.\n", addr, ret, xga->on); return ret; } @@ -2930,8 +3132,8 @@ xga_readw(uint32_t addr, void *priv) cycles -= svga->monitor->mon_video_timing_read_w; - ret = xga_read_banked(addr, svga); - ret |= (xga_read_banked(addr + 1, svga) << 8); + ret = xga_readw_banked(addr, svga); + xga_log("ReadBankedW addr=%08x, ret=%04x, ison=%d.\n", addr, ret, xga->on); return ret; } @@ -2952,10 +3154,8 @@ xga_readl(uint32_t addr, void *priv) cycles -= svga->monitor->mon_video_timing_read_l; - ret = xga_read_banked(addr, svga); - ret |= (xga_read_banked(addr + 1, svga) << 8); - ret |= (xga_read_banked(addr + 2, svga) << 16); - ret |= (xga_read_banked(addr + 3, svga) << 24); + ret = xga_readw_banked(addr, svga); + ret |= (xga_readw_banked(addr + 2, svga) << 16); return ret; } @@ -2965,13 +3165,13 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv) svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; - xga_log("WriteLL XGA=%d.\n", xga->on); + xga_log("WriteLL XGA=%d, addr=%08x, val=%02x.\n", xga->on, addr, val); if (!xga->on) { svga_write_linear(addr, val, svga); return; } - addr &= (xga->vram_size - 1); + addr &= xga->vram_mask; if (addr >= xga->vram_size) { xga_log("Write Linear Over!.\n"); @@ -2980,23 +3180,35 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv) cycles -= svga->monitor->mon_video_timing_write_b; - xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; - xga->vram[addr & xga->vram_mask] = val; + xga->changedvram[(xga_transform_addr(addr, xga->access_mode) & xga->vram_mask) >> 12] = + svga->monitor->mon_changeframecount; + xga->vram[xga_transform_addr(addr, xga->access_mode) & xga->vram_mask] = + xga_transform_val(val, xga->access_mode, 8); } static void xga_writew_linear(uint32_t addr, uint16_t val, void *priv) { - svga_t *svga = (svga_t *) priv; - const xga_t *xga = (xga_t *) svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + xga_log("WriteLL XGA=%d, addr=%08x, val=%02x.\n", xga->on, addr, val); if (!xga->on) { svga_writew_linear(addr, val, svga); return; } - xga_write_linear(addr, val, priv); - xga_write_linear(addr + 1, val >> 8, priv); + addr &= xga->vram_mask; + + if (addr >= xga->vram_size) { + xga_log("Write Linear Over!.\n"); + return; + } + + cycles -= svga->monitor->mon_video_timing_write_b; + + xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; + *(uint16_t *) &(xga->vram[addr & xga->vram_mask]) = xga_transform_val(val, xga->access_mode, 16); } static void @@ -3010,10 +3222,8 @@ xga_writel_linear(uint32_t addr, uint32_t val, void *priv) return; } - xga_write_linear(addr, val, priv); - xga_write_linear(addr + 1, val >> 8, priv); - xga_write_linear(addr + 2, val >> 16, priv); - xga_write_linear(addr + 3, val >> 24, priv); + xga_writew_linear(addr, val, priv); + xga_writew_linear(addr + 2, val >> 16, priv); } static uint8_t @@ -3023,19 +3233,17 @@ xga_read_linear(uint32_t addr, void *priv) const xga_t *xga = (xga_t *) svga->xga; uint8_t ret = 0xff; - if (!xga->on) - return svga_read_linear(addr, svga); + if (xga->on) { + addr &= xga->vram_mask; - addr &= (xga->vram_size - 1); + if (addr < xga->vram_size) { + cycles -= svga->monitor->mon_video_timing_read_b; - if (addr >= xga->vram_size) { - xga_log("Read Linear Over ADDR=%x!.\n", addr); - return ret; - } - - cycles -= svga->monitor->mon_video_timing_read_b; - - ret = xga->vram[addr & xga->vram_mask]; + ret = xga_transform_val(xga->vram[xga_transform_addr(addr, xga->access_mode) & xga->vram_mask], + xga->access_mode, 8); + } + } else + ret = svga_read_linear(addr, svga); return ret; } @@ -3045,13 +3253,19 @@ xga_readw_linear(uint32_t addr, void *priv) { svga_t *svga = (svga_t *) priv; const xga_t *xga = (xga_t *) svga->xga; - uint16_t ret; + uint16_t ret = 0xffff; - if (!xga->on) - return svga_readw_linear(addr, svga); + if (xga->on) { + addr &= xga->vram_mask; - ret = xga_read_linear(addr, svga); - ret |= (xga_read_linear(addr + 1, svga) << 8); + if (addr < xga->vram_size) { + cycles -= svga->monitor->mon_video_timing_read_b; + + ret = xga_transform_val(*(uint16_t *) &(xga->vram[addr & xga->vram_mask]), + xga->access_mode, 16); + } + } else + ret = svga_readw_linear(addr, svga); return ret; } @@ -3066,10 +3280,8 @@ xga_readl_linear(uint32_t addr, void *priv) if (!xga->on) return svga_readl_linear(addr, svga); - 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); + ret = xga_readw_linear(addr, svga); + ret |= (xga_readw_linear(addr + 2, svga) << 16); return ret; } @@ -3109,7 +3321,7 @@ xga_poll(void *priv) if (xga->dispon) { xga->h_disp_on = 1; - xga->ma &= xga->vram_mask; + xga->memaddr &= xga->vram_mask; if (xga->firstline == 2000) { xga->firstline = xga->displine; @@ -3117,14 +3329,14 @@ xga_poll(void *priv) } if (xga->hwcursor_on) - xga->changedvram[xga->ma >> 12] = xga->changedvram[(xga->ma >> 12) + 1] = xga->interlace ? 3 : 2; + xga->changedvram[xga->memaddr >> 12] = xga->changedvram[(xga->memaddr >> 12) + 1] = xga->interlace ? 3 : 2; svga->render_xga(svga); - svga->x_add = (overscan_x >> 1); + svga->x_add = svga->left_overscan; xga_render_overscan_left(xga, svga); xga_render_overscan_right(xga, svga); - svga->x_add = (overscan_x >> 1); + svga->x_add = svga->left_overscan; if (xga->hwcursor_on) { xga_hwcursor_draw(svga, xga->displine + svga->y_add); @@ -3153,20 +3365,20 @@ xga_poll(void *priv) xga->linepos = 0; if (xga->dispon) { - if (xga->sc == xga->rowcount) { - xga->sc = 0; + if (xga->scanline == xga->rowcount) { + xga->scanline = 0; - xga_log("MA=%08x, MALATCH=%x.\n", xga->ma, xga->ma_latch); - xga->maback += (xga->rowoffset << 3); + xga_log("MA=%08x, MALATCH=%x.\n", xga->memaddr, xga->memaddr_latch); + xga->memaddr_backup += (xga->rowoffset << 3); if (xga->interlace) - xga->maback += (xga->rowoffset << 3); + xga->memaddr_backup += (xga->rowoffset << 3); - xga->maback &= xga->vram_mask; - xga->ma = xga->maback; + xga->memaddr_backup &= xga->vram_mask; + xga->memaddr = xga->memaddr_backup; } else { - xga->sc++; - xga->sc &= 0x1f; - xga->ma = xga->maback; + xga->scanline++; + xga->scanline &= 0x1f; + xga->memaddr = xga->memaddr_backup; } } @@ -3175,14 +3387,14 @@ xga_poll(void *priv) if (xga->vc == xga->split) { if (xga->interlace && xga->oddeven) - xga->ma = xga->maback = (xga->rowoffset << 1); + xga->memaddr = xga->memaddr_backup = (xga->rowoffset << 1); else - xga->ma = xga->maback = 0; + xga->memaddr = xga->memaddr_backup = 0; - xga->ma = (xga->ma << 2); - xga->maback = (xga->maback << 2); + xga->memaddr = (xga->memaddr << 2); + xga->memaddr_backup = (xga->memaddr_backup << 2); - xga->sc = 0; + xga->scanline = 0; } if (xga->vc == xga->dispend) { xga->dispon = 0; @@ -3220,20 +3432,20 @@ xga_poll(void *priv) svga->monitor->mon_changeframecount = xga->interlace ? 3 : 2; if (xga->interlace && xga->oddeven) - xga->ma = xga->maback = xga->ma_latch + (xga->rowoffset << 1); + xga->memaddr = xga->memaddr_backup = xga->memaddr_latch + (xga->rowoffset << 1); else - xga->ma = xga->maback = xga->ma_latch; + xga->memaddr = xga->memaddr_backup = xga->memaddr_latch; - xga->ma = (xga->ma << 2); - xga->maback = (xga->maback << 2); + xga->memaddr = (xga->memaddr << 2); + xga->memaddr_backup = (xga->memaddr_backup << 2); } if (xga->vc == xga->v_total) { xga->vc = 0; - xga->sc = 0; + xga->scanline = 0; xga->dispon = 1; xga->displine = (xga->interlace && xga->oddeven) ? 1 : 0; - svga->x_add = (overscan_x >> 1); + svga->x_add = svga->left_overscan; xga->hwcursor_on = 0; xga->hwcursor_latch = xga->hwcursor; @@ -3270,17 +3482,18 @@ xga_mca_write(int port, uint8_t val, void *priv) mem_mapping_disable(&xga->memio_mapping); xga->on = 0; xga->a5_test = 0; + xga->test_stage = 0; /* Save the MCA register value. */ xga->pos_regs[port & 7] = val; - if (!(xga->pos_regs[4] & 1)) /*MCA 4MB addressing on systems with more than 16MB of memory*/ - xga->pos_regs[4] |= 1; if (xga->pos_regs[2] & 1) { xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; xga->base_addr_1mb = (xga->pos_regs[5] & 0x0f) << 20; xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); + if (!xga->base_addr_1mb) + xga->pos_regs[4] |= 1; /*If 1MB VRAM aperture is disabled on MCA, enable the 4MB VRAM aperture instead.*/ io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); @@ -3322,11 +3535,11 @@ xga_reset(void *priv) xga_t *xga = (xga_t *) svga->xga; xga_log("Normal Reset.\n"); - if (xga_standalone_enabled) - mem_mapping_disable(&xga->memio_mapping); + mem_mapping_disable(&xga->memio_mapping); xga->on = 0; xga->a5_test = 0; + xga->test_stage = 0; mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); svga_set_poll(svga); } @@ -3361,7 +3574,6 @@ xga_pos_in(uint16_t addr, void *priv) ret = xga->pos_regs[3]; ret |= (xga->dma_channel << 3); } - xga_log("POS IDX for 0103 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); break; case 0x0104: @@ -3465,11 +3677,8 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv) break; case 0x0104: xga_log("104Write=%02x.\n", val); - if ((xga->pos_idx & 3) == 0) { + if ((xga->pos_idx & 3) == 0) xga->pos_regs[4] = val; - if (!(xga->pos_regs[4] & 0x01)) /*4MB addressing on systems with more than 15MB of memory*/ - xga->pos_regs[4] |= 0x01; - } break; case 0x0105: xga_log("105Write=%02x.\n", val); @@ -3515,13 +3724,11 @@ xga_init(const device_t *info) svga->xga = xga; - xga->ext_mem_addr = device_get_config_hex16("ext_mem_addr"); - xga->instance_isa = device_get_config_int("instance"); xga->type = device_get_config_int("type"); xga->dma_channel = device_get_config_int("dma"); xga->bus = info->flags; - xga->vram_size = (1024 << 10); + xga->vram_size = 1024 << 10; xga->vram_mask = xga->vram_size - 1; xga->vram = calloc(xga->vram_size, 1); xga->changedvram = calloc((xga->vram_size >> 12) + 1, 1); @@ -3529,6 +3736,7 @@ xga_init(const device_t *info) xga->hwcursor.cur_xsize = 64; xga->hwcursor.cur_ysize = 64; xga->a5_test = 0; + xga->test_stage = 0; if (info->flags & DEVICE_MCA) { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_mca); @@ -3548,25 +3756,6 @@ xga_init(const device_t *info) mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, xga_memio_writeb, xga_memio_writew, xga_memio_writel, xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); - } else { - xga->pos_regs[2] = (xga->instance_isa << 1) | xga->ext_mem_addr; - xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); - xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; - xga->pos_regs[2] |= 0x01; - xga->pos_regs[4] |= 0x01; - if (mem_size >= 15360) - xga->pos_regs[5] = 0; - else { - xga->pos_regs[5] = ((mem_size * 64) >> 0x10) + 1; - if (xga->pos_regs[5] == 0x10) - xga->pos_regs[5] = 0x00; - } - xga->base_addr_1mb = (xga->pos_regs[5] & 0x0f) << 20; - xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); - rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, xga->rom_addr, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, - xga_memio_writeb, xga_memio_writew, xga_memio_writel, - xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); } } @@ -3585,10 +3774,6 @@ xga_init(const device_t *info) } else { io_sethandler(0x0096, 0x0001, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga); io_sethandler(0x0100, 0x0010, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga); - if (xga_standalone_enabled) { - io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); - mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr, 0x2000); - } } return svga; } @@ -3678,89 +3863,6 @@ static const device_config_t xga_mca_configuration[] = { // clang-format on }; -static const device_config_t xga_isa_configuration[] = { - // clang-format off - { - .name = "type", - .description = "XGA type", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "XGA-1", .value = 0 }, - { .description = "XGA-2", .value = 1 }, - { .description = "" } - }, - .bios = { { 0 } } - }, - { - .name = "instance", - .description = "Instance", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 6, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "0 (2100h-210Fh)", .value = 0 }, - { .description = "1 (2110h-211Fh)", .value = 1 }, - { .description = "2 (2120h-212Fh)", .value = 2 }, - { .description = "3 (2130h-213Fh)", .value = 3 }, - { .description = "4 (2140h-214Fh)", .value = 4 }, - { .description = "5 (2150h-215Fh)", .value = 5 }, - { .description = "6 (2160h-216Fh)", .value = 6 }, - { .description = "7 (2170h-217Fh)", .value = 7 }, - { .description = "" } - }, - .bios = { { 0 } } - }, - { - .name = "ext_mem_addr", - .description = "MMIO Address", - .type = CONFIG_HEX16, - .default_string = NULL, - .default_int = 0x00f0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "C800h", .value = 0x0040 }, - { .description = "CA00h", .value = 0x0050 }, - { .description = "CC00h", .value = 0x0060 }, - { .description = "CE00h", .value = 0x0070 }, - { .description = "D000h", .value = 0x0080 }, - { .description = "D200h", .value = 0x0090 }, - { .description = "D400h", .value = 0x00a0 }, - { .description = "D600h", .value = 0x00b0 }, - { .description = "D800h", .value = 0x00c0 }, - { .description = "DA00h", .value = 0x00d0 }, - { .description = "DC00h", .value = 0x00e0 }, - { .description = "DE00h", .value = 0x00f0 }, - { .description = "" } - }, - .bios = { { 0 } } - }, - { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 7, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "Disabled", .value = 0 }, - { .description = "DMA 6", .value = 6 }, - { .description = "DMA 7", .value = 7 }, - { .description = "" } - }, - .bios = { { 0 } } - }, - { .name = "", .description = "", .type = CONFIG_END } - // clang-format on -}; - static const device_config_t xga_inmos_isa_configuration[] = { // clang-format off { @@ -3812,20 +3914,6 @@ const device_t xga_device = { .config = xga_mca_configuration }; -const device_t xga_isa_device = { - .name = "XGA (ISA)", - .internal_name = "xga_isa", - .flags = DEVICE_ISA16, - .local = 0, - .init = xga_init, - .close = xga_close, - .reset = xga_reset, - .available = xga_available, - .speed_changed = xga_speed_changed, - .force_redraw = xga_force_redraw, - .config = xga_isa_configuration -}; - const device_t inmos_isa_device = { .name = "INMOS XGA (ISA)", .internal_name = "inmos_xga_isa", @@ -3848,6 +3936,4 @@ xga_device_add(void) if (machine_has_bus(machine, MACHINE_BUS_MCA)) device_add(&xga_device); - else - device_add(&xga_isa_device); } diff --git a/src/video/video.c b/src/video/video.c index 0773e61ce..c8dc137c5 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -1006,76 +1006,73 @@ video_force_resize_set_monitor(uint8_t res, int monitor_index) } void -loadfont_common(FILE *f, int format) +loadfont_common(FILE *fp, int format) { - int c; - int d; - switch (format) { case 0: /* MDA */ - for (c = 0; c < 256; c++) - for (d = 0; d < 8; d++) - fontdatm[c][d] = fgetc(f) & 0xff; - for (c = 0; c < 256; c++) - for (d = 0; d < 8; d++) - fontdatm[c][d + 8] = fgetc(f) & 0xff; - (void) fseek(f, 4096 + 2048, SEEK_SET); - for (c = 0; c < 256; c++) - for (d = 0; d < 8; d++) - fontdat[c][d] = fgetc(f) & 0xff; + for (uint16_t c = 0; c < 256; c++) /* 8x14 MDA in 8x8 cell (lines 0-7) */ + for (uint8_t d = 0; d < 8; d++) + fontdatm[c][d] = fgetc(fp) & 0xff; + for (uint16_t c = 0; c < 256; c++) /* 8x14 MDA in 8x8 cell (lines 8-13 + padding lines) */ + for (uint8_t d = 0; d < 8; d++) + fontdatm[c][d + 8] = fgetc(fp) & 0xff; + (void) fseek(fp, 4096 + 2048, SEEK_SET); + for (uint16_t c = 0; c < 256; c++) /* 8x8 CGA (thick, primary) */ + for (uint8_t d = 0; d < 8; d++) + fontdat[c][d] = fgetc(fp) & 0xff; break; case 1: /* PC200 */ - for (d = 0; d < 4; d++) { + for (uint8_t 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(&fontdatm[256 * d + c][0], 1, 16, f); - for (c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */ - (void) !fread(&fontdat[256 * d + c][0], 1, 8, f); - fseek(f, 8, SEEK_CUR); + for (uint16_t c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */ + (void) !fread(&fontdatm[256 * d + c][0], 1, 16, fp); + for (uint16_t c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */ + (void) !fread(&fontdat[256 * d + c][0], 1, 8, fp); + fseek(fp, 8, SEEK_CUR); } } break; default: case 2: /* CGA */ - for (c = 0; c < 256; c++) - for (d = 0; d < 8; d++) - fontdat[c][d] = fgetc(f) & 0xff; + for (uint16_t c = 0; c < 256; c++) + for (uint8_t d = 0; d < 8; d++) + fontdat[c][d] = fgetc(fp) & 0xff; break; case 3: /* Wyse 700 */ - for (c = 0; c < 512; c++) - for (d = 0; d < 32; d++) - fontdatw[c][d] = fgetc(f) & 0xff; + for (uint16_t c = 0; c < 512; c++) + for (uint8_t d = 0; d < 32; d++) + fontdatw[c][d] = fgetc(fp) & 0xff; break; case 4: /* MDSI Genius */ - for (c = 0; c < 256; c++) - for (d = 0; d < 16; d++) - fontdat8x12[c][d] = fgetc(f) & 0xff; + for (uint16_t c = 0; c < 256; c++) + for (uint8_t d = 0; d < 16; d++) + fontdat8x12[c][d] = fgetc(fp) & 0xff; break; - case 5: /* Toshiba 3100e */ - for (d = 0; d < 2048; d += 512) { /* Four languages... */ - for (c = d; c < d + 256; c++) { - (void) !fread(&fontdatm[c][8], 1, 8, f); + case 5: /* Toshiba 3100e */ + for (uint16_t d = 0; d < 2048; d += 512) { /* Four languages... */ + for (uint16_t c = d; c < d + 256; c++) { + (void) !fread(&fontdatm[c][8], 1, 8, fp); } - for (c = d + 256; c < d + 512; c++) { - (void) !fread(&fontdatm[c][8], 1, 8, f); + for (uint32_t c = d + 256; c < d + 512; c++) { + (void) !fread(&fontdatm[c][8], 1, 8, fp); } - for (c = d; c < d + 256; c++) { - (void) !fread(&fontdatm[c][0], 1, 8, f); + for (uint32_t c = d; c < d + 256; c++) { + (void) !fread(&fontdatm[c][0], 1, 8, fp); } - for (c = d + 256; c < d + 512; c++) { - (void) !fread(&fontdatm[c][0], 1, 8, f); + for (uint32_t c = d + 256; c < d + 512; c++) { + (void) !fread(&fontdatm[c][0], 1, 8, fp); } - fseek(f, 4096, SEEK_CUR); /* Skip blank section */ - for (c = d; c < d + 256; c++) { - (void) !fread(&fontdat[c][0], 1, 8, f); + fseek(fp, 4096, SEEK_CUR); /* Skip blank section */ + for (uint32_t c = d; c < d + 256; c++) { + (void) !fread(&fontdat[c][0], 1, 8, fp); } - for (c = d + 256; c < d + 512; c++) { - (void) !fread(&fontdat[c][0], 1, 8, f); + for (uint32_t c = d + 256; c < d + 512; c++) { + (void) !fread(&fontdat[c][0], 1, 8, fp); } } break; @@ -1087,65 +1084,64 @@ loadfont_common(FILE *f, int format) if (!fontdatksc5601_user) fontdatksc5601_user = malloc(192 * sizeof(dbcs_font_t)); - for (c = 0; c < 16384; c++) { - for (d = 0; d < 32; d++) - fontdatksc5601[c].chr[d] = fgetc(f) & 0xff; + for (uint32_t c = 0; c < 16384; c++) { + for (uint8_t d = 0; d < 32; d++) + fontdatksc5601[c].chr[d] = fgetc(fp) & 0xff; } break; case 7: /* Sigma Color 400 */ /* The first 4k of the character ROM holds an 8x8 font */ - for (c = 0; c < 256; c++) { - (void) !fread(&fontdat[c][0], 1, 8, f); - fseek(f, 8, SEEK_CUR); + for (uint16_t c = 0; c < 256; c++) { + (void) !fread(&fontdat[c][0], 1, 8, fp); + fseek(fp, 8, SEEK_CUR); } /* The second 4k holds an 8x16 font */ - for (c = 0; c < 256; c++) { - if (fread(&fontdatm[c][0], 1, 16, f) != 16) + for (uint16_t c = 0; c < 256; c++) { + if (fread(&fontdatm[c][0], 1, 16, fp) != 16) fatal("loadfont(): Error reading 8x16 font in Sigma Color 400 mode, c = %i\n", c); } break; - case 8: /* Amstrad PC1512, Toshiba T1000/T1200 */ - for (c = 0; c < 2048; c++) /* Allow up to 2048 chars */ - for (d = 0; d < 8; d++) - fontdat[c][d] = fgetc(f) & 0xff; + case 8: /* Amstrad PC1512, Toshiba T1000/T1200 */ + for (uint16_t c = 0; c < 2048; c++) /* Allow up to 2048 chars */ + for (uint8_t d = 0; d < 8; d++) + fontdat[c][d] = fgetc(fp) & 0xff; break; case 9: /* Image Manager 1024 native font */ - for (c = 0; c < 256; c++) - (void) !fread(&fontdat12x18[c][0], 1, 36, f); + for (uint16_t c = 0; c < 256; c++) + (void) !fread(&fontdat12x18[c][0], 1, 36, fp); break; - case 10: /* Pravetz */ - for (c = 0; c < 1024; c++) /* Allow up to 1024 chars */ - for (d = 0; d < 8; d++) - fontdat[c][d] = fgetc(f) & 0xff; + case 10: /* Pravetz */ + for (uint16_t c = 0; c < 1024; c++) /* Allow up to 1024 chars */ + for (uint8_t d = 0; d < 8; d++) + fontdat[c][d] = fgetc(fp) & 0xff; break; - case 11: /* PC200 */ - for (d = 0; d < 4; d++) { + for (uint8_t 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); + for (uint16_t c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */ + (void) !fread(&fontdatm2[256 * d + c][0], 1, 16, fp); + for (uint16_t c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */ + (void) !fread(&fontdat2[256 * d + c][0], 1, 8, fp); + fseek(fp, 8, SEEK_CUR); } } break; } - (void) fclose(f); + (void) fclose(fp); } void -loadfont_ex(char *s, int format, int offset) +loadfont_ex(char *fn, int format, int offset) { FILE *fp; - fp = rom_fopen(s, "rb"); + fp = rom_fopen(fn, "rb"); if (fp == NULL) return; @@ -1154,9 +1150,9 @@ loadfont_ex(char *s, int format, int offset) } void -loadfont(char *s, int format) +loadfont(char *fn, int format) { - loadfont_ex(s, format, 0); + loadfont_ex(fn, format, 0); } uint32_t diff --git a/wl_protocols/keyboard-shortcuts-inhibit-unstable-v1.xml b/wl_protocols/keyboard-shortcuts-inhibit-unstable-v1.xml new file mode 100644 index 000000000..27748764d --- /dev/null +++ b/wl_protocols/keyboard-shortcuts-inhibit-unstable-v1.xml @@ -0,0 +1,143 @@ + + + + + Copyright © 2017 Red Hat Inc. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol specifies a way for a client to request the compositor + to ignore its own keyboard shortcuts for a given seat, so that all + key events from that seat get forwarded to a surface. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible + changes may be added together with the corresponding interface + version bump. + Backward incompatible changes are done by bumping the version + number in the protocol and interface names and resetting the + interface version. Once the protocol is to be declared stable, + the 'z' prefix and the version number in the protocol and + interface names are removed and the interface version number is + reset. + + + + + A global interface used for inhibiting the compositor keyboard shortcuts. + + + + + Destroy the keyboard shortcuts inhibitor manager. + + + + + + Create a new keyboard shortcuts inhibitor object associated with + the given surface for the given seat. + + If shortcuts are already inhibited for the specified seat and surface, + a protocol error "already_inhibited" is raised by the compositor. + + + + + + + + + + + + + + A keyboard shortcuts inhibitor instructs the compositor to ignore + its own keyboard shortcuts when the associated surface has keyboard + focus. As a result, when the surface has keyboard focus on the given + seat, it will receive all key events originating from the specified + seat, even those which would normally be caught by the compositor for + its own shortcuts. + + The Wayland compositor is however under no obligation to disable + all of its shortcuts, and may keep some special key combo for its own + use, including but not limited to one allowing the user to forcibly + restore normal keyboard events routing in the case of an unwilling + client. The compositor may also use the same key combo to reactivate + an existing shortcut inhibitor that was previously deactivated on + user request. + + When the compositor restores its own keyboard shortcuts, an + "inactive" event is emitted to notify the client that the keyboard + shortcuts inhibitor is not effectively active for the surface and + seat any more, and the client should not expect to receive all + keyboard events. + + When the keyboard shortcuts inhibitor is inactive, the client has + no way to forcibly reactivate the keyboard shortcuts inhibitor. + + The user can chose to re-enable a previously deactivated keyboard + shortcuts inhibitor using any mechanism the compositor may offer, + in which case the compositor will send an "active" event to notify + the client. + + If the surface is destroyed, unmapped, or loses the seat's keyboard + focus, the keyboard shortcuts inhibitor becomes irrelevant and the + compositor will restore its own keyboard shortcuts but no "inactive" + event is emitted in this case. + + + + + Remove the keyboard shortcuts inhibitor from the associated wl_surface. + + + + + + This event indicates that the shortcut inhibitor is active. + + The compositor sends this event every time compositor shortcuts + are inhibited on behalf of the surface. When active, the client + may receive input events normally reserved by the compositor + (see zwp_keyboard_shortcuts_inhibitor_v1). + + This occurs typically when the initial request "inhibit_shortcuts" + first becomes active or when the user instructs the compositor to + re-enable and existing shortcuts inhibitor using any mechanism + offered by the compositor. + + + + + + This event indicates that the shortcuts inhibitor is inactive, + normal shortcuts processing is restored by the compositor. + + + +